创建计划事件以执行 Amazon Lambda 函数 - Amazon SDK for JavaScript
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon SDK for JavaScript V3 API 参考指南详细描述了 Amazon SDK for JavaScript 版本 3 (V3) 的所有 API 操作。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

创建计划事件以执行 Amazon Lambda 函数

您可以使用 Ama CloudWatch zon 事件创建调用Amazon Lambda函数的计划事件。您可以将 CloudWatch 事件配置为使用 cron 表达式来安排何时调用 Lambda 函数。例如,您可以安排一个 CloudWatch 事件,使其在每个工作日调用 Lambda 函数。

Amazon Lambda 是一项计算服务,使您无需预置或管理服务器即可运行代码。您可以使用各种编程语言创建 Lambda 函数。有关 Amazon Lambda 的更多信息,请参阅什么是 Amazon Lambda

在本教程中,您将使用 Lambda 运行时 API 创建 Lambda 函数。 JavaScript此示例调用不同的 Amazon 服务以执行特定的应用场景。例如,假设组织在员工入职一周年纪念日时向员工发送移动短信表示祝贺,如下图所示。


                DynamoDB 表

完成本教程大约需要 20 分钟。

本教程向您展示如何使用 JavaScript 逻辑来创建执行此用例的解决方案。例如,您将学习如何使用 Lambda 函数读取数据库以确定哪些员工已达到入职一周年纪念日、如何处理数据以及如何发送短信。然后,您将学习如何使用 cron 表达式在每个工作日调用 Lambda 函数。

本 Amazon 教程使用名为 Employee 的 Amazon DynamoDB 表,其中包含以下字段。

  • id - 表的主键。

  • firstName - 员工的名字。

  • phone - 员工的电话号码。

  • startDate - 员工的入职日期。


                DynamoDB 表
重要

完成费用:本文档中包含的 Amazon 服务包含在 Amazon 免费套餐中。但是,请务必在完成本教程后终止所有资源,以确保系统不会向您收费。

先决条件任务

要设置和运行此示例,您必须先完成以下任务:

  • 设置项目环境以运行这些 Node.js TypeScript 示例,并安装所需的模块Amazon SDK for JavaScript和第三方模块。按照上的说明进行操作 GitHub

  • 使用用户凭证创建共享配置文件。有关提供共享凭证文件的更多信息,请参阅《Amazon SDK 和工具参考指南》中的共享配置和凭证文件

创建 Amazon 资源

本教程要求具有以下资源。

  • 一个名为 Employee 的 Amazon DynamoDB 表,其键名为 Id,其字段如上图所示。请务必输入正确的数据,包括要用来测试此使用案例的有效手机号。有关更多信息,请参阅创建表

  • 具有执行 Lambda 函数的附加权限的 IAM 角色。

  • 一个用于托管 Lambda 函数的 Amazon S3 存储桶。

您可以手动创建这些资源,但我们建议使用本教程中所述的 Amazon CloudFormation 预置这些资源。

使用 Amazon CloudFormation 创建 Amazon

Amazon CloudFormation 让您能够以可预测、可重复的方式创建和预置 Amazon 基础设施部署。有关 Amazon CloudFormation 的更多信息,请参阅 Amazon CloudFormation 用户指南

使用 Amazon CLI 创建 Amazon CloudFormation 堆栈:

  1. 按照 Amazon CLI 用户指南中的说明安装和配置 Amazon CLI。

  2. 在项目文件夹的根目录setup.yaml中创建一个名为的文件,然后将此处的内容复制 GitHub到该文件中。

    注意

    该Amazon CloudFormation模板是使用此处Amazon CDK提供的模板生成的 GitHub。有关 Amazon CDK 的更多信息,请参阅 Amazon Cloud Development Kit (Amazon CDK) 开发人员指南

  3. 从命令行运行以下命令,将 STACK_NAME 替换为堆栈的唯一名称。

    重要

    在一个 Amazon 区域和一个 Amazon 账户中,堆栈名称必须唯一。您最多可指定 128 个字符,支持数字和连字符。

    aws cloudformation create-stack --stack-name STACK_NAME --template-body file://setup.yaml --capabilities CAPABILITY_IAM

    有关 create-stack 命令参数的更多信息,请参阅 Amazon CLI 命令参考指南Amazon CloudFormation 用户指南

    在 Amazon CloudFormation 仪表板上打开堆栈,然后选择资源选项卡,即可在控制台中查看资源列表。您将在本教程中需要这些内容。

  4. 创建堆栈后,使用 Amazon SDK for JavaScript 填充 DynamoDB 表,如填充 DynamoDB 表中所述。

填充 DynamoDB 表

要填充表,请先创建一个名为 libs 的目录,然后在其中创建一个名为 dynamoClient.js 的文件,再将下面的内容粘贴到其中。

const { DynamoDBClient } = require( "@aws-sdk/client-dynamodb" ); // Set the AWS Region. const REGION = "REGION"; // e.g. "us-east-1" // Create an Amazon DynamoDB service client object. const dynamoClient = new DynamoDBClient({region:REGION}); module.exports = { dynamoClient };

