View a markdown version of this page

设置动态流 - AWS 最终用户社交消息

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

设置动态流

动态流程在运行时调用您自己的 HTTPS 端点来获取屏幕内容并决定导航。静态流定义了 Flow JSON 中的所有屏幕。相反,用户每次在屏幕之间导航时,动态流都会使用该data_exchange操作从您的终端节点请求数据。这样可以实现以数据为导向的个性化体验,例如向用户显示其未平仓订单、验证服务器端输入或根据后端决策进行分支。

当用户与动态流交互时,Meta 会通过加密请求直接调用您的端点。您的终端节点解密请求,运行您的业务逻辑,加密响应,然后将其返回给 Meta。加密的请求和响应直接在 Meta 和您的终端节点之间传递,因此 AWS 最终用户 Messaging Social 永远无法访问这些交易所的解密内容。 AWS 最终用户消息 Social 负责管理控制平面:创建和更新 Flow、上传加密公钥以及交付 Flow 运行状况网络挂钩。

要设置动态流,请完成以下步骤:

  1. 部署 HTTPS 终端节点。

  2. 上传企业公钥进行加密。

  3. 使用您的终端节点 URI 创建 Flow。

  4. 附上您的 Meta 应用程序以进行请求验证。

  5. 发布流程。

第 1 步:部署 HTTPS 终端节点

您的终端节点必须满足以下要求:

  • 使用有效的 TLS 证书可公开访问的 HTTPS 网址。

  • 在 10 秒内响应。Meta 强制执行硬超时并监控 p90 延迟。持续超过延迟阈值或返回错误的端点可能会受到限制或阻止。

  • 接受包含加密 JSON 有效负载的 POST 请求。

  • 以text/plain(base64 编码)形式返回加密的响应。

您可以使用任何提供公共 HTTPS 网址的计算选项。常见的方法包括:

  • AWS Lambda 函数 URL — 具有内置 HTTPS 端点的单一函数。将授权类型设置NONE为,因为 Meta 不使用。您可以使用您在中配置的业务加密密钥对对对请求进行身份验证第 2 步:上传企业公钥。

  • 带有 Lambda 的 Amazon API Gateway — 提供额外的控制措施,例如限制来源 IP、 AWS WAF 规则和限制的资源策略。

  • 使用 Lambda 目标实现弹性负载平衡 — 当您想与现有的负载平衡基础设施相结合时很有用。

  • 任何其他 HTTPS 服务器(容器、亚马逊 EC2 实例或外部服务)。

您的端点必须实现 Meta 的数据交换合约,该合约处理以下请求类型:

  • 运行状况检查 — Meta 定期发送ping请求以验证您的终端节点是否可用。回复时使用{"data": {"status": "active"}}。

  • INIT — 当用户打开流程时发送。返回初始屏幕及其数据。

  • data_exchange — 用户每次提交屏幕时发送。返回下一个屏幕及其数据。

  • 返回 — 当用户导航回上一个屏幕时发送。

有关完整的端点实施指南,包括多种语言的加密和解密代码示例,请参阅 Meta for Developers 网站上的 “实现您的 Flow 端点”。

第 2 步:上传企业公钥

Meta 使用您的 RSA (Rivest-Shamir-Adleman) 公钥对所有数据交换请求进行端到端加密。您的终端节点使用相应的私钥对请求进行解密。 AWS 最终用户消息 Social 代表你将公钥上传到 Meta,但从不访问或存储私钥。

使用 PutWhatsAppBusinessPublicKey API 上传电话号码的公钥。您必须准确提供以下内容之一:

  • PEM-encoded RSA 公钥 — 直接提供密钥。您的终端节点持有相应的私钥用于解密。

  • AWS Key Management Service 密钥 ARN — 提供非对称 RSA-2048 KMS 密钥的 ARN。 AWS 最终用户消息 Social 仅读取公众一半正在使用kms:GetPublicKey并将其上传到 Meta。私钥永远不会离开 AWS KMS。您的终端节点kms:Decrypt用于在运行时解密请求。

提供两者或两者都不提供会返回InvalidParametersException.

PEM 模式

生成 RSA 密钥对并上传公钥:

# Generate a key pair openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -pubout -out public.pem # Upload the public key aws social-messaging put-whatsapp-business-public-key \ --origination-phone-number-id {PHONE_NUMBER_ID} \ --business-public-key "$(cat public.pem)"

