使用 AWS Lambda 自定义分段 - Amazon Pinpoint

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

使用 AWS Lambda 自定义分段

这是适用于公共测试版中功能的预发行文档。本文档随时可能更改。

您可以使用 AWS Lambda 函数来定制 Amazon Pinpoint 活动与您的目标受众互动的方式。借助 AWS Lambda,您可以在 Amazon Pinpoint 发送活动消息的那一刻修改活动的分段。

AWS Lambda 是一项计算服务,您可用来运行代码而无需预配置或管理服务器。您可将代码打包并作为 Lambda 函数上传到 Lambda。当一个函数被调用(由您手动调用,或者为响应事件而自动调用)时,Lambda 会运行该函数。有关更多信息,请参阅 AWS Lambda 开发人员指南

要将 Lambda 函数分配给活动,您可以使用 Amazon Pinpoint API中的活动资源定义活动的 CampaignHook 设置。这些设置包括 Lambda 函数名称。还包括 CampaignHook 模式,用于指定 Amazon Pinpoint 是否接收函数返回值。

您分配给活动的 Lambda 函数称为 Amazon Pinpoint 扩展

定义了 CampaignHook 设置之后,Amazon Pinpoint 会在运行活动时自动调用 Lambda 函数,然后再发送活动消息。当 Amazon Pinpoint 调用该函数时,它会提供有关消息传送的事件数据。此数据包括活动的分段,即 Amazon Pinpoint 将消息发送到的端点的列表。

如果 CampaignHook 模式设置为 FILTER,则在发送消息之前,Amazon Pinpoint 会允许该函数修改并返回分段。例如,该函数可能会使用包含来自 Amazon Pinpoint 外部的源中数据的属性更新端点定义。或者,该函数可能会根据函数代码中的条件删除某些端点,从而筛选分段。Amazon Pinpoint 从您的函数收到修改后的分段之后,它会使用活动的传送渠道,将消息发送到分段的每个端点。

通过使用 AWS Lambda 来处理您的分段,您可以更好地控制将消息发送给哪些用户以及这些消息中包含什么内容。您可以在发送活动消息的那一刻实时定制您的活动。通过筛选分段,您可以与定义更加明确的分段子集进行互动。通过添加或更新端点属性,您还可以使新数据可供消息变量使用。

注意

您还可以使用 CampaignHook 设置来分配处理消息传输的 Lambda 函数。这种类型的函数对于通过 Amazon Pinpoint 不支持的自定义渠道(例如社交媒体平台)传送消息非常有用。有关更多信息,请参阅在 Amazon Pinpoint 中创建自定义渠道

使用 Amazon Pinpoint 调用 Lambda 钩子时,Lambda 函数还必须与 Amazon Pinpoint 项目位于同一区域。

要使用 AWS Lambda 修改活动分段,请先创建一个函数,由其负责处理 Amazon Pinpoint 所发送的事件数据并返回修改后的分段。然后,通过分配 Lambda 函数策略来授权 Amazon Pinpoint 调用该函数。最后,通过定义 CampaignHook 设置,将该函数分配给一个或多个活动。

事件数据

当 Amazon Pinpoint 调用您的 Lambda 函数时,它会提供以下负载作为事件数据:

{ "MessageConfiguration": {Message configuration} "ApplicationId": ApplicationId, "CampaignId": CampaignId, "TreatmentId": TreatmentId, "ActivityId": ActivityId, "ScheduledTime": Scheduled Time, "Endpoints": { EndpointId: {Endpoint definition} . . . } }

AWS Lambda 将事件数据传递到您的函数代码。事件数据提供了以下属性:

  • MessageConfiguration – 具有与 Amazon Pinpoint API 中消息资源的 DirectMessageConfiguration 对象相同的结构。

  • ApplicationId – 活动所属的 Amazon Pinpoint 项目的 ID。

  • CampaignId – 为其调用该函数的 Amazon Pinpoint 活动的 ID。

  • TreatmentId – 用于 A/B 测试的活动变体的 ID。

  • ActivityId – 由活动执行的活动的 ID。

  • ScheduledTime – 将传输活动消息的日期和时间,采用 ISO 8601 格式。

  • Endpoints – 将端点 ID 与端点定义关联的映射。每个事件数据负载最多可包含 50 个端点。如果活动分段包含的端点数超过 50 个,则 Amazon Pinpoint 将重复调用该函数,一次最多处理 50 个端点,直至处理完所有端点。