此代码可从此处获得 GitHub。

接下来,在项目文件夹的根目录populate-table.js中创建一个名为的文件,然后将此处的内容复制 GitHub到该文件中。对于其中一项,将 phone 属性的值替换为 E.164 格式的有效手机号码,将 startDate 的值替换为今天的日期。

在命令行处,运行以下命令。

node populate-table.js
const { BatchWriteItemCommand } = require( "aws-sdk/client-dynamodb" ); const {dynamoClient} = require( "./libs/dynamoClient" ); // Set the parameters. const params = { RequestItems: { Employees: [ { PutRequest: { Item: { id: { N: "1" }, firstName: { S: "Bob" }, phone: { N: "155555555555654" }, startDate: { S: "2019-12-20" }, }, }, }, { PutRequest: { Item: { id: { N: "2" }, firstName: { S: "Xing" }, phone: { N: "155555555555653" }, startDate: { S: "2019-12-17" }, }, }, }, { PutRequest: { Item: { id: { N: "55" }, firstName: { S: "Harriette" }, phone: { N: "155555555555652" }, startDate: { S: "2019-12-19" }, }, }, }, ], }, }; export const run = async () => { try { const data = await dbclient.send(new BatchWriteItemCommand(params)); console.log("Success", data); } catch (err) { console.log("Error", err); } }; run();

此代码可从此处获得 GitHub。

创建 Amazon Lambda 函数

配置 SDK

首先导入所需的 Amazon SDK for JavaScript (v3) 模块和命令:DynamoDBClient 和 DynamoDB ScanCommand,以及 SNSClient 和 Amazon SNS PublishCommand 命令。将 REGION 替换为 Amazon 区域、然后计算今天的日期并将其分配给一个参数。然后,为 ScanCommand 创建参数。将 TABLE_NAME 替换为您在此示例的创建 Amazon 资源 部分中创建的表的名称。

下面的代码段演示了此步骤。(有关完整示例,请参阅捆绑 Lambda 函数。)

"use strict"; // Load the required clients and commands. const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb"); const { SNSClient, PublishCommand } = require("@aws-sdk/client-sns"); //Set the AWS Region. const REGION = "REGION"; //e.g. "us-east-1" // Get today's date. const today = new Date(); const dd = String(today.getDate()).padStart(2, "0"); const mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0! const yyyy = today.getFullYear(); const date = yyyy + "-" + mm + "-" + dd; // Set the parameters for the ScanCommand method. const params = { // Specify which items in the results are returned. FilterExpression: "startDate = :topic", // Define the expression attribute value, which are substitutes for the values you want to compare. ExpressionAttributeValues: { ":topic": { S: date }, }, // Set the projection expression, which the the attributes that you want. ProjectionExpression: "firstName, phone", TableName: "TABLE_NAME", };

扫描 DynamoDB 表

首先,创建一个名为 sendText 的异步/等待函数,以使用 Amazon SNS PublishCommand 发布短信。然后,添加一个 try 块模式,用于扫描 DynamoDB 表中是否有工作周年纪念日在今天的员工,然后调用 sendText 函数向这些员工发送短信。如果发生错误,则将调用 catch 块。

下面的代码段演示了此步骤。(有关完整示例,请参阅捆绑 Lambda 函数。)

