In this article, I will demonstrate how to use a webhook and AWS Lambda to send notifications from Amazon Web Services (AWS) to Microsoft Teams.
Latest posts by Graham Beer (see all)

Receiving notifications on user and system events is common in IT. The rule of thumb is that any notification requiring an action should ideally perform a task and not just send an email.

Who doesn’t know the feeling the feeling of seeing hundreds if not thousands of unread emails in a mailbox dedicated to a particular notification, only to find an important email months later that was not actioned? However, on some occasions you just want to be informed that something has happened. Rather than an email with a block of text, the preference would be for a dedicated channel with clear and easy-to-read notifications. Microsoft Teams allows for this with something called a webhook.

In this article, you will learn:

  • What a webhook is.
  • How to create your own Teams channel and connector.
  • How to configure AWS Lambda to integrate with Teams.
  • How to write an Office 365 Connector Card to format your notification.
  • How to add your Connector Card to a AWS Lambda written in Python.

A working example used in this guide will be a well-presented S3 upload notification sent via AWS Lambda to our dedicated Teams Channel.

What is a webhook? ^

A webhook is a type of connector. In this article, we will use an Incoming Webhook as an example. An incoming webhook is a quick and easy way to connect to a channel, which, in our case, will be in Microsoft Teams. Connectors allow users to subscribe to and receive notifications from a web service, such as AWS. Using HTTPS to expose the endpoint, the channel will accept a correctly formatted JSON notification. The notifications are typically sent in the form of cards.

A webhook is different from an API, as it sends data only when it is available, whereas with an API, a request is sent and is followed by a response.

Microsoft Teams ^

Microsoft Teams is a good choice to share content such as notifications, as it provides a straightforward way to configure the content. Also, if Teams is your corporate tool of choice, having notifications in the same place as documents, chats, and online meetings keeps everything simple.

Next, you will learn how to create your channel and incoming webhook in Teams.

Teams channel and connector ^

This demo will show how to create a new channel in Teams called S3 Upload.

Under your Team name, click on the ellipses: (More options). Choose Add Channel and name the channel S3 Upload:

Create a new channel in Microsoft Teams

Create a new channel in Microsoft Teams

After adding the new channel, the next step is to create an incoming webhook. Microsoft Teams makes this step very simple to set up. Hover over the newly created channel and click on the . From this menu, click on Connectors. Teams provides a vast list of available connectors, and I recommend taking a look.

Incoming Webhooks is the first connector on the list; choose it, and click the configure button to the right.

Creating a new webhook connector

Creating a new webhook connector

All that is required on this page is your connector’s name. You can also upload your own custome image for your notifications, replacing the default image shown in the above screenshot. At the bottom of the screen, click Create. The next window will then provide you with a URL:

Webhook URL in connector setup

Webhook URL in connector setup

Make sure to make a copy of this URL for later use.

That is all that Teams requires to generate an Incoming Webhook URL.

Integrating AWS Lambda into Teams with webhooks ^

AWS provides a serverless solution called Lambda. AWS Lambda allows you to run code without provisioning or managing servers; that is all taken care of. AWS Lambda is an excellent way to keep costs down, as you pay only for the compute time you consume.

You set your code to trigger automatically in the event of a file’s upload to a specific S3 bucket. The code will format the event message, which will be sent with the webhook URL to the Teams channel.

To get started, you will need to create an S3 bucket.

S3 bucket creation setup

S3 bucket creation setup

 In this demo, the bucket is named 4sysops-bucket with a folder named text-files.

Once you create the bucket, you can configure the event trigger and code from AWS Lambda.

Navigate to the Lambda service from the AWS console. Create a new Lambda, adding a function name (this demo uses S3-file-notification) and selecting the runtime of Python 3.8. Under Choose or create an execution role, leave the default option of Create a new role with basic Lambda permissions.

Creation of an AWS Lambda function

Creation of an AWS Lambda function