创建 Lambda 函数

要了解如何创建 Lambda 函数,请参阅《AWS Lambda 开发人员指南》中的入门。当您创建函数时,请注意在以下条件下,消息传送会失败:

  • Lambda 函数需要超过 15 秒才能返回修改后的分段。

  • Amazon Pinpoint 无法解码该函数的返回值。

  • 需要从 Amazon Pinpoint 调用 3 次以上才能成功调用该函数。

Amazon Pinpoint 只接受该函数返回值中的端点定义。该函数无法修改事件数据中的其他元素。

示例 Lambda 函数

您的 Lambda 函数处理 Amazon Pinpoint 发送的事件数据,并返回修改后的端点,如以下示例处理程序(使用 Node.js 编写)所示:

'use strict'; exports.handler = (event, context, callback) => { for (var key in event.Endpoints) { if (event.Endpoints.hasOwnProperty(key)) { var endpoint = event.Endpoints[key]; var attr = endpoint.Attributes; if (!attr) { attr = {}; endpoint.Attributes = attr; } attr["CreditScore"] = [ Math.floor(Math.random() * 200) + 650]; } } console.log("Received event:", JSON.stringify(event, null, 2)); callback(null, event.Endpoints); };

Lambda 将事件数据作为 event 参数传递给处理程序。

在此示例中,处理程序迭代 event.Endpoints 对象中的每个端点,并将新属性 CreditScore 添加到端点。CreditScore 属性的值只是一个随机数字。

console.log() 语句将事件记录在 CloudWatch Logs 中。

callback() 语句将修改后的端点返回到 Amazon Pinpoint。通常,callback 参数在 Node.js Lambda 函数中是可选的,但在此上下文中是必需的,因为该函数必须将更新后的端点返回给 Amazon Pinpoint。

函数返回端点的格式必须与事件数据提供的格式相同,该格式是一个将端点 ID 与端点定义关联起来的映射,如以下示例中所示:

{ "eqmj8wpxszeqy/b3vch04sn41yw": { "ChannelType": "GCM", "Address": "4d5e6f1a2b3c4d5e6f7g8h9i0j1a2b3c", "EndpointStatus": "ACTIVE", "OptOut": "NONE", "Demographic": { "Make": "android" }, "EffectiveDate": "2017-11-02T21:26:48.598Z", "User": {} }, "idrexqqtn8sbwfex0ouscod0yto": { "ChannelType": "APNS", "Address": "1a2b3c4d5e6f7g8h9i0j1a2b3c4d5e6f", "EndpointStatus": "ACTIVE", "OptOut": "NONE", "Demographic": { "Make": "apple" }, "EffectiveDate": "2017-11-02T21:26:48.598Z", "User": {} } }

示例函数会修改并返回在事件数据中收到的 event.Endpoints 对象。

(可选)您可以在返回的端点定义中包含 TitleOverrideBodyOverride 属性。

注意

当您使用此解决方案发送消息时,对于 ChannelType 属性值为以下之一的端点,Amazon Pinpoint 只接受 TitleOverrideBodyOverride 属性:ADMAPNSAPNS_SANDBOXAPNS_VOIPAPNS_VOIP_SANDBOXBAIDUGCMSMS

对于 ChannelType 属性值为 EMAIL 的端点,Amazon Pinpoint 支持这些属性。

分配 Lambda 函数策略

要使用 Lambda 函数处理您的端点,您必须先授权 Amazon Pinpoint 调用您的 Lambda 函数。要授予调用权限,请为该函数分配 Lambda 函数策略。Lambda 函数策略是一种基于资源的权限策略,它指定哪些实体可以使用您的函数以及这些实体可以执行哪些操作。

有关更多信息,请参阅《AWS Lambda 开发人员指南》中的将基于资源的策略用于 AWS Lambda

示例函数策略

以下策略授予 Amazon Pinpoint 服务主体对特定活动 (campaign-id) 使用 lambda:InvokeFunction 操作的权限:

