After building and using the stock notifier I built in Go I am pleased that it is solid and the calculations seem to be working as expected. I recently decided to integrate a Telegram Bot into this system, as an addition to email. I then added some commands to the bot. This process was much easier than expected, taking under two hours from start to finish.

Telegram

I decided to use Telegram due to its ease of integration. It allowed for communication directly to me, as opposed to having to create a team, and had loads of well written libraries for Go that I could just drop in. After a ten minute test, I had gone from nothing to messages being received. I was sold.

The integration

Keeping code separate and neat is an ideal I strive for, so I create a separate file to handle all of the Telegram integration. This project is due for a clean-up soon, but is looking fair overall.

The abstracted Telegram file has a function to send messages to a bot, as well as function to set up an always on server to listen to messages coming in. The message sending is done simply as follows:

func sendTelegramBotMessage(message string, configuration Configuration, replyId int) {
    bot, err := tgbotapi.NewBotAPI(configuration.TelegramBotApi)
    if err != nil {
    log.Fatal(err)
    }

    bot.Debug = true

    fmt.Printf("Authorized on account %s", bot.Self.UserName)
    botId, err := strconv.Atoi(configuration.TelegramBotID)
    if err != nil {
    fmt.Println("Could not convert telegram bot id")
    return
    }

    msg := tgbotapi.NewMessage(botId, message)
    if replyId != 0 {
    msg.ReplyToMessageID = replyId
    }

    bot.Send(msg)
}

The bot server is structured as follows:

func startTelegramBot(configuration Configuration) {
    bot, err := tgbotapi.NewBotAPI(configuration.TelegramBotApi)
    if err != nil {
    log.Fatal(err)
    }

    bot.Debug = true

    fmt.Printf("Authorized on account %s", bot.Self.UserName)

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates, err := bot.GetUpdatesChan(u)

    for update := range updates {
        ...
    }
{

Once this has been set up, the strings are split and parsed against predefined commands. The two commands implemented are trends and stock. The first just returns all trending stocks, the second is used as stock jse npn which would return information on the JSE listed stock NPN.

Bot stock example

Conclusion

The above will be extended as the project grows, allowing for a more fully qualified bot. For now, it provides an immediate use case for me: checking stock prices on the go.

As always, the code is available on Github.