如何使用 Webhooks 将 Amazon SNS 消息发布给 Amazon Chime、Slack 或 Microsoft 团队?

上次更新时间:2020 年 4 月 29 日

我想要使用 Webhooks 将我的 AWS 环境与 Amazon Chime 聊天室,或与 Slack 或 Microsoft 团队渠道连接。如何将来自 Amazon Simple Notification Service (Amazon SNS) 的通知发送至 Webhook?

简短描述

您可以使用 Amazon SNS 将通知消息发送至 HTTP(S) 终端节点,例如 Webhook URL。然而,有些 Webhooks 希望在确认 HTTP(S) 订阅时收到 Amazon SNS 不支持的 JSON 键值对。例如,Amazon Chime Webhooks 希望收到其中包含对应于 "Content" 键的消息字符串的 JSON 请求。同样地,Slack 和 Microsoft 团队的传入 Webhooks 都希望收到其中包含对应于 "text" 键的消息字符串的 JSON 请求。

注意:有关 Amazon SNS 消息正文 JSON 文档中的键值对列表,请参阅 HTTP/HTTPS 通知 JSON 格式

您可以使用 AWS Lambda 函数将 Webhook 终端节点的 Amazon SNS 消息正文 JSON 文档转换为待处理的格式。

解决方法

创建 SNS 主题

如果您尚未创建,请用唯一的名称创建 SNS 主题

创建 Lambda 函数

有关创建 Lambda 函数的说明,请参阅 AWS Lambda 入门。有关更多信息,请参阅将 AWS Lambda 用于 Amazon SNS

您的 Lambda 函数代码必须包含转换您正在使用的 Webhook 终端节点类型的 SNS 主题通知消息的逻辑。有关示例,请参阅下面的 Amazon Chime、Slack 和 Microsoft 团队 Webhooks 的 Python 代码段。这些代码示例按原样提供。它们与 Python 3.6 运行时兼容。

Amazon Chime Webhooks 希望收到其中包含对应于"Content" 键的消息字符串的 JSON 请求。有关更多信息,请参阅 Amazon Chime 的 Webhooks

注意:在 Amazon Chime Webhooks 的本示例函数代码中,将 https://hooks.chime.aws/incomingwebhooks/xxxxxxx 替换为 Webhook URL。

#!/usr/bin/python3.6
import urllib3 
import json
http = urllib3.PoolManager() 
def lambda_handler(event, context): 
    url = "https://hooks.chime.aws/incomingwebhooks/xxxxxxx"
    msg = {
        "Content": event['Records'][0]['Sns']['Message']
    }
    encoded_msg = json.dumps(msg).encode('utf-8')
    resp = http.request('POST',url, body=encoded_msg)
    print({
        "message": event['Records'][0]['Sns']['Message'], 
        "status_code": resp.status, 
        "response": resp.data
    })

Slack 传入 Webhooks 希望收到其中包含对应于 "text" 键的消息字符串的 JSON 请求。它们还支持消息定制,例如添加用户名和图标,及覆盖 Webhook 的默认渠道。有关更多信息,请参阅 Slack 网站上的使用传入 Webhooks 发送消息

注意:在 Slack 传入 Webhooks 的示例函数代码中,将 https://hooks.slack.com/services/xxxxxxx 替换为传入 Webhook URL。另外再将 #CHANNEL_NAME 替换为目标渠道的名称。

#!/usr/bin/python3.6
import urllib3
import json
http = urllib3.PoolManager()
def lambda_handler(event, context):
    url = "https://hooks.slack.com/services/xxxxxxx"
    msg = {
        "channel": "#CHANNEL_NAME",
        "username": "WEBHOOK_USERNAME",
        "text": event['Records'][0]['Sns']['Message'],
        "icon_emoji": ""
    }
    
    encoded_msg = json.dumps(msg).encode('utf-8')
    resp = http.request('POST',url, body=encoded_msg)
    print({
        "message": event['Records'][0]['Sns']['Message'], 
        "status_code": resp.status, 
        "response": resp.data
    })

Microsoft 团队的传入 Webhooks 也希望收到其中包含对应于 "text" 键的消息字符串的 JSON 请求。有关更多信息,请参阅 Microsoft Docs 网站上的设置自定义传入 Webhook

注意:在 Microsoft 团队的传入 Webhooks 的示例函数代码中,将 https://outlook.office.com/webhook/xxxxxxx 替换为 Webhook URL。

#!/usr/bin/python3.6
import urllib3 
import json
http = urllib3.PoolManager() 
def lambda_handler(event, context): 
    url = "https://outlook.office.com/webhook/xxxxxxx"    
    msg = {
        "text": event['Records'][0]['Sns']['Message']
    }
    encoded_msg = json.dumps(msg).encode('utf-8')
    resp = http.request('POST',url, body=encoded_msg)
    print({
        "message": event['Records'][0]['Sns']['Message'], 
        "status_code": resp.status, 
        "response": resp.data
    })

测试 Lambda 函数

  1. 在 Lambda 控制台的函数页面上,选择您的函数。
  2. 在右上角选择选择测试事件,然后选择配置测试事件
  3. 配置测试事件对话框中,选择创建新测试事件
  4. 对于事件模板,请选择 Amazon SNS 主题通知
  5. 对于事件名称,请输入测试事件的名称。
  6. 选择创建
  7. 选择测试
  8. 查看执行结果

如果测试调用成功并返回 200 状态代码,则 Amazon SNS 通知消息被 Webhook 接受,然后再发送到相应的渠道中。如果调用失败并返回 4xx 状态代码,则检查 Webhook URL 并验证键值对正确且被您的目标 Webhook 接受。

有关在 Lambda 控制台中测试函数的更多信息,请参阅调用 Lambda 函数

添加 SNS 主题触发器到 Lambda 函数

在 Lambda 控制台中将 SNS 消息作为测试成功发送到 Webhook 之后,将您的函数订阅到 SNS 主题。您可以通过添加 SNS 主题触发器从 Lambda 控制台中对此进行配置。

  1. 在 Lambda 控制台的函数页面上,选择您的函数。
  2. 设计器下,选择添加触发器。有关更多信息,请参阅使用设计器
  3. 触发器配置下,选择选择触发器,然后选择 SNS
  4. 对于 SNS 主题,选择您之前创建的 SNS 主题。
  5. 选中启用触发器复选框。
  6. 选择添加

有关更多信息,请参阅在 AWS Lambda 控制台中配置函数

通过将您的函数订阅到 SNS 主题,将发布到主题的消息转发至该函数,然后再转发至您的 Webhook。

提示:使用 Amazon CloudWatch 警报在警报被触发时在 Amazon Chime、Slack 或 Microsoft 团队中获取 Amazon SNS 通知。