You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Serverless、DynamoDB与Node.js通过Amazon SES发送邮件?求方案

正确解决方案

1. 修复HTML内容显示问题

原代码中message字段使用了转义的<p>,SES发送HTML邮件时需要传入未转义的HTML字符串,否则收件人会看到纯文本形式的转义标签而非格式化内容。如果你的消息是从外部(如数据库)获取的转义内容,可通过反转义处理:

// 反转义HTML内容工具函数
function unescapeHtml(str) {
  return str.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
}

const params = {
    id: uuid.v1(),
    to: 'recipient@example.com',
    from: 'sender@example.com',
    subject: 'Test Email',
    message: '<p>Hello World!</p>' // 直接用未转义HTML,或用上面的函数处理转义内容
};

2. 完善Serverless环境下的SDK初始化

Serverless环境会自动注入AWS角色权限,无需手动配置凭证,只需正确初始化SES和DynamoDB客户端:

const AWS = require('aws-sdk');
const ses = new AWS.SES({ region: 'us-east-1' }); // 替换为你的SES所在区域
const uuid = require('uuid');
const dynamodb = new AWS.DynamoDB.DocumentClient(); // 初始化DynamoDB客户端

3. 整合DynamoDB记录存储逻辑

结合需求将邮件发送记录存入DynamoDB,同时用async/await替代回调提升代码可读性:

async function sendEmailAndRecord() {
  const params = {
      id: uuid.v1(),
      to: 'recipient@example.com',
      from: 'sender@example.com',
      subject: 'Test Email',
      message: '<p>Hello World!</p>'
  };

  // 构建SES发送参数
  const emailParams = {
      Destination: {
          ToAddresses: [params.to]
      },
      Message: {
          Body: {
              Html: {
                  Data: params.message,
                  Charset: 'UTF-8' // 指定字符集避免乱码
              }
          },
          Subject: {
              Data: params.subject,
              Charset: 'UTF-8'
          }
      },
      Source: params.from
  };

  try {
    // 发送邮件
    const sesResponse = await ses.sendEmail(emailParams).promise();
    console.log('邮件发送成功:', sesResponse);

    // 写入DynamoDB成功记录
    const dbSuccessParams = {
      TableName: 'EmailLogs', // 替换为你的DynamoDB表名
      Item: {
        id: params.id,
        to: params.to,
        from: params.from,
        subject: params.subject,
        message: params.message,
        sentAt: new Date().toISOString(),
        sesMessageId: sesResponse.MessageId,
        status: 'SUCCESS'
      }
    };
    await dynamodb.put(dbSuccessParams).promise();
    console.log('记录已存入DynamoDB');

    return {
      statusCode: 200,
      body: JSON.stringify({ message: '邮件发送成功' })
    };
  } catch (err) {
    console.error('发送失败:', err);

    // 写入DynamoDB失败记录
    const dbFailParams = {
      TableName: 'EmailLogs',
      Item: {
        id: params.id,
        to: params.to,
        from: params.from,
        subject: params.subject,
        message: params.message,
        sentAt: new Date().toISOString(),
        error: err.message,
        status: 'FAILED'
      }
    };
    await dynamodb.put(dbFailParams).promise();

    return {
      statusCode: 500,
      body: JSON.stringify({ error: '邮件发送失败' })
    };
  }
}

// Serverless函数导出
module.exports.handler = async (event) => {
  return await sendEmailAndRecord();
};

4. 配置Serverless权限

在serverless.yml中添加SES发送和DynamoDB写入的权限:

service: email-service

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - ses:SendEmail
        - ses:SendRawEmail
      Resource: "*"
    - Effect: Allow
      Action:
        - dynamodb:PutItem
      Resource: "arn:aws:dynamodb:${self:provider.region}:*:table/EmailLogs"

functions:
  sendEmail:
    handler: handler.handler
    events:
      - http:
          path: send-email
          method: post

5. 关键注意事项

  • SES发件邮箱需完成验证,沙箱模式下仅能发送到已验证的收件邮箱,生产环境需申请移出沙箱。
  • 替换代码中的AWS区域、DynamoDB表名为实际值。
  • 确保Serverless部署的角色拥有对应权限,避免因权限不足导致发送失败。

内容的提问来源于stack exchange,提问作者Deva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:15:01