Building a Telegram bot: the bot comes to life
Tags: go, tutorial, programming, bots
Published: 2021-01-29 19:44:00

I recently got curious about how to develop a Telegram bot. That's why I have decided to give it a try and document the process in this series of posts, so anyone can benefit from it as well.

####What are we building?👷‍♀️
The idea is really simple: we are building a dictionary bot. It will allow us to search for a word and give us back info about it like meanings, synonyms, etc. We want it to work in any conversation or group we have, so we can share it with others.
We will develop it in Golang using the [WordsAPI](https://www.wordsapi.com/) and deploying it to Heroku.

####Creating the bot in Telegram 🤖
To create a bot in Telegram we need to use the [@BotFather](https://t.me/botfather) bot.
We need to use the `/newbot` command, give it a name and a username and we'll get a link and a token in return:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/61q9ruy7pbimcn0l65x2.png)

We can use the link to start a conversation with our bot and later we'll also need the token to connect to the bot from our code. We can always go back to the [@BotFather](https://t.me/botfather) and retrieve again the token or change some settings.

####Make it talk 🗣
We are ready to start the implementation. We'll be using the [Telebot](https://github.com/tucnak/telebot) Go library. Telebot is a framework that is going help us a lot interacting with the Telegram Bot API (setting up the bot, handling requests, sending messages, etc).

Our only goal now will be making our bot reply to any message we send to it.

First of all, we need to create our bot instance and configure it with an endpoint that Telegram will use to POST   the messages the bot receives. 
That endpoint will be something like 

```
https://localhost:[PORT]/bot[BOT_TOKEN]
```

but it can't be in our local, we need to make it accessible to the internet so the bot can actually hit it.
For that purpose, we can use a tool called [Ngrok](https://ngrok.com/download) and with a simple command it will expose the local port of our choice (`4040` in this case) and give us back a URL.
```javascript
ngrok http 4040
// returns a URL like https://89e834cae2b6.ngrok.io
```

We have everything ready, so we can now create our bot instance configured with the webhook endpoint in which it will receive all the updates from Telegram:
```go
webhook := &telebot.Webhook{
	Listen: ":" + os.Getenv("PORT"),
	Endpoint: &telebot.WebhookEndpoint{
		PublicURL: os.Getenv("WEBHOOK_URL") + "/bot" + os.Getenv("BOT_TOKEN"),
	},
}

settings := telebot.Settings{
	Token:  os.Getenv("BOT_TOKEN"),
	Poller: webhook,
}

bot, err := telebot.NewBot(settings)
if err != nil {
	log.Fatalf("error initializing bot: %s", err)
	return
}
```

After that, we can add a handle to the bot that will trigger every time it receives any text message and replies to the user with `I'm a 🤖!`.

```go
bot.Handle(telebot.OnText, func(msg *telebot.Message) {
	_, err := bot.Send(msg.Sender, "I'm a 🤖!")
	if err != nil {
		log.Printf("error sending message: %s", err)
		return
	}
})

bot.Start()
```

We are finally ready to test our bot! Let's run it with:
```go
PORT=[port of our chice] \
WEBHOOK_URL=[public url] \
BOT_TOKEN=[bot token provided by @BotFather] \
    go run cmd/dictiobot/main.go
```
We can access the [link](http://t.me/share_the_word_bot) that the `@BotFather` provided when we created the bot and send a message to it. Hopefully, we'll get our response back! 😅
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5jpb6xvl9wwrhgmxipv8.png)And it works! 🙌 It's not too clever for now, but it will get better!

You can check the whole code here: https://github.com/albarin/dictiobot/tree/01-the-bot-comes-to-life

In the next chapter, we will build a service to make requests to the [WordsAPI](https://www.wordsapi.com/) to be able to search for words.

See you! 👋