AWS Lambda: Send Notifications to your Discord Server using SNS Topics
Tags: python, aws, discord, sns
Published: 2022-08-26 23:03:00

## **Introduction**

First, I'd like to thank @josuebustos for his article, which gave me the idea to come up with an alternative version.
You can integrate Lambda and SNS to send notifications regarding your resources, this brings a lot of possibilities, and we'll see a basic one. Such notifications will contain information from an SNS Topic in AWS. We'll learn how to send messages to a discord channel using webhooks.

Want to know more about Lambda?
[Click here](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)

Want to know more about Discord Webhook?
[Click here](https://discord.com/developers/docs/resources/webhook)

## **Getting Started**

This tutorial is focused on being as simple as possible, so you can easily set up your lambda function within minutes and change it accordingly if you are having problems or only want the code [here is the link](https://github.com/SaidS11/DiscordNotifier-ForAWSPipeline) of my repo with everything you'll need.

Prerequisites:
- AWS Account
- Discord Server

## **Create a Discord Server and a Webhook**

> The first step is to create a server. If you already have one skip until the webhook section.

In your Discord Dashboard.
1. Click the green button in the lower left corner to create a server.
![Add Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gb4vj9x3ckk88gka7y5b.png)

2. Select one of the following options. I recommend you choose the 'Create my Own' option.
![Add Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hua1pjns62w3mq2wcasi.png) 

3. Select Select one of the following options. I recommend you choose the 'For me and my friends' option.
![Add Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lr3pqc5g6ixfupixd93d.png) 

4. Customize your server with a name and an image if you want it.
![Add Server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fw1n8f78mikt9i7tcm32.png)

5. I'll recommend you create a separate channel for the webhook to keep things organized. Click on the create channel button above the channel names.
![Channel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ajy72w8c3gljqfl009f.png)

6. Configure the channel as you like, but keep the **Text** option. 
![Channel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jk4bvl5b6d6ob8rqsl2r.png)

**Time to set up the webhook**

7. Click on the 'Gear' option on the name of the channel you want to edit.
![Webhook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5yqltw0o9bqujfw7l5i.png)

8. Select the **Integrations** option to access the webhooks menu.
Then press the **Create webhook button**
![Webhook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqmjqdeu39d9hg46ynu8.png)

9. You can configure the name and the icon for your webhook. Select the channel you want your webhook to use.
![Webhook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpufr19lrcoij846gobd.png)

10. Copy the webhook URL and save it somewhere because we'll use it in a few sections.
![Webhook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuhgighfv37jjtuhgo7n.png)
 
## **Create an SNS Topic**

> If you already have an SNS Topic that you want to use to send information to your discord channel, skip this section. 

We will create a simple one, and then you can connect this topic to any other resource.

Let's get into the SNS service, selecting **Simple Notification Service**.

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qjf0ym4hz5i7jfo0uw25.PNG)


Select the topic option on the sidebar, and then the **Create topic** option.


![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75bgk8ur3dmjkgr1imw2.PNG)

Use the following options for a simple SNS topic and press on the **create topic** button

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ot32wzl774ry1pns1kab.PNG)

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gahf49hck9b1ps0c47s3.PNG)

Now, it's time to subscribe to the SNS topic.
After the creation, this screen will pop up. If not, select your recently created topic in the topics section.
Press on the **Create subscription** option.

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfv2b236w55ojhrn5e4x.PNG)



Select the following options to create a simple Email subscription, **change the email field** with the email you want to receive the notifications and press the **Create subscription button**.

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yzufuv1uiflikxvakib.PNG)

![SNS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dci93361561tendocw3.PNG) 

You'll receive an email asking you to confirm the subscription, do it and then continue.

 
Now you have an SNS topic you can link to any other AWS resource, [here](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-notify-sns.html) is an example to use SNS topics and Codecommit triggers.

## **Prepare a Zip for AWS Lambda Layers**

