Forwarding Amazon SNS Notifications to a Telegram Chat

Figure showing an SNS topic that invokes a Lambda function. The Lambda function sends out a Telegram message.

Amazon Simple Notification Service (SNS) is a web service that allows to publish messages from an application and immediately deliver them to subscribers or other applications.

A publisher sends a message to an SNS topic, and the Amazon SNS service delivers this message (notification) to the subscribers of this SNS topic. The supported notification protocols are HTTP/S, SQS, Lambda, mobile push, email, or SMS.

If you want your notifications to be delivered to a Telegram chat, you can not simply use an HTTP/S endpoint to integrate your SNS topic with the Telegram Bot API. You need to create a simple Lambda function that calls the Bot API to forward notifications to a Telegram chat. The following procedure describes how to do it.

How to Forward SNS Notifications to a Telegram Chat

In this procedure, you create a Telegram bot. Bots are Telegram accounts operated by software – not people. In our case, the bot is operated by a Lambda function that sends notifications to a Telegram chat on behalf of this bot. The communication is one-directional. That is, the bot sends messages to you but does not process any messages received from you.

Flow diagram showing an SNS topic that invokes a Lambda function. The Lambda function sends an HTTP request to the Telegram bot API. As a result, the SNS notification is delivered to the Telegram chat of a mobile client.

To forward SNS notifications to a Telegram chat, perform the following steps:

  1. Create a new Telegram bot.
    1. In your Telegram app, search @BotFather and press the Start button (or send the /start command). Then, send the /newbot command and follow a few simple steps to create a new Telegram bot.
      The BotFather generates an authorization token for your new bot. The token is a string that looks something like 123456789:ABCD1234efgh5678-IJKLM. It is required to send requests to the Telegram Bot API.
    2. In your Telegram app, search by the name the bot that you just created and press the Start button (or send the /start command). Then, write any test message to the chat with your bot. For example, write Hello.
    3. Execute a Bot API call to get the ID of your chat with your bot.
      In the following command, replace <token> with the authorization token that you received from the BotFather.
      curl 'https://api.telegram.org/bot<token>/getUpdates' | python -m json.tool
      
      In the output, find your test message and the corresponding chat ID. For example, in the following output, the chat ID is 987654321.
      {
        "ok": true,
        "result": [
          {
            "message": {
              "chat": {
                ...
                "id": 987654321,
                ...
              },
              ...
              "message_id": 2,
              "text": "Hello"
            },
            ...
          }
        ]
      }
  2. Open the Amazon SNS Console at https://console.aws.amazon.com/sns/home and create a new SNS topic in the AWS region of your choice.
  3. Open the Lambda Management Console at https://console.aws.amazon.com/lambda/home and switch to the same AWS region where you created your SNS topic. Then, create a new Lambda function with the configuration below.
    Runtime: Python 3.7
    Execution role: create a new Lambda IAM role that has the inline policy below.
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"
          ],
          "Resource": "arn:aws:logs:*:*:*",
          "Effect": "Allow"
        }
      ]
    }
    Function code: use the following snippet.
    This function executes the sendMessage method of the Telegram Bot API to forward SNS messages (notifications) to a Telegram chat.
    # CloudBriefly.com
    
    import os
    import json
    from urllib import request, parse, error
    
    def lambda_handler(event, context):
        url = 'https://api.telegram.org/bot%s/sendMessage' % os.environ['TOKEN']
        message = event['Records'][0]['Sns']['Message']
        data = parse.urlencode({'chat_id': os.environ['CHAT_ID'], 'text': message})
    
        try:
            # Send the SNS message (notification) to Telegram
            request.urlopen(url, data.encode('utf-8'))
        except error.HTTPError as e:
            print('Failed to send the SNS message below:\n%s' % message)
            response = json.load(e)
            if 'description' in response:
                print(response['description'])
            raise e
    Memory (MB): 128 MB
    Timeout: 5 sec
    Environment variables: set the CHAT_ID and TOKEN environment variables of your Lambda function (use your values from Step 1).
    For example: Screen capture showing a sample configuration of the environment variables of the Lambda function.
  4. Publish a new version of your Lambda function. Then, copy from the top of the page the function ARN (including the version suffix).
  5. Open your SNS topic in the Amazon SNS Console. Then, create a new subscription for the AWS Lambda protocol with the ARN from the previous step.
  6. Open your SNS topic in the Amazon SNS Console. Then, publish a test message.
    The message is delivered to your Telegram chat with your bot.
  • Different published versions of your Lambda function can have different values of the TOKEN and CHAT_ID environment variables. Thus, to forward SNS notifications from one SNS topic to different Telegram chats, you can create two subscriptions with different versions of the same Lambda function.