Telegram Bot with Apps Script
Google Apps Script is a cloud scripting service based in JavaScript and makes it easy to do cool things with most of Google's products. Lately, I've been a big fan of its flexibility and versatility, for example with just a few lines of code you can interact with the Telegram Bot API to control your bot, you won't have to worry about having a server, SSL certificates or configure ports.
What We Are Going to Do
Our goal is to create a simple Telegram bot that replies to a command with a random quote from Quotes on Design.
You can test it just by starting a conversation with DesignQuotesBot and sending the command /quote
.
Now let's get started with the step by step instructions:
🤖 Meet BotFather
The first step is to talk to BotFather to create and setup our bot, he will also give us our authorization token.
Sign in to Telegram from your favorite device and search for the account BotFather and start a conversation.
Click the Start button.
He will reply with the list of commands supported by BotFather.
Create a new bot by sending the command /newbot
. The BotFather will ask you for a name, we'll call our bot Quotes on Design.
The name of your bot will be displayed in contact details and elsewhere.
Now, BotFather will ask you for a username, let it be DesignQuotesBot.
The username is a short name, to be used in mentions and telegram.me links. Usernames are 5-32 characters long and are case insensitive, but may only include Latin characters, numbers, and underscores. Your bot's username must end in ‘bot’, e.g. ‘tetris_bot’ or ‘TetrisBot’.
BotFather will congratulate us, and give us an unique authorization token, it
is a string along the lines of 2970976:AAFbL7yMJqVaGP4
, this will be required to
send requests to the Bot API.
Ok, It's time to code!
Let's jump to Google Apps Script, grab your browser and visit script.google.com/intro (You'll need to be signed in to your Google account.) You'll see the Script Editor with a Blank project, delete any code in the Code.gs file.
Telegram Bot API currently supports two (mutually exclusive) ways of receiving updates. We can either use long polling or Webhooks, for this example we're going to use Webhooks, this means every time there is an update in for the bot (like when someone sends a command to our bot or add him to a group), they will send an HTTP POST request to a specified URL containing a JSON-serialized Update.
So, we need to create an application to be able to respond to POST requests sent from the Bot API, the good news are that Google Apps Script would let us deploy our script as a Web App that would let us interpret those request.
When an user or a program (in this case de Bot API) sends to our script an HTTP Post request, Apps Script will run the special callback function doPost(e) so all we need to do is define that function in our script. The e
argument represents an event parameter that contains the information of the request. As we mentioned above, the Bot API will send the POST request containing a JSON-serialized, this means we're gonna recieve an object converted into String, so we need to parse the text content of the POST body e.postBody.contents
with the method JSON.parse().
When our script receives an update, in this case the command /quote
the JSON-object should look similar to this example:
An incoming update can be of many types, for this example we're going to focus on bot commands, so first we need to make sure the update is type message, in JavaScript we can use the method hasOwnProperty() to determine whether an object has the specified property.
Let's define two variables, the first one will be chatId
here we're going to store the update's unique identifier for this chat, this will become handy when we want to reply with the quote to the correct conversation. The second will be the whole message property, we're going to name it msg
.
Once we are sure the update is a message, we need to confirm the user sent a command, we can determine this by the field type
in the message entity. When a user sends a command to our bot this field will have the String bot_command
.
The field entities contains an Array, remember that JavaScript Arrays are zero-indexed, so the first element is at the index 0, so to access the element type
we need to use msg.entities[0].type
.
Now we just need to confirm that command we received is /quote
, by evaluating if msg.text
is equal to /quote
.
At this point our doPost() function should look like this:
We're going to retrieve a random quote from quotesondesign.com so we can send it to the user. Fortunatelly the website has a JSON REST API, to get a random quote we can use the URL: https://quotesondesign.com/wp-json/wp/v2/posts/?orderby=rand
.
Google Apps Script can interact with APIs from all over the web, we can use the built-in URL Fetch Service with the method fetch() to make a request to the URL mentioned above.
The same as the Bot API, we need to parse the response to work with a JSON Object.
The returned value would look like an array of this:
The returned value is an Array, so we can use the JavaScript method shift() it will remove the first element from an Array and returns that element.
The Bot API supports basic formatting for messages, let's take advantage of this and format the quote, we're goinf to add quotations marks, an em dash and the author in bold.
"No matter how cool your interface is, it would be better if there were less of it." — Alan Cooper
Notice the returned value contains HTML p tags, since Bot API does not support those tags, we need to remove them, we can achieve this with the JavaScript replace() method and the Regular expression /<(?:.|\n)*?>/gm
(explanation). Let's also get rid of the last line break \n
with the regular expression /\n/gm
.
The next step is to send the Bot API our request, for this we're also going to use the URL Fetch Service and the Bot API method sendMessage.
We need to define the POST body for the request containing the requiered parameters:
- The
method
we're going to use, as we mentioned abovesendMessage
. - The
chat_id
, this is the unique identifier of the conversation to reply, we stored it in thechatId
variable. - The
text
we want to send, that is in ourquote
variable. - The
parse_mode
with the valueHTML
because we're sending our text formatted with HTML.
Because payload is a JavaScript object, it will be interpreted as an HTML form. (We do not need to specify contentType; it will automatically default to either 'application/x-www-form-urlencoded' or 'multipart/form-data')
We also need to specify the HTTP method for the request, in this case Post.
To make the request we're going to use the method fetch(url, params). All queries to Telegram Bot API must be served over HTTPS to the endpoint: https://api.telegram.org/bot<token>
. Here is where we're going to use the token we received from the BotFather.
The Full Code
Dude, Just Deploy It Already
To publish our script as a web app, we need to follow these steps:
- Save our code with File > Save
- In the Script Editor, select Publish > Deploy as web app.
- Under Project version, select New, optionally set a description.
- Under Execute the app as, select Me.
- Under Who has access to the app, select Anyone, even anonymous.
- Click Deploy.
Once we click Deploy, we'll see one of the authorization dialogs, we need to authorize our script to Connect to an external services because we're using the URL Fetch Service, click Review Permissions and then Allow.
We'll see a new dialog indicating that your project has been successfully
deployed as a web app. The dialog provides two URLs for your app, the first
labeled Current web app URL and ends in /exec
we're going to need this to
set our Webhook.
The final step is to share the Bot API the URL they need to send the update requests, the easiest way is to open your browser and visit the following url:
Replacing with {API_TOKEN}
and {CURRENT_WEB_APP_URL}
with our respective token and URL.
If everything turns out as planned, after visiting the url we'll see the response:
Let's Test It!
We just need to open Telegram on any device, search for our bot and send the command /quote
.
We’re done!
I hope this post gave you a better understanding of what we can achieve with Google Apps Script and a little more on how to create a Telegram Bot.