First things first

This days I’m working on Botio. An opinionated CLI to build and manage bots and their commands for different platforms among which is Telegram. And it’s from working on Botio that this article comes from.

I would also like to warm you that the code below may seem at first glance too simple and therefore disappoint a little. If that’s your case, I’m sorry. In this article I just want to lay the groundwork for future articles that (I hope) might interest you a bit more.

What is Telegram

If you’re reading this it’s quite possible that you know perfectly well what Telegram is. If you don’t know anything about Telegram I recommend you to check their website.

Basically, Telegram is a free messaging app with support for bots.

What is a Telegram bot

A bot (or chatbot in this case), is nothing more than a service (server) that after receiving a command (request), will perform some actions and then respond with another text message (response).

If my definition hasn’t made it clear to you, here is the Wikipedia to the rescue.

Why we would want to write a Telegram bot

A short and simple answer is because it’s funny to build one.

It is true that bots, specially chatbots for messaging application are no longer fashionable (if they ever have been…). But don’t forget that knowing how to build one can help you in the future, especially because almost all platforms are very similar and once you more or less understand how one of them works when it comes to receiving and answering messages you more or less understand how the rest works.

How to get a Telegram token

To start building a bot for Telegram you’ll first need a Telegram token, and to get a token you’ll first need to talk to… well… to a bot.

I really think that the Telegram team have done a very good job explaining the process of getting a token in this article. So I just recommend you to check it before you continue. If you think there is too much text and want to go directly to the explanation of how to get your token you can click here.

Building our Telegram bot

To build or Telegram bot we’re going to use the yanzay/tbot package that you can find here.

There are other packages to work with like this one called telegram-bot-api and that you might want to check back later.

Also note that the code I will show below the Telegram token is going to be hard-coded. This is something that it is obviously not recommended to do in any case and that you can avoid using environment variables of the flags package.

Handling our first command

Now that it’s all cleared up, let’s get started:

package main

import (
	"log"

	"github.com/yanzay/tbot/v2"
)

const token = "YOUR-TELEGRAM-TOKEN"

func main() {
	bot := tbot.New(token)
	client := bot.Client()

	bot.HandleMessage("/hi", func(m *tbot.Message) {
		client.SendMessage(m.Chat.ID, "Hi!")
	})

	log.Fatal(bot.Start())
}

In the code above we are basically creating a new Server using our Telegram’s token from which we’re going to create our client that we’re going to use to communicate with our users.

So if you now go into the Telegram application and send the message /hi to your bot you should receive Hi! as a response.

Commands in Telegram begin with /. On other platforms this may differ.

If you have paid attention, you may have noticed that before you can talk to your telegram bot to test the /hi command, /start is sent. This command is used to send to the user a description of everything the bot can do for him.

More handling

So, let’s handle the /start command then.

package main

import (
	"fmt"
	"log"

	"github.com/yanzay/tbot/v2"
)

const token = "YOUR-TELEGRAM-TOKEN"

func main() {
	bot := tbot.New(token)
	client := bot.Client()

	bot.HandleMessage("/start", func(m *tbot.Message) {
        response := fmt.Sprintf("Hi %s, my name is %s and I'm here to help you!", m.Chat.Username, "YOUR BOT NAME")

		client.SendMessage(m.Chat.ID, response)
	})

	bot.HandleMessage("/hi", func(m *tbot.Message) {
		client.SendMessage(m.Chat.ID, "Hi!")
	})

	log.Fatal(bot.Start())
}

Now we have an answer for the /start and the /hi commands.

If you have noticed, the tbot.Message struct contains information about the user among other things. If you want to improve your Telegram bot it’s highly recommended that you take a deep look at it.

Handling everything

It may seem like the method HandleMessage receives as its first parameter a simple string. But what he’s actually receiving is a pattern.

package main

import (
	"log"

	"github.com/yanzay/tbot/v2"
)

const token = "YOUR-TELEGRAM-TOKEN"

func main() {
	bot := tbot.New(token)
	client := bot.Client()

	bot.HandleMessage(".", func(m *tbot.Message) {
		client.SendMessage(m.Chat.ID, "Hi!")
	})

	log.Fatal(bot.Start())
}

If now you send any message to your bot you’ll receive a Hi! all the time as the only answer. This is because the . refers to any character except newlines.

This allows us to receive anything the user sends us, check to see if we have a ready response and if so, send it to them.

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/yanzay/tbot/v2"
)

const token = "YOUR-TELEGRAM-TOKEN"

func main() {
	responses := map[string]func() string{
		"/start": func() string { return "Nice to meet you!" },
		"/hi":    func() string { return "Hi!" },
		"/now":   func() string { return fmt.Sprintf("%v", time.Now()) },
	}

	bot := tbot.New(token)
	client := bot.Client()

	bot.HandleMessage(".", func(m *tbot.Message) {
		resp, ok := responses[m.Text]
		if !ok {
			client.SendMessage(m.Chat.ID, "I didn't understand you.")
		}

		client.SendMessage(m.Chat.ID, resp())
	})

	log.Fatal(bot.Start())
}

Now we have a bot to which we can easily add commands with his answers.

Optional steps

Some things you can improve on your own are:

  • Do not hard-code the Telegram token (please).
  • Better logging.
  • Using a database instead of a map.
  • Send chat actions.