Microsoft teams has a pretty nifty way of opening access to posting messages. This can be configured like this
https://towardsdatascience.com/automate-teams-with-your-first-python-alerting-bot-bcc8f7c6ee5a
After generating a webhook url, let’s store it in SSM since it is credentials for writing to a channel. For this first go ahead I’m going to store it as json with multiple key pairs, it might be better to store them separately, but this will work for now.
The general look is
{
"team_test1": "https://sample.webhook.office.com/webhookb2/blahblah",
"team_test2": "https://sample.webhook.office.com/webhookb2/blahblah"
}
Let’s call the paramater
/dev/teamsintegration/channels
Next, creating the lambda
So it grabs the possible channels from SSM and loads into key pairs for use later (the channel_name paramater)
import sys
import logging
import os
import json
import urllib3
import boto3
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
runtime_region = os.environ['AWS_REGION']
http = urllib3.PoolManager()
session = boto3.Session(region_name=runtime_region)
ssm = session.client('ssm')
channels = ssm.get_parameter(Name='/dev/teamsintegration/channels', WithDecryption=True)['Parameter']['Value']
channels = json.loads(channels)
def send_teams(webhook_url: str, content: str, title: str, color: str="000000") -> int:
msg = {
"@context": "https://schema.org/extensions",
"@type": "MessageCard",
"themeColor": color,
"title": title,
"text": content
}
encoded_msg = json.dumps(msg).encode('utf-8')
http.request('POST', webhook_url, body=encoded_msg)
def lambda_handler(event, context):
content = event["content"]
title = event["title"]
color = event["color"]
channel_name = event["channel_name"]
webhook_url = channels[channel_name]
try:
print(event)
send_teams(webhook_url, content, title,color)
return {
'statusCode': 200,
'body': json.dumps(title)
}
except Exception as error:
raise
In order for the lambda to access the SSM parameter create a quick inline policy
{
"Statement": [
{
"Action": "ssm:DescribeParameters",
"Effect": "Allow",
"Resource": "*",
"Sid": "VisualEditor0"
},
{
"Action": "ssm:GetParameter",
"Effect": "Allow",
"Resource": "arn:aws:ssm:us-east-1:accountid:parameter/dev/teamsintegration/channels",
"Sid": "VisualEditor1"
}
],
"Version": "2012-10-17"
}
Ok, lets test this function out. Configure a test event like this
{
"content": "some content",
"title": "a title that is really cool",
"color": "ff0400",
"channel_name1": "team_test1"
}
Assuming that all worked you should get

To use this from Tulip my favorite method is https://michaelellerbeck.com/2021/07/06/my-new-favorite-way-to-trigger-lambdas-from-tulip/
Grant your rds-lambda-role permission to execute the lambda.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "lambda:InvokeFunction",
"Effect": "Allow",
"Resource": "arn:aws:lambda:us-east-1:943667677541:function:your-function-name-here",
"Sid": "VisualEditor2"
}
]
}
Wrap it in a postgres function
CREATE OR REPLACE FUNCTION public.send_teams_msg(content text, title text, color text, channel_name text)
RETURNS integer
LANGUAGE plpgsql
AS $function$
declare
rows_affected int;
create_json TEXT;
response TEXT;
err_context text;
begin
RAISE INFO 'Started';
-- Create Json
select
into
create_json row_to_json(t)
from
(
select
content,
title,
color,
channel_name
) t;
SELECT into response payload FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('your-function-name-here', 'us-east-1'),
create_json::json,'RequestResponse'
);
RAISE INFO 'response:%',response;
-- parse the response
select into response response::json->'response';
-- remove qutoes
select into response replace(response,'"','');
if response = 'sent' then
return 1;
else
return 0;
END IF;
end;
$function$
;
Call it like this
select public.send_teams_msg('some content','the title', 'ff0400','team_test1')
Then create a connector function

Then of course you can use it in an app like this

Of course, no solution is really complete until automated so let’s Terraform this up.
So this is a somewhat incomplete .tf
https://github.com/mellerbeck/tulip-send-teams-msg/blob/main/tulip_send_teams_msg.tf