How do I use webhooks to publish Amazon SNS messages to Amazon Chime, Slack, or Microsoft Teams?

Last updated: 2020-04-29

I want to use webhooks to connect my AWS environment to my Amazon Chime chat room, or to my Slack or Microsoft Teams channel. How do I send notifications from Amazon Simple Notification Service (Amazon SNS) to a webhook?

Short Description

You can use Amazon SNS to send notification messages to HTTP(S) endpoints, such as webhook URLs. However, some webhooks expect JSON key-value pairs that Amazon SNS doesn't support while confirming the HTTP(S) subscription. For example, Amazon Chime webhooks expect a JSON request with a message string corresponding to a "Content" key. Similarly, Slack and Microsoft Teams incoming webhooks both expect a JSON request with a message string corresponding to a "text" key.

Note: For a list of the key-value pairs in the Amazon SNS message body JSON document, see HTTP/HTTPS notification JSON format.

You can use an AWS Lambda function to transform the Amazon SNS message body JSON document for the webhook endpoint to process.

Resolution

Create an SNS topic

If you haven't done so already, create an SNS topic with a unique name.

Create a Lambda function

For instructions to create a Lambda function, see Getting Started with AWS Lambda. For more information, see Using AWS Lambda with Amazon SNS.

Your Lambda function code must include logic to transform your SNS topic's notification messages for the type of webhook endpoint that you're using. For examples, see the following Python code snippets for Amazon Chime, Slack, and Microsoft Teams webhooks. These code examples are provided as-is. They're compatible with the Python 3.6 runtime.

Amazon Chime webhooks expect a JSON request with a message string corresponding to a "Content" key. For more information, see Webhooks for Amazon Chime.

Note: In this example function code for Amazon Chime webhooks, replace https://hooks.chime.aws/incomingwebhooks/xxxxxxx with the 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 Incoming Webhooks expect a JSON request with a message string corresponding to a "text" key. They also support message customization, such as adding a user name and icon, and overriding the webhook's default channel. For more information, see Sending messages using Incoming Webhooks on the Slack website.

Note: In this example function code for Slack Incoming Webhooks, replace https://hooks.slack.com/services/xxxxxxx with the Incoming Webhook URL. Also replace #CHANNEL_NAME with the destination channel's 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 Teams incoming webhooks also expect a JSON request with a message string corresponding to a "text" key. For more information, see Setting up a custom incoming webhook on the Microsoft Docs website.

Note: In this example function code for Microsoft Teams incoming webhooks, replace https://outlook.office.com/webhook/xxxxxxx with the 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
    })

Test the Lambda function

  1. On the Functions page of the Lambda console, choose your function.
  2. At the top right, choose Select a test event, and then choose Configure test events.
  3. In the Configure test event dialog box, choose Create new test event.
  4. For Event template, choose Amazon SNS Topic Notification.
  5. For Event name, enter a name for the test event.
  6. Choose Create.
  7. Choose Test.
  8. Review the Execution result.

If the test invocation succeeds with a 200 status code, the Amazon SNS notification message is accepted by your webhook, which delivers it to the corresponding channel. If the invocation fails with a 4xx status code, check the webhook URL and verify that the key-value pair is correct and accepted by your destination webhook.

For more information about testing functions in the Lambda console, see Invoke the Lambda Function.

Add an SNS topic trigger to your Lambda function

After successfully sending an SNS message to your webhook as a test in the Lambda console, subscribe your function to your SNS topic. You can configure this from the Lambda console by adding an SNS topic trigger.

  1. On the Functions page of the Lambda console, choose your function.
  2. Under Designer, choose Add trigger. For more information, see Use the Designer.
  3. Under Trigger configuration, choose Select a trigger, and then choose SNS.
  4. For SNS topic, choose the SNS topic that you created earlier.
  5. Select the Enable trigger check box.
  6. Choose Add.

For more information, see Configuring Functions in the AWS Lambda Console.

With your function subscribed to your SNS topic, messages published to the topic are forwarded to the function, and then to your webhook.

Tip: Use Amazon CloudWatch alarms to get Amazon SNS notifications in Amazon Chime, Slack, or Microsoft Teams when an alarm is triggered.