exports.handler = async (event, context, callback) => { // Helper function to send message using Amazon SNS. async function sendText(textParams) { try { const data = await snsclient.send(new PublishCommand(textParams)); console.log("Message sent"); } catch (err) { console.log("Error, message not sent ", err); } } try { // Scan the table to check identify employees with work anniversary today. const data = await dbclient.send(new ScanCommand(params)); data.Items.forEach(function (element, index, array) { const textParams = { PhoneNumber: element.phone.N, Message: "Hi " + element.firstName.S + "; congratulations on your work anniversary!", }; // Send message using Amazon SNS. sendText(textParams); }); } catch (err) { console.log("Error, could not scan table ", err); } };

捆绑 Lambda 函数

本主题介绍如何将此示例的 mylambdafunction.js 和所需的 Amazon SDK for JavaScript 模块捆绑到名为 index.js 的捆绑文件中。

  1. 如果您尚未安装 Webpack,请按照本示例中的先决条件任务部分进行安装。

    注意

    有关 webpack 的信息,请参阅将应用程序与 webpack 捆绑在一起

  2. 在命令行中运行以下命令,将本示例的捆绑到名 JavaScript 为的文件中<index.js>

    webpack mylamdbafunction.js --mode development --target node --devtool false --output-library-target umd -o index.js
    重要

    请注意,输出被命名为 index.js。这是因为 Lambda 函数必须有一个 index.js 处理程序才能工作。

  3. 将捆绑的输出文件 index.js 压缩到名为 my-lambda-function.zip 的 ZIP 文件中。

  4. mylambdafunction.zip 上传到您在本教程的创建 Amazon 资源 主题中创建的 Amazon S3 存储桶。

以下是 mylambdafunction.js 的完整的浏览器脚本代码。

"use strict"; // Load the required clients and commands. const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb"); const { SNSClient, PublishCommand } = require("@aws-sdk/client-sns"); //Set the AWS Region. const REGION = "REGION"; //e.g. "us-east-1" // Get today's date. const today = new Date(); const dd = String(today.getDate()).padStart(2, "0"); const mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0! const yyyy = today.getFullYear(); const date = yyyy + "-" + mm + "-" + dd; // Set the parameters for the ScanCommand method. const params = { // Specify which items in the results are returned. FilterExpression: "startDate = :topic", // Define the expression attribute value, which are substitutes for the values you want to compare. ExpressionAttributeValues: { ":topic": { S: date }, }, // Set the projection expression, which the the attributes that you want. ProjectionExpression: "firstName, phone", TableName: "TABLE_NAME", }; // Create the client service objects. const dbclient = new DynamoDBClient({ region: REGION }); const snsclient = new SNSClient({ region: REGION }); exports.handler = async (event, context, callback) => { // Helper function to send message using Amazon SNS. async function sendText(textParams) { try { const data = await snsclient.send(new PublishCommand(textParams)); console.log("Message sent"); } catch (err) { console.log("Error, message not sent ", err); } } try { // Scan the table to check identify employees with work anniversary today. const data = await dbclient.send(new ScanCommand(params)); data.Items.forEach(function (element, index, array) { const textParams = { PhoneNumber: element.phone.N, Message: "Hi " + element.firstName.S + "; congratulations on your work anniversary!", }; // Send message using Amazon SNS. sendText(textParams); }); } catch (err) { console.log("Error, could not scan table ", err); } };

部署 Lambda 函数

在项目的根目录中,创建一个 lambda-function-setup.js 文件,然后将以下内容粘贴到其中。

BUCKET_NAME 替换为您将 ZIP 版本的 Lambda 函数上传到的 Amazon S3 存储桶的名称。将 ZIP_FILE_NAME 替换为您的 ZIP 版本的 Lambda 函数的名称。将 IAM_ROLE_ARN 替换为您在本教程的创建 Amazon 资源 主题中创建的 IAM 角色的 Amazon 资源编号 (ARN)。将 LAMBDA_FUNCTION_NAME 替换为 Lambda 函数的名称。

// Load the required Lambda client and commands. const { CreateFunctionCommand, } = require("@aws-sdk/client-lambda"); const { lambdaClient } = require("..libs/lambdaClient.js"); // Instantiate an Lambda client service object. const lambda = new LambdaClient({ region: REGION }); // Set the parameters. const params = { Code: { S3Bucket: "BUCKET_NAME", // BUCKET_NAME S3Key: "ZIP_FILE_NAME", // ZIP_FILE_NAME }, FunctionName: "LAMBDA_FUNCTION_NAME", Handler: "index.handler", Role: "IAM_ROLE_ARN", // IAM_ROLE_ARN; e.g., arn:aws:iam::650138640062:role/v3-lambda-tutorial-lambda-role Runtime: "nodejs12.x", Description: "Scans a DynamoDB table of employee details and using Amazon Simple Notification Services (Amazon SNS) to " + "send employees an email the each anniversary of their start-date.", }; const run = async () => { try { const data = await lambda.send(new CreateFunctionCommand(params)); console.log("Success", data); // successful response } catch (err) { console.log("Error", err); // an error occurred } }; run();

在命令行中输入以下内容以部署 Lambda 函数。

node lambda-function-setup.js

此代码示例可在此处找到 GitHub

配置 CloudWatch 为调用 Lambda 函数

CloudWatch 要配置为调用 Lambda 函数,请执行以下操作:

  1. 打开 Lambda 控制台的函数页面。

  2. 选择 Lambda 函数。

  3. 设计器下方,选择添加触发器

  4. 将触发器类型设置为 CloudWatch Events/ EventBridge

  5. 对于“规则”,选择创建新规则

  6. 填写“规则名称”和“规则描述”。

  7. 对于规则类型,请选择计划表达式

  8. 计划表达式字段中,输入一个 cron 表达式。例如,cron(0 12 ? * MON-FRI *)

  9. 选择添加

    注意

    有关更多信息,请参阅将 Lambda 与事件配合 CloudWatch 使用

删除资源

恭喜您!您已使用亚马逊 CloudWatch 计划的事件调用了 Lambda 函数。Amazon SDK for JavaScript如本教程开头所述,请务必在学习本教程时终止您创建的所有资源,以确保系统不会向您收费。您可以通过删除在本教程的创建 Amazon 资源 主题中创建的 Amazon CloudFormation 堆栈来实现此目的,方法如下所示:

  1. 打开Amazon CloudFormation控制台

  2. 堆栈页面上,选择堆栈。

  3. 选择 删除