skip to Main Content

I’m working on a Nuxt 3 application that uses AWS Amplify Hosting (Gen 2), and I want to send emails via AWS SES using a Lambda function. I have created the following Lambda function:

import type { Schema } from "../../data/resource";
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";

const sesClient = new SESClient({ region: "af-south-1" });

export const handler: Schema["sendEmail"]["functionHandler"] = async (event) => {
  const recipient = "[email protected]";
  const subject = "Subject";
  const body = "Body";

  const command = new SendEmailCommand({
    Source: "[email protected]",
    Destination: {
      ToAddresses: [recipient],
    },
    Message: {
      Body: {
        Text: { Data: body },
      },
      Subject: { Data: subject },
    },
  });

  try {
    const result = await sesClient.send(command);
    console.log(`Email sent to ${recipient}: ${result.MessageId}`);
  } catch (error) {
    console.error(`Error sending email to ${recipient}: ${error}`);
    throw new Error(`Failed to send email to ${recipient}`, { cause: error });
  }

  return `Hello, ${event.name}!`;
};

In my front end I am triggering the lamda as follow:

import { generateClient } from "aws-amplify/api";
import type { Schema } from "~/amplify/data/resource";

const client = generateClient<Schema>();
const response = await client.queries.sendEmail({
  name: "Amplify",
});

I do get error when I trigger this lamda "Not Authorized to access sendEmail on type Query"

this is my backend resource setup

import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
import { sendEmail } from '../functions/send-email/resource';

const schema = a.schema({

  sendEmail: a
    .query()
    .arguments({
      name: a.string(),
    })
    .returns(a.string())
    .authorization((allow) => [allow.guest() ,allow.authenticated()])
    .handler(a.handler.function(sendEmail)),

  Todo: a
    .model({
      content: a.string(),
    })
    .authorization((allow) => [allow.publicApiKey(), allow.guest() ,allow.authenticated()]),
});

export type Schema = ClientSchema<typeof schema>;

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: 'apiKey',
    apiKeyAuthorizationMode: { expiresInDays: 30 }
  }
});

Any guidance would be greatly appreciated! Specifically, I’d like to know:

  • Is this the best way to send emails via SES, or would creating a
    custom class provide a better solution?
  • How can I securely trigger
    the email from the frontend application?
  • What permissions are required to ensure the Lambda function can send emails successfully?

I’ve already verified my email address in the SES af-south-1 region.

Thanks in advance for your help!

2

Answers


  1. Chosen as BEST ANSWER

    Update

    I have added the following policies to my amplify/backend.ts

    const backend = defineBackend({
       auth,
       data,
       sendEmail
    });
    
       backend.sendEmail.resources.lambda.addToRolePolicy(
         new PolicyStatement({
         actions: ['ses:SendEmail', 'ses:SendRawEmail'],
         resources: ['*']
       })
    )
    

    This is working now.


  2. On Frontend, You will need to specify authMode.

    import { generateClient } from "aws-amplify/api";
    import type { Schema } from "~/amplify/data/resource";
    
    const client = generateClient<Schema>();
    const response = await client.queries.sendEmail({
      name: "Amplify",
    },{
        authMode: "userPool"
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search