从错过的航班到任务:在 AWS 上构建 24 小时提醒服务
发布: (2025年11月30日 GMT+8 05:19)
4 min read
原文: Dev.to
Source: Dev.to
🛠️ 技术栈
- 数据层: DynamoDB 表用于存储预约(
Name、Date、Time)。 - 计算层: AWS Lambda 扫描表,判断哪些预约需要提醒。
- 通知层: Amazon SNS 发送电子邮件 / 短信通知。
步骤详解
1. 创建 DynamoDB 表
| 属性 | 值 |
|---|---|
| 表名 | Appointment |
| 主键 | 分区键 = Name(字符串) |
| 属性 | Name – 例如 “Dentist Visit” Date – ISO 格式字符串,例如 2025-12-29 Time – 可选,24 小时制 (HH:mm) |
如需为每个用户发送通知,可额外添加属性(例如
UserEmail)。
2. 创建 SNS 主题并订阅
- 打开 Amazon SNS → Topics → Create topic。
- 主题名称:
AppointmentReminders(Standard)。 - 复制 Topic ARN —— 稍后在 Lambda 代码中使用。
- 添加订阅:
- 协议: Email(或 SMS)。
- 终端: 你的电子邮件地址(或手机号码)。
- 通过 AWS 发送的链接确认订阅。
3. 创建 Lambda 函数(Node.js)
配置
- 运行时: Node.js 18.x
- 处理程序:
index.handler - 内存 / 超时: 128 MB,30 秒(可自行调整)
index.js
// index.js
const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb");
const { SNSClient, PublishCommand } = require("@aws-sdk/client-sns");
// Environment variables (set in Lambda console)
const TABLE_NAME = process.env.APPOINTMENT_TABLE;
const SNS_TOPIC_ARN = process.env.SNS_TOPIC_ARN;
const ddb = new DynamoDBClient({});
const sns = new SNSClient({});
exports.handler = async () => {
// 1️⃣ Scan the Appointment table
const scanParams = {
TableName: TABLE_NAME,
ProjectionExpression: "Name, #d, #t, Email",
ExpressionAttributeNames: {
"#d": "Date",
"#t": "Time"
}
};
const data = await ddb.send(new ScanCommand(scanParams));
// 2️⃣ Determine which items are within the next 24 h
const now = new Date();
const next24h = new Date(now.getTime() + 24 * 60 * 60 * 1000);
const reminders = data.Items.filter(item => {
const dateStr = item.Date.S; // e.g. "2025-12-29"
const timeStr = item.Time?.S || "00:00"; // optional, default midnight
const apptDate = new Date(`${dateStr}T${timeStr}:00Z`);
return apptDate > now && apptDate <= next24h;
});
// 3️⃣ Publish a reminder for each upcoming appointment
for (const appt of reminders) {
const message = `Reminder: ${appt.Name.S} on ${appt.Date.S} at ${appt.Time?.S || "00:00"}.`;
const publishParams = {
TopicArn: SNS_TOPIC_ARN,
Message: message,
Subject: "24‑hour Appointment Reminder",
MessageAttributes: {
"email": {
DataType: "String",
StringValue: appt.Email?.S || ""
}
}
};
await sns.send(new PublishCommand(publishParams));
}
return {
statusCode: 200,
body: `Sent ${reminders.length} reminder(s).`
};
};
在 Lambda 控制台中设置的环境变量
| 变量 | 值 |
|---|---|
APPOINTMENT_TABLE | Appointment |
SNS_TOPIC_ARN | AppointmentReminders 主题的 ARN |
4. 为 Lambda 配置 IAM 权限
将以下内联策略(或托管策略)附加到 Lambda 执行角色,以授予所需权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:GetItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/Appointment"
},
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:*:*:AppointmentReminders"
}
]
}
5. 在 DynamoDB 中添加测试项
| Name | Date | Time | |
|---|---|---|---|
| Dentist Visit | 2025-12-29 | 09:00 | your.email@example.com |
可通过 DynamoDB 控制台或 AWS CLI 添加:
aws dynamodb put-item \
--table-name Appointment \
--item '{"Name":{"S":"Dentist Visit"},"Date":{"S":"2025-12-29"},"Time":{"S":"09:00"},"Email":{"S":"your.email@example.com"}}'
6. 测试 Lambda
- 在 Lambda 控制台点击 Test,创建一个简单事件(函数本身不使用负载)。
- 运行测试。
- 检查你的电子邮件(或短信)——应收到类似以下内容的消息:
Subject: 24‑hour Appointment Reminder
Message: Reminder: Dentist Visit on 2025-12-29 at 09:00.
如果收到了邮件,说明端到端流程已成功。
🚀 我的收获
- 忘记很容易,系统不会。 一个小型的无服务器栈可以可靠地给你提前提醒。
- 24 小时的提前时间 足以让人做好准备,又不会显得打扰。
- 你不需要庞大的平台——只要一个 DynamoDB 表、一个 Lambda 函数、一个 SNS 主题以及一个定时触发器(如 CloudWatch Events / EventBridge)每天运行一次即可。
- 完成此项目巩固了核心 DevOps / 云工程 技能:最小权限 IAM 策略、Lambda 开发、DynamoDB 数据建模以及 SNS 通知。
这就是完整的提醒服务——简单、低成本且高效。祝构建愉快!