Create a new Environment variable with the key name of HookUrl and set the value to your webhook URL.

Next, you will define the trigger. From the top of the screen, select Add Trigger. A drop-down box will appear with a list of services to use as triggers. For this demo, choose S3. Assuming you have followed the naming conventions of this demo, copy the details from the screen below. If you changed any values, then replace them where appreciate.

Now you have a trigger setup and an environment variable. Next, paste in the Python code given below. This code will run once it is triggered by the file upload to S3:

import json
import os
import logging
import datetime as dt
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

# Microsoft Teams url webhook
HOOK_URL = os.environ['HookUrl']

# set logging
logger = logging.getLogger()

def lambda_handler(event, context):

    message = dict(event['Records'][0])

    source = message['requestParameters']['sourceIPAddress']
    bucket_name = message['s3']['bucket']['name']
    filename = message['s3']['object']['key']
    filesize = message['s3']['object']['size']

    d = dt.datetime.fromisoformat(message['eventTime'][:-1])
    dt_formatted = d.strftime('%Y-%m-%d %H:%M:%S').split(' ')

    # message information to display in Microsoft Teams
    teams_message = {
        "@context": "",
        "@type": "MessageCard",
        "themeColor": "64a837",
        "title": "S3 Notification",
        "text": f"File upload UTC time of **{dt_formatted[1]}** on **{dt_formatted[0]}**",
        "sections": [
                "facts": [
                        "name": "Destination bucket",
                        "value": f"{bucket_name}"
                        "name": "Source IP Address: ",
                        "value": f"{source}"
                        "name": "Folder: ",
                        "value": f"{filename.split('/')[0]}"
                        "name": "Object name: ",
                        "value": f"{filename.split('/')[1]}"
                        "name": "Object size: ",
                        "value": f"{filesize}"

    # request connection to Microsoft Teams
    request = Request(

    # post message to Microsoft Teams
        response = urlopen(request)"Message posted")
    except HTTPError as err:
        logger.error(f"Request failed: {err.code} {err.reason}")
    except URLError as err:
        logger.error(f"Server connection failed: {err.reason}")

Make sure to save your function using the orange Save button in the top right-hand corner.

This code simply puts an event triggered by the S3 file upload into JSON format. The code filters out the information needed and posts it to Teams.

I won’t go through the code in great detail but will highlight a couple of areas.

The code snippet below comes at the end and is called a Connector Card. The Connector Card is what formats the message in Teams.

"@context": "",
        "@type": "MessageCard",
        "themeColor": "64a837",

Something called a JSON payload is posted via the Lambda to the webhook URL. The payload in this case takes the form of a Microsoft 365 Connector Card.

It is worth reading the information given at the two Microsoft pages linked below to get an understanding of Connector Cards and the various ways you can configure them to get the desired output.

Sending messages to connectors and webhooks

Office 365 Connector Card

Python includes the Connector Card as a Python Dictionary.

Receiving a file upload notification ^

Now that you have configured all parts of the Lambda, it’s time to see the results! Copy a file to the Text-files folder within your S3 bucket.

Notification in Teams channel

Notification in Teams channel

The way the data is organized is a construct named facts, which is formed under sections of the Connector Card. As well as formatting the message the Connector Card allows for push buttons. The buttons can be configured to perform further actions if required.

Subscribe to 4sysops newsletter!

Conclusion ^

I hope reading this article you’ve seen what can be achieved with Webhooks and Connector Cards in Microsoft teams. A Webhook is a simple but very effective way to send notifications to Teams. Using the Connector Card you have many ways to present the information being sent. The added advantage of using a serverless function such as AWS Lambda, is that you can integrate Webhooks with your event driven functions effectively.

1 Comment
  1. Andreas 2 years ago

    Thanks for sharing, Graham. I came up with a similar solution for CloudWatch alarms. Check out:

    How to send CloudWatch alarms to Microsoft Teams?

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account