安全地存储私钥并将其提供给您的终端节点进行解密。

AWS KMS mode

创建非对称 RSA KMS 密钥并上传其 ARN:

# Create the KMS key KMS_KEY_ARN=$(aws kms create-key \ --key-spec RSA_2048 \ --key-usage ENCRYPT_DECRYPT \ --description "WhatsApp Dynamic Flow encryption key" \ --query KeyMetadata.Arn --output text) # Upload the KMS key ARN aws social-messaging put-whatsapp-business-public-key \ --origination-phone-number-id {PHONE_NUMBER_ID} \ --kms-key-arn $KMS_KEY_ARN

KMS 密钥策略必须授予以下权限:

  • kms:GetPublicKey致social-messaging.amazonaws.com服务负责人。这允许 AWS 最终用户消息社交读取公钥并将其上传到 Meta。

  • kms:Decrypt到您的终端节点的执行角色。这允许您的终端节点解密传入的数据交换请求。 AWS 最终用户消息 Social 从kms:Decrypt不使用此密钥。

验证密钥

使用 GetWhatsAppBusinessPublicKey API 验证存储的密钥并检查 Meta 的签名状态:

aws social-messaging get-whatsapp-business-public-key \ --origination-phone-number-id {PHONE_NUMBER_ID}

响应包括存储的 PEM 和 Meta 的签名状态(VALID或MISMATCH)。MISMATCH状态表示存储的密钥与 Meta 的预期不匹配。如果您看到此状态,请上传新密钥。

第 3 步:使用端点创建 Flow

创建动态流时,为--endpoint-uri参数提供您的 HTTPS 终端节点 URL。Flow JSON 还必须声明data_api_version,这会告诉 Meta 在 Flow 会话期间调用您的终端节点。

aws social-messaging create-whatsapp-flow \ --id {WABA_ID} \ --flow-name "my_dynamic_flow" \ --categories '["OTHER"]' \ --flow-json fileb://flow.json \ --endpoint-uri "https://your-endpoint.example.com/flow"

您还可以使用以下方法在现有 DRAFT Flow 上添加或更改端点UpdateWhatsAppFlow:

aws social-messaging update-whatsapp-flow \ --id {WABA_ID} \ --flow-id {FLOW_ID} \ --endpoint-uri "https://your-endpoint.example.com/flow"
注意

当您发布动态流程时,Meta 会对您的终端节点执行同步运行状况检查。如果终端节点没有响应或返回错误,则发布操作将失败,并出现 Meta 错误,例如131000(“验证终端节点是否可用以及您是否实施了运行状况检查”)。企业公钥丢失或无效也可能导致此错误。在发布之前,请确保您的终端节点已部署并对ping请求作出响应,并且您上传了有效的企业公钥(请参阅第 2 步:上传企业公钥)。

要验证为 Flow 配置的端点和数据 API 版本,请使用GetWhatsAppFlow:

aws social-messaging get-whatsapp-flow \ --id {WABA_ID} \ --flow-id {FLOW_ID}

响应包括 Meta 保存的endpointUri内容、在 Flow JSON 中dataApiVersion声明的以及当前附带的内容application。

第 4 步:附上您的 Meta 应用程序以进行请求验证

默认情况下,当您通过 AWS 最终用户消息社交创建 Flow 时,它与该服务的元应用程序相关联。要验证向您的终端节点发出的数据交换请求是否源自 Meta,请将您自己的 Meta 应用程序附加到 Flow。如果没有附上自己的应用程序,则无法进行请求来源验证。附加您的应用程序可让您访问验证 Meta 在每个请求中包含的 X-Hub-Signature-256 HMAC 标头所需的应用程序密钥。

aws social-messaging update-whatsapp-flow \ --id {WABA_ID} \ --flow-id {FLOW_ID} \ --meta-app-id "{YOUR_META_APP_ID}"

Meta 应用程序必须归拥有企业账户 (WABA) 的同一个 WhatsApp 企业所有。

重要

附加您自己的 Meta 应用程序是单向操作。连接应用程序后,无法重新连接该服务的应用程序。这不会影响 Flow 功能。只有新的 Flow 会重置应用程序关联。

您可以在同一个呼叫或单独的通话中设置--endpoint-uri和--meta-app-id。这两个字段是独立的。

连接您的应用程序后,通过调用GetWhatsAppFlow并检查响应中的application字段来验证配置。application.id应与您提供的 Meta 应用程序 ID 相匹配。

