/ 4 min read
Send emails with AWS Lambda Function URL and AWS Simple Email Service from a static website
The problem
I have a very simple static website, and wanted to integrate a cheap email solution. After some considerations AWS Simple Email Service was the best option for me.
Let’s see what steps I followed to have a static site that sends emails using AWS Lambda and AWS SEM.
Creating an IAM Role
We need a Lambda that sends emails of course, but… first, in order to be able to let that function to do the job, we need to create a Role and give it the necessary permissions to operate with the Amazon SES.
- Create a new role for AWS service
- Add permissions to the Lambda so it can write the CloudWatch Logs via AWSLambdaBasicExecutionRole
- Add permissions to the Lambda so it can use Amazon Simple Email Service via AmazonSESFullAccess
- We do a final review of the previous configurations and then create the new Role
Then we need to create our Lambda function, from scratch, and specially picking the role we just created.
Activating Function URL for Lambda In this scenario, I don’t want to expose the lambda via HTTP using an API Gateway, just for one function. So the other possible solution for this is to check the Function URL option in the Additional Configurations panel. This way the Lambda will have an endpoint that can be called via HTTP(S) directly.
For the Auth Type choose NONE since this is going to be a “Public” endpoint, but additionally I’ll configure a CORs policy so it only get’s called from the site I define. In this case https://roccosada.com. To do so we need to check the option Configure cross-origin resource sharing (CORS)
CORS for Function URL
In the configuration tab, Function URL section we can edit the CORS policy. In the Allow Origin input we can set the URL from which the Lambda endpoint can be called. We replace * with https://roccosada.com/ and save.
Script for Lambda
This script is a simple Nodejs one to handle the email sending process
import AWS from 'aws-sdk'
const ses = new AWS.SES({ region: 'us-east-1' }) // Adjunts region SES
export const handler = async (event) => { try { // Validate origin (extra for security) const allowedOrigin = 'https://roccosada.com' const origin = event.headers?.origin || ''
if (origin !== allowedOrigin) { return { statusCode: 403, body: JSON.stringify({ error: 'Forbidden' }) } }
// Parse body const body = JSON.parse(event.body) const { name, email, message } = body
// Params of SES const params = { Destination: { ToAddresses: ['customemail@mail.com'] }, // your mail verified in SES Message: { Body: { Text: { Data: `From: ${name} <${email}>\n\n${message}` } }, Subject: { Data: '📩 New message from your blog' } }, Source: 'anotheremail@mail.com' // also must be verified in SES }
await ses.sendEmail(params).promise()
return { statusCode: 200, headers: { 'Access-Control-Allow-Origin': allowedOrigin, 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' }, body: JSON.stringify({ success: true }) } } catch (err) { console.error('Error SES:', err) return { statusCode: 500, body: JSON.stringify({ error: 'Error sending the email' }) } }}👉 Este handler:
Rechaza requests que no vengan de tu dominio.
Envía email solo a tu casilla verificada.
Responde con CORS configurado.
🔹 Paso 2. Crear la Lambda
Si usás AWS CLI:
zip function.zip index.mjs package.json
aws lambda create-function
—function-name ContactFormHandler
—runtime nodejs18.x
—handler index.handler
—zip-file fileb://function.zip
—role arn:aws:iam::
Necesitas un IAM Role con al menos la policy AmazonSESFullAccess (o granular con ses:SendEmail).
🔹 Paso 3. Crear el Function URL
aws lambda create-function-url-config
—function-name ContactFormHandler
—auth-type NONE
—cors ‘AllowOrigins=[“https://roccosada.com”],AllowMethods=[“POST”,“OPTIONS”],AllowHeaders=[“content-type”]’
Esto te devuelve algo como:
https://abcd1234.lambda-url.us-east-1.on.aws/
🔹 Paso 4. Formulario en Astro
Ejemplo de integración:
🔹 Paso 5. Verificación en SES
Verifica remitente (contacto@roccosada.com).
Verifica destinatario (tucorreo@gmail.com).
Mientras estés en sandbox, los mails solo llegarán a direcciones verificadas.