Creating a server-less Telegram bot with AWS Lambda and AWS API Gateway

At Zingle we’ve been doing message-based automations since 2013. After Facebook’s recent F8 keynote, there’s a ton of buzz around bots in the tech world. Major messaging platforms like Telegram, Facebook Messenger, and Slack all have robust bot support. Most bots are simple enough that they don’t require a complex server and datastore setup. This article will demonstrate how a bot can be set up on AWS Lambda and API Gateway with very little configuration.

If you don’t care about the walkthrough, the code is available on GitHub here.

Prerequisites

You’ll need the following to work through this tutorial:

Step 1: Create the Bot

Telegram (bot API docs here) provides a nifty way of creating the actual bot account. They have a bot of their own called BotFather. By simply messaging BotFather you can create the bot and get the access token.

Creating the Bot

I’ve created a bot called InterestingImageBot. When you setup your own bot, be sure to copy the auth token, we’ll need it later.

Step 2: Write and package some code

I won’t get into all of the details about the code here. I recommend you head over to GitHub to review it. You’ll find the code is commented in extreme detail to explain what’s going on. You can deploy as-is for your own purposes by just updating the Flickr auth token and Telegram bot token in the index.js file.

The gist of the code flow is that the Lambda function’s ‘handler’ method will be called on any incoming message to the bot. This will trigger a query to Flickr’s API to query the five most ‘interesting’ images of the day. An HTTP request is issued to stream each of those images to a buffer, which is then passed to Telegram’s ‘sendPhoto’ method for delivery to the client.

With AWS Lambda you can either edit the code inline, one file at a time, in their interface or you can zip it up and upload it. We’ll need to go that route since we’re using npm to include some packages. So once you’ve written your code and run ‘npm install’, zip it up.

Step 2: Create the Lambda function

AWS Lambda lets you create what they call functions, which are essentially Javascript modules (they also support Java and Python). For this bot we’ll create a Node 4.3 Lambda function and set the execution timeout to ten seconds. The default is three, but since we’re querying an API and streaming data we’ll need a little more that that.

Creating the Lambda Function

The setting for IAM role can be a bit confusing. For the time being, simply select ‘* Basic execution role’. This will open a new tab for creating a new IAM role — leave the settings at their defaults and click the ‘Allow’ button at the bottom. Go back to the Lambda Function creation window and select the newly-created ‘lambda_basic_execution_role.’

Once that’s done, upload your zipped code file.

Step 4: Create an AWS API Gateway endpoint

A standalone Lambda function doesn’t do us any good as it’s not publicly accessible. AWS makes it simple to assign an API gateway endpoint to a Lambda function. On the Lambda function page go to the API Endpoints tab and click ‘Add API Endpoint.’

Adding an API endpoint to a Lambda function

Make sure to specify the method as POST (Telegram uses POST for webhook notifications) and the security as Open, which makes the API endpoint publicly accessible with no auth needed.

After hitting submit, the API Endpoints tab will update and you’ll be given the URL for the Lambda function.

Step 5: Point the Telegram bot at AWS

We now have a Telegram bot and an API setup to handle it’s requests, but they haven’t been introduced to each other yet. The final step requires telling our bot to call the AWS API whenever an incoming message is received. To do so we issue a POST request to the Telegram bot API with the setWebhook command:

curl -XPOST https://api.telegram.org/botYOURTOKEN/setWebhook\?url\=YOURAPIURL

Make sure to include the word ‘bot’ before your bot token and to properly url-encode the API url.

Step 6: Try it out!

All the pieces are in place. From Telegram, we should be able to send a message to our bot and get a response back.

The InterestingImageBot in action

Beautiful!

There’s plenty more that can be done with this bot, such as supporting complex search, pagination, scheduled delivery, etc., but this serves as a good starting point for building out a more complex, intelligent bot.