保护您的终端节点

由于 Meta 直接调用您的终端节点,因此请考虑以下安全措施:

  • 验证请求签名 — 如果您附加了自己的 Meta 应用程序(步骤 4),请使用应用程序密钥来验证每个请求的X-Hub-Signature-256 HMAC-SHA256 标头。这确认了源自 Meta 的请求。如果验证失败,则返回 HTTP 状态 432。

  • 验证流量令牌 -将 Flow 发送给用户时,flow_token为每个 Flow 会话生成一个独一无二的、不可预测的。您的终端节点在加密负载内接收令牌,并应根据活动会话对其进行验证。拒绝带有未知、过期或已完成令牌的请求。这可以防止未经授权或重放的请求到达您的业务逻辑。

  • 无需令牌验证即可处理运行状况检查 — Meta 定期发送ping请求以监控端点运行状况。这些请求不包含flow_token. 无需令牌验证即可响应运行状况检查,因为拒绝运行状况检查会降低终端节点的可用性分数。

  • 返回相应的状态码 -如果您的端点无法解密请求(Meta 重新获取公钥并重试),则返回 421。如果无效,flow_token则返回 427(Meta 禁用该会话的 Flow 按钮)。

编写动态流 JSON

动态流 JSON 与静态流 JSON 有两个不同之处:

  1. 顶级data_api_version字段是必填字段。这告诉 Meta 在 Flow 会话期间调用您的端点。支持的值为"3.0"和"4.0"(推荐)。

  2. 屏幕页脚使用data_exchange动作而不是。navigate每个data_exchange操作都会将表单数据发送到您的终端节点,该端点会返回下一个屏幕及其内容。

以下示例显示了具有两个屏幕的最小动态流 JSON。第一个屏幕收集用户名并将其发送到端点。终端节点在第二个屏幕上返回个性化问候语。

{ "version": "6.0", "data_api_version": "3.0", "routing_model": { "INPUT": ["RESULT"], "RESULT": [] }, "screens": [ { "id": "INPUT", "title": "Welcome", "data": { "greeting": { "type": "string", "__example__": "Tell us your name" } }, "layout": { "type": "SingleColumnLayout", "children": [ { "type": "TextBody", "text": "${data.greeting}" }, { "type": "Form", "name": "input_form", "children": [ { "type": "TextInput", "name": "user_name", "label": "Your name", "input-type": "text", "required": true }, { "type": "Footer", "label": "Submit", "on-click-action": { "name": "data_exchange", "payload": { "user_name": "${form.user_name}" } } } ] } ] } }, { "id": "RESULT", "title": "Hello", "terminal": true, "data": { "message": { "type": "string", "__example__": "Hello, World!" } }, "layout": { "type": "SingleColumnLayout", "children": [ { "type": "TextBody", "text": "${data.message}" }, { "type": "Footer", "label": "Done", "on-click-action": { "name": "complete", "payload": {} } } ] } } ] }

有关完整的 Flow JSON 架构参考,请参阅开发者元数据网站上的 Flow JSON 。

End-to-end 示例

以下示例显示了用于设置和发布动态流程的 API 调用的完整顺序:

# 1. Upload the business public key (KMS mode) aws social-messaging put-whatsapp-business-public-key \ --origination-phone-number-id {PHONE_NUMBER_ID} \ --kms-key-arn {KMS_KEY_ARN} # 2. Create the Dynamic Flow with an endpoint FLOW_ID=$(aws social-messaging create-whatsapp-flow \ --id {WABA_ID} \ --flow-name "my_dynamic_flow" \ --categories '["OTHER"]' \ --flow-json fileb://flow.json \ --endpoint-uri "https://your-endpoint.example.com/flow" \ --query flowId --output text) # 3. Attach your Meta app for signature verification aws social-messaging update-whatsapp-flow \ --id {WABA_ID} \ --flow-id $FLOW_ID \ --meta-app-id "{YOUR_META_APP_ID}" # 4. Publish the Flow aws social-messaging publish-whatsapp-flow \ --id {WABA_ID} \ --flow-id $FLOW_ID # 5. Verify the configuration aws social-messaging get-whatsapp-flow \ --id {WABA_ID} \ --flow-id $FLOW_ID

发布后,Flow 可用于模板消息。有关发送 Flow 的更多信息,请参阅向用户发送 WhatsApp 流程。