{ "Sid": "sid", "Effect": "Allow", "Principal": { "Service": "pinpoint.us-east-1.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "{arn:aws:lambda:us-east-1:account-id:function:function-name}", "Condition": { "StringEquals": { "AWS:SourceAccount": "111122223333" }, "ArnLike": { "AWS:SourceArn": "arn:aws:mobiletargeting:us-east-1:account-id:apps/application-id/campaigns/campaign-id" } } }

您的函数策略需要包含 AWS:SourceArn 密钥的 Condition 块。此代码声明允许哪个 Amazon Pinpoint 活动调用该函数。在本示例中,策略仅将权限授予一个活动。Condition 块还必须包含一个 AWS:SourceAccount 密钥,用于控制哪个 AWS 账户可以调用该操作。

要编写更为通用的策略,请使用多字符匹配通配符 (*)。例如,您可以使用以下 Condition 块来允许特定 Amazon Pinpoint 项目 (application-id) 中的任何活动调用该函数:

... "Condition": { "StringEquals": { "AWS:SourceAccount": "111122223333" }, "ArnLike": { "AWS:SourceArn": "arn:aws:mobiletargeting:us-east-1:account-id:apps/application-id/campaigns/*" } } ...

如果您希望 Lambda 函数成为项目的所有活动使用的默认函数,建议您按上述方法配置策略的 Condition 块。有关将 Lambda 函数设置为项目中的所有活动的默认函数的信息,请参阅将 Lambda 函数分配给活动

授予 Amazon Pinpoint 调用权限

您可以使用 AWS Command Line Interface (AWS CLI) 将权限添加到分配给您的 Lambda 函数的 Lambda 函数策略。要允许 Amazon Pinpoint 为特定活动调用函数,请使用 Lambda add-permission 命令,如以下示例所示:

$ aws lambda add-permission \ > --function-name function-name \ > --statement-id sid \ > --action lambda:InvokeFunction \ > --principal pinpoint.us-east-1.amazonaws.com \ > --source-account 111122223333 > --source-arn arn:aws:mobiletargeting:us-east-1:account-id:apps/application-id/campaigns/campaign-id

您可以使用 AWS CLI 中的 get-campaigns 命令来查找活动 ID。您也可以使用 get-apps 命令查找您的应用程序 ID。

运行 Lambda add-permission 命令时,Lambda 返回以下输出:

{ "Statement": "{\"Sid\":\"sid\", \"Effect\":\"Allow\", \"Principal\":{\"Service\":\"pinpoint.us-east-1.amazonaws.com\"}, \"Action\":\"lambda:InvokeFunction\", \"Resource\":\"arn:aws:lambda:us-east-1:111122223333:function:function-name\", \"Condition\": {\"ArnLike\": {\"AWS:SourceArn\": \"arn:aws:mobiletargeting:us-east-1:111122223333:apps/application-id/campaigns/campaign-id\"}} {\"StringEquals\": {\"AWS:SourceAccount\": \"111122223333\"}}} }

Statement 值是已添加到 Lambda 函数策略的语句的 JSON 字符串版本。

将 Lambda 函数分配给活动

您可以将 Lambda 函数分配给单独的 Amazon Pinpoint 活动。或者,将 Lambda 函数设置为某个项目的所有活动(除了单独分配函数的活动之外)默认使用的函数。

要将 Lambda 函数分配给单独的活动,请使用 Amazon Pinpoint API 来创建或更新 Campaign 对象,并定义其 CampaignHook 属性。要将某个 Lambda 函数设置为某个项目中所有活动的默认函数,请创建或更新该项目的 Settings 资源并定义其 CampaignHook 对象。

在两种情况下,设置以下 CampaignHook 属性:

  • LambdaFunctionName – 在发送活动消息之前 Amazon Pinpoint 调用的 Lambda 函数的名称或 ARN。

  • Mode – 设置为 FILTER。使用此模式时,Amazon Pinpoint 会调用该函数并等待它返回修改后的端点。收到端点之后,Amazon Pinpoint 将发送消息。Amazon Pinpoint 最多等待 15 秒钟,如果 15 秒后未收到返回结果,则认为消息传送失败。

借助为活动定义的 CampaignHook 设置,Amazon Pinpoint 将在发送活动消息之前调用指定的 Lambda 函数。Amazon Pinpoint 会等待接收该函数返回的修改后的端点。如果 Amazon Pinpoint 收到更新后的端点,它会使用更新后的端点数据继续消息传送。