Skip to content

Commit 249f3eb

Browse files
authored
Merge pull request aws-samples#1610 from RickXie747/rickxieaws-feature-sns-slack-teams-integration-cdk-python
2 parents bcb1c9b + 7fc4edf commit 249f3eb

9 files changed

Lines changed: 303 additions & 0 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Amazon SNS integration with slack/teams channels
2+
3+
This pattern demonstrates how you can setup a fully serverless setup to integrate your SNS topic with a Slack/Teams channel. This provisions AWS resources for you and you just need to integrate your Slack/Teams webhooks to get it running.
4+
5+
[Learn more about this pattern at Serverless Land Patterns](https://serverlessland.com/repos/sns-slack-teams-integration-cdk-python)
6+
7+
[SNS & Slack/Teams integration diagram](https://github.com/ajayv-AWS/Img/blob/870961eb05a4732ea2ee6a36af8ad1fd6a7ef206/SNS-teams-slack.drawio.png?raw=true)
8+
9+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
10+
11+
## Requirements
12+
13+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
14+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
15+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
16+
* [AWS CDK](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) installed and configured
17+
18+
## Deployment Instructions
19+
20+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
21+
```bash
22+
git clone https://github.com/aws-samples/serverless-patterns
23+
```
24+
2. Change directory to the pattern directory:
25+
```bash
26+
cd serverless-patterns/sns-slack-teams-integration-cdk-python
27+
```
28+
3. To manually create a virtualenv on MacOS and Linux:
29+
```bash
30+
python3 -m venv .venv
31+
```
32+
4. After the init process completes and the virtualenv is created, you can use the following
33+
step to activate your virtualenv.
34+
```bash
35+
source .venv/bin/activate
36+
```
37+
5. If you are a Windows platform, you would activate the virtualenv like this:
38+
```bash
39+
.venv\Scripts\activate.bat
40+
```
41+
6. Once the virtualenv is activated, you can install the required dependencies.
42+
```bash
43+
pip install -r requirements.txt
44+
```
45+
7. To deploy the application:
46+
```bash
47+
cdk deploy
48+
```
49+
50+
## How it works
51+
52+
This template will create an SNS topic which you can use to publish notifications to your Slack/Teams channel, and a Lambda function which will process the SNS message and pass it to the Slack/Teams webhook. You can customise the code to apply additional formatting as per your usecase.
53+
54+
## Testing
55+
56+
Publish a message from AWS Console or by CLI.
57+
58+
Example using CLI:
59+
60+
aws sns publish --topic-arn ENTER_YOUR_SNS_TOPIC_ARN --subject testSubject --message testMessage
61+
62+
## Cleanup
63+
64+
* Delete the stack
65+
```bash
66+
cdk destroy
67+
```
68+
----
69+
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
70+
71+
SPDX-License-Identifier: MIT-0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
6+
from sns_slack_teams_integration_cdk_python.sns_slack_teams_integration_cdk_python_stack import SnsSlackTeamsIntegrationCdkPythonStack
7+
8+
9+
app = cdk.App()
10+
SnsSlackTeamsIntegrationCdkPythonStack(app, "SnsSlackTeamsIntegrationCdkPythonStack",
11+
# If you don't specify 'env', this stack will be environment-agnostic.
12+
# Account/Region-dependent features and context lookups will not work,
13+
# but a single synthesized template can be deployed anywhere.
14+
15+
# Uncomment the next line to specialize this stack for the AWS Account
16+
# and Region that are implied by the current CLI configuration.
17+
18+
#env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),
19+
20+
# Uncomment the next line if you know exactly what Account and Region you
21+
# want to deploy the stack to. */
22+
23+
#env=cdk.Environment(account='123456789012', region='us-east-1'),
24+
25+
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
26+
)
27+
28+
app.synth()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"python/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
19+
"@aws-cdk/core:checkSecretUsage": true,
20+
"@aws-cdk/core:target-partitions": [
21+
"aws",
22+
"aws-cn"
23+
],
24+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
27+
"@aws-cdk/aws-iam:minimizePolicies": true,
28+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
33+
"@aws-cdk/core:enablePartitionLiterals": true,
34+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
35+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
36+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
37+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
38+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
39+
"@aws-cdk/aws-route53-patters:useCertificate": true,
40+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
41+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
42+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
43+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
44+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
45+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
46+
"@aws-cdk/aws-redshift:columnId": true,
47+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
48+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
49+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
50+
"@aws-cdk/aws-kms:aliasNameRef": true,
51+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
52+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
53+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
54+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
55+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
56+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true
57+
}
58+
}
59+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"title": "Amazon SNS integration with Slack/Teams channels",
3+
"description": "This sample project demonstrates the publishing of messages from an SNS topic to an AWS Lambda function, which in turn triggers notifications to a Slack/Teams channel.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "CDK",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This sample pattern demonstrates how to use AWS SNS and Lambda function to deliver notifications to your slack or teams channels.",
11+
"This pattern uses AWS CDK to setup the AWS serverless services and provides you with a setup ready to be integrated with your Slack/Teams channel",
12+
"This pattern deploys one SNS topic and one Lambda function"
13+
]
14+
},
15+
"gitHub": {
16+
"template": {
17+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/sns-slack-teams-integration-cdk-python",
18+
"templateURL": "serverless-patterns/sns-slack-teams-integration-cdk-python",
19+
"projectFolder": "sns-slack-teams-integration-cdk-python",
20+
"templateFile": "sns_slack_teams_integration_cdk_python/sns_slack_teams_integration_cdk_python_stack.py"
21+
}
22+
},
23+
"resources": {
24+
"bullets": [
25+
{
26+
"text": "Getting started with the AWS CDK",
27+
"link": "https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html"
28+
},
29+
{
30+
"text": "Setup SNS topic",
31+
"link": "https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html"
32+
},
33+
{
34+
"text": "Create Lambda function",
35+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html"
36+
},{
37+
"text": "Add lambda function as subscriber to a SNS topic",
38+
"link": "https://docs.aws.amazon.com/sns/latest/dg/lambda-console.html"
39+
},
40+
{
41+
"text": "Add your slack/MS teams and channel configuration to the Lambda function",
42+
"link": "https://repost.aws/knowledge-center/sns-lambda-webhooks-chime-slack-teams"
43+
}
44+
]
45+
},
46+
"deploy": {
47+
"text": [
48+
"cdk deploy"
49+
]
50+
},
51+
"testing": {
52+
"text": [
53+
"See the GitHub repo for detailed testing instructions."
54+
]
55+
},
56+
"cleanup": {
57+
"text": [
58+
"cdk destroy"
59+
]
60+
},
61+
"authors": [
62+
{
63+
"name": "Rick Xie",
64+
"image": "https://drive.google.com/file/d/1GEM7I1PK3i0HT3pMMoI7d5zFXw4wAEFL/view?usp=sharing",
65+
"bio": "Cloud Support Engineer @ AWS",
66+
"linkedin": "https://www.linkedin.com/in/rick-xie"
67+
}
68+
]
69+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import urllib3
2+
import json
3+
4+
http = urllib3.PoolManager()
5+
6+
def lambda_handler(event, context):
7+
8+
#when using slack
9+
url = 'https://hooks.slack.com/services/xxxxxxx'
10+
msg = {
11+
'channel': '#CHANNEL_NAME',
12+
'text': event['Records'][0]['Sns']['Message'],
13+
'icon_emoji': '',
14+
}
15+
16+
#when using teams
17+
#url = "https://outlook.office.com/webhook/xxxxxxx"
18+
#msg = {"text": event["Records"][0]["Sns"]["Message"]}
19+
20+
encoded_msg = json.dumps(msg).encode('utf-8')
21+
resp = http.request('POST', url, body=encoded_msg)
22+
print({
23+
"message": event["Records"][0]["Sns"]["Message"],
24+
"status_code": resp.status,
25+
"response": resp.data,
26+
})
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-cdk-lib==2.93.0
2+
constructs>=10.0.0,<11.0.0

sns-slack-teams-integration-cdk-python/sns_slack_teams_integration_cdk_python/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from aws_cdk import (
2+
Duration,
3+
Stack,
4+
CfnOutput,
5+
aws_sns as sns,
6+
aws_sns_subscriptions as subscriptions,
7+
aws_lambda as _lambda
8+
)
9+
from constructs import Construct
10+
11+
class SnsSlackTeamsIntegrationCdkPythonStack(Stack):
12+
13+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
14+
super().__init__(scope, construct_id, **kwargs)
15+
16+
# Lambda function
17+
lambdaFn = _lambda.Function(self, "SlackTeamsIntegrationLambda",
18+
runtime=_lambda.Runtime.PYTHON_3_8,
19+
code=_lambda.Code.from_asset('lambda'),
20+
handler="lambda_function.lambda_handler",
21+
timeout=Duration.seconds(10))
22+
23+
# SNS topic
24+
topic = sns.Topic(self, "SlackTeamsIntegrationTopic",
25+
display_name="SlackTeamsIntegrationTopic")
26+
27+
# Subscribe Lambda to SNS topic
28+
topic.add_subscription(subscriptions.LambdaSubscription(lambdaFn))
29+
30+
# Output information about the created resources
31+
CfnOutput(self, 'snsTopicArn',
32+
value=topic.topic_arn,
33+
description='The ARN of the SNS topic')
34+
35+
CfnOutput(self, 'functionName', value=lambdaFn.function_name, description="The name of the Lambda function")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@echo off
2+
3+
rem The sole purpose of this script is to make the command
4+
rem
5+
rem source .venv/bin/activate
6+
rem
7+
rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8+
rem On Windows, this command just runs this batch file (the argument is ignored).
9+
rem
10+
rem Now we don't need to document a Windows command for activating a virtualenv.
11+
12+
echo Executing .venv\Scripts\activate.bat for you
13+
.venv\Scripts\activate.bat

0 commit comments

Comments
 (0)