如何使用 Webhook 将 Amazon SNS 消息发布到 Amazon Chime、Slack 或 Microsoft Teams?

上次更新时间:2021 年 2 月 17 日

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

简短描述

您可以使用 Amazon SNS 将通知消息发送至 HTTP(S) 终端节点,例如 Webhook URL。然而,有些 Webhook 希望在确认 HTTP(S) 订阅时收到 Amazon SNS 不支持的 JSON 键值对。

例如,Amazon Chime Webhook 希望收到其中包含对应于 "Content" 键的消息字符串的 JSON 请求。同样地,Slack 和 Microsoft 团队的 Webhook 都希望收到其中包含对应于 "text" 键的消息字符串的 JSON 请求。

要转换 Webhook 终端节点的 Amazon SNS 消息正文 JSON 文档以进行处理,可使用 AWS Lambda 函数

注意:有关 Amazon SNS 消息正文 JSON 文档中的键值对列表,请参阅 HTTP/HTTPS 通知 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 的 Python 代码片段示例

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

注意:在 Amazon Chime Webhook 的本示例函数代码中,将 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 的 Python 代码片段示例

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

注意:在 Slack 传入 Webhook 的示例函数代码中,将 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 团队的 Python 代码片段示例

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

注意:在 Microsoft 团队的传入 Webhook 的示例函数代码中,将 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 主题。要从 Lambda 控制台进行配置,请执行以下操作以添加 SNS 主题触发器:

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

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

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

注意: 有关如何通过其他 AWS 服务获取 Amazon SNS 通知的信息,请参阅将 AWS Chatbot 用于其他 AWS 服务