To utilize python packages in our lambda function, we need to upload a zip file with the content of our packages to Lambda Layers, follow the steps to create your zip or use [mine](https://github.com/SaidS11/DiscordNotifier-ForAWSPipeline/blob/main/python.zip) and skip the creation.
You can follow most of the steps from a terminal or using the GUI. 
Create a directory named **python**. The name is vital if you want to avoid possible issues.
You can use this instruction or create the folder manually.
```bash
$ mkdir python
```

![Folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qknsg02ipjf7t9bzhfiy.png)
For the following steps, you'll need a terminal, don't worry it's easy, and remember, if you are not so sure about this, download my zip [here](https://github.com/SaidS11/DiscordNotifier-ForAWSPipeline/blob/main/python.zip). Open a terminal inside your recently created directory or cd into it.

```bash
$ cd /d/Documents/python
```

Use this instruction to install the necessary packages inside the folder. In this case, we'll be installing **discord-webhook**.

```bash
$ pip3 install -t . discord-webhook
```

4. The next step is eliminating unnecessary files using this command.

```bash
$ rm -r *dist-info __pycache__
```
Don't worry if you get a warning after this command, proceed 
without a problem.

5. Now, it's time to zip the folder. You can use this command or do it manually. 

```bash
$ zip -r layer.zip python
```
 
![Zip](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkc2x4578e4xa8fq4hib.PNG)

## **Upload Zip to Lambda Layer**

First, let's get into the lambda service

![Lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gkdemjs5naoogpi80lud.PNG)

Select the **Layer** option on the sidebar and select **Create Layer**

![Lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qw4l39z53d5zvdyjzdme.PNG)
Upload the zip and fill in the options following the image below.
 
![Lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbxucg95quyt9lsoe3on.jpg)


## **Create the Lambda function**
Now it's time to create the function. We will select the **Function** option on the same service, and then the **Create function** button.

![Function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdosrrr1obh56g7y931e.PNG)

This is an essential step. To make things easier, instead of selecting the author from scratch option, we will choose the **Use a blueprint** option. Then we will search for the sns blueprint for python and select it. Then press on the **Configure** button

![Function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2osi8n9li549ydh8vk3e.PNG)

Select the following options. Choose a name for your function.

![Function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b16h98f7pagid18271q.jpg)
Select your topic from the SNS topic list, and then press **Create function**


![Function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tn0gnv0ip1cacb7av6r.jpg)

![Function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3pumf7xcvcajauj68f90.jpg)
 
## **Import the Layer**

Inside your function, press the layers button.

![Modules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og1y38d3w76veq1ohfig.PNG)

Then press **Add a Layer**

![Modules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/855nu7xt0ejqjnc7h60z.PNG)

In this menu, we'll fill in the options like the image below.
Under the custom layer option, select the Layer we just created and press **Add**
![Layers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zc7xbzf1qhwkyqbtt0kc.PNG)

 


## **Code for the Function**
Now you can replace the code from the function with the following:

```python
from discord_webhook import DiscordWebhook, DiscordEmbed
import json

print('Loading function')


def lambda_handler(event, context):
    message = event['Records'][0]['Sns']['Message']
    print("From SNS: " + message)

    webhook = DiscordWebhook(url="replace with your webhook url")
    embed = DiscordEmbed(
        title="AWS",
        description=message,
        color="00ff00")

    #Select an image if you want
    #embed.set_image(url="")

    webhook.add_embed(embed)
    webhook.execute()

    return message
```

Depending on your SNS topic, you may want to filter the messages with a simple sentence. If that's the case, use the following:

```python
from discord_webhook import DiscordWebhook, DiscordEmbed
import json

print('Loading function')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    message = event['Records'][0]['Sns']['Message']
    print("From SNS: " + message)
    message_str=str(message)
    ###If sentence to filter the messages you want to receive.
    if "New" in message:
        webhook = DiscordWebhook(url="replace with your webhook url")
        embed = DiscordEmbed(
            title="AWS",
            description=message,
            color="00ff00")
        
        #embed.set_image(url="")
        webhook.add_embed(embed)
        webhook.execute()
    else:
        pass
    return message
```

## **Configure Test Event**
Before the testing, we need to configure a Test Event.
Press on the test option and then on the Configure test event option.

![Code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a9cnvxi4m7gkhfn1ifuh.png)

Choose a name for your test event. A template for the test event would be already selected. If not, search for the **Sns notification** template.

![Code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n93w30e773jhgvru992.PNG)

Press **Save** at the end.
![Code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f771nv7grvpf4pa3beh.PNG)
## **Test the code**
Before testing, press the deploy button.

![Test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7tuaqcbr166usb9o89r.PNG)

Now you're all set. Press on the **Test** button and check your discord channel.


![Test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjtgpquoi0pewb5zc0d5.PNG)

And here is what it looks like when triggered by an SNS message.

![TTest](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6cvavvcvaz5k1vhzesm.PNG)

If you are having problems related to the module while testing, please refer to the official documentation [here](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-import-module-error-python/) Or try using the python.zip that is in my [repo](https://github.com/SaidS11/DiscordNotifier-ForAWSPipeline/blob/main/python.zip).

## **Conclusion**
Now you know how to set up a discord notifier that listens to an SNS Topic using Lambdas.
I hope you found this helpful.

Keep Learning.