DEV Community

Alba Rincón
Alba Rincón

Posted on • Updated on

Building a Telegram bot: share the words!

In the second post of this series, we added a package to make requests to the WordsAPI. In this last post, we'll use it to search words from the user input and share the results in any channel.

Configuring the bot 🤖

We want the bot to be accessible from any conversation in Telegram, to achieve that we need to make it an Inline bot.
This needs to be configured with @BotFather. We need to run the /mybots command, select the @share_the_word_bot from the list, go to the bots settings, and turn on Inline mode.
Alt Text
Once this setting is enabled, we can invoke the bot by typing @share_the_word_bot followed by the word we want to search for:

@share_the_word_bot cat
Enter fullscreen mode Exit fullscreen mode

This will generate a query to our bot with the selected word as a string.

Reacting to the query ↩️

We'll need to change our bot handler to listen for any query (telebot.OnQuery) instead of listening for any text (telebot.OnText) and then capture the word from the query:

bot.Handle(telebot.OnQuery, func(q *telebot.Query) {
    word := q.Text
}
Enter fullscreen mode Exit fullscreen mode

Using the API client

First, we'll need to initialize our pkg/words client to get the word definition:

api := words.New(
    "https://wordsapiv1.p.rapidapi.com/words",
    os.Getenv("WORDSAPI_TOKEN"),
    http.DefaultClient,
)
Enter fullscreen mode Exit fullscreen mode

Next, in the query handler, we'll make the request:

bot.Handle(telebot.OnQuery, func(q *telebot.Query) {
    word := q.Text

    // get the word definitions
    definitions, err := api.Word(word)
    if err != nil {
        log.Printf("error searching for word: %s", err)
    }

    // format the results to send back to Telegram
    results := make(telebot.Results, len(definitions))
    for i, def := range definitions {
        results[i] = createResult(word, def, i)
    }

    // send the answer back
    err = bot.Answer(q, &telebot.QueryResponse{Results: results})
    if err != nil {
        log.Println(err)
    }
})
Enter fullscreen mode Exit fullscreen mode

Each word definition is converted into a telebot.Result:

func createResult(word string, def words.Result, i int) *telebot.ArticleResult {
    result := &telebot.ArticleResult{
        Title:       word,
        Description: def.Definition,
    }

    result.SetContent(&telebot.InputTextMessageContent{
        Text:      def.Format(word),
        ParseMode: telebot.ModeMarkdownV2,
    })

    result.SetResultID(strconv.Itoa(i))

    return result
}
Enter fullscreen mode Exit fullscreen mode

That's it! We can finally use our bot, just run

PORT=[port of our chice] \
WEBHOOK_URL=[public url] \
BOT_TOKEN=[bot token provided by @BotFather] \
    go run cmd/dictiobot/main.go
Enter fullscreen mode Exit fullscreen mode

and try it!

Check the code: https://github.com/albarin/dictiobot/tree/03-share-the-words

Thank you! 😊👋

Top comments (0)