Golang bindings for the Telegram Bot API

Golang bindings for the Telegram Bot API

GoDoc Travis

All methods are fairly self explanatory, and reading the godoc page should explain everything. If something isn't clear, open an issue or submit a pull request.

The scope of this project is just to provide a wrapper around the API without any additional features. There are other projects for creating something with plugins and command handlers without having to design all that yourself.

Join the development group if you want to ask questions or discuss development.

Example

First, ensure the library is installed and up to date by running go get -u github.com/go-telegram-bot-api/telegram-bot-api.

This is a very simple bot that just displays any gotten updates, then replies it to that chat.

package main

import (
	"log"

	"github.com/go-telegram-bot-api/telegram-bot-api"
)

func main() {
	bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
	if err != nil {
		log.Panic(err)
	}

	bot.Debug = true

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

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

	updates, err := bot.GetUpdatesChan(u)

	for update := range updates {
		if update.Message == nil { // ignore any non-Message Updates
			continue
		}

		log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

		msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
		msg.ReplyToMessageID = update.Message.MessageID

		bot.Send(msg)
	}
}

There are more examples on the wiki with detailed information on how to do many different kinds of things. It's a great place to get started on using keyboards, commands, or other kinds of reply markup.

If you need to use webhooks (if you wish to run on Google App Engine), you may use a slightly different method.

package main

import (
	"log"
	"net/http"

	"github.com/go-telegram-bot-api/telegram-bot-api"
)

func main() {
	bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = true

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

	_, err = bot.SetWebhook(tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, "cert.pem"))
	if err != nil {
		log.Fatal(err)
	}
	info, err := bot.GetWebhookInfo()
	if err != nil {
		log.Fatal(err)
	}
	if info.LastErrorDate != 0 {
		log.Printf("Telegram callback failed: %s", info.LastErrorMessage)
	}
	updates := bot.ListenForWebhook("/" + bot.Token)
	go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)

	for update := range updates {
		log.Printf("%+v\n", update)
	}
}

If you need, you may generate a self signed certficate, as this requires HTTPS / TLS. The above example tells Telegram that this is your certificate and that it should be trusted, even though it is not properly signed.

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3560 -subj "//O=Org\CN=Test" -nodes

Now that Let's Encrypt is available, you may wish to generate your free TLS certificate there.

Comments
  • Multi-thread safe?

    Multi-thread safe?

    Just wondering if I need to protect the bot object with a mutex when calling bot.Send() from multiple go routines. I don't think I do, but just want to be sure.

  • cannot access some methods when using with go.mod

    cannot access some methods when using with go.mod

    It works fine when not using go.mod

    my go.mod

    module github.com/phanirithvij/stickerbot
    
    go 1.13
    
    require (
    	github.com/cavaliercoder/grab v2.0.0+incompatible
    	github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
    	github.com/spf13/viper v1.6.3
    	github.com/technoweenie/multipartstreamer v1.0.1 // indirect
    )
    

    my go.sum file

    //...
    github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
    github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
    

    Code:

    //...
    config := tgbotapi.GetStickerSetConfig{Name: stickerSet}
    data, err := bot.GetStickerSet(config)
    //...
    

    Error:

    # command-line-arguments
    .\bot.go:76:14: undefined: tgbotapi.GetStickerSetConfig
    .\bot.go:77:20: bot.GetStickerSet undefined (type *tgbotapi.BotAPI has no field or method GetStickerSet)
    
  • BUTTON_TYPE_INVALID

    BUTTON_TYPE_INVALID

    Bad Request: BUTTON_TYPE_INVALID if I try remove InlineKeyboard in message by this code:

    edit := tgbotapi.NewEditMessageReplyMarkup(
        callback.Message.Chat.ID,
        callback.Message.MessageID,
        tgbotapi.InlineKeyboardMarkup{},
    )
    bot.Send(edit)
    

    P.S.: Also, as and with this variant:

    var markup tgbotapi.InlineKeyboardMarkup
    edit := tgbotapi.NewEditMessageText(
        callback.Message.Chat.ID,
        callback.Message.MessageID,
        "sample text",
    )
    edit.ReplyMarkup = &markup
    bot.Send(edit)
    
  • Panic when sending Photo by URL

    Panic when sending Photo by URL

    Trying to send a Photo by URL results in nil pointer dereference

    This is the panic:

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x476208]
    
    goroutine 52 [running]:
    panic(0x6224a0, 0xc42000c0d0)
            /usr/lib/go/src/runtime/panic.go:500 +0x1a1
    io.(*multiReader).Read(0xc42023c1a0, 0xc4204572e7, 0x44, 0xd19, 0x1cc, 0x0, 0x0)
            /usr/lib/go/src/io/multi.go:20 +0x98
    io/ioutil.(*nopCloser).Read(0xc42022a270, 0xc4204572e7, 0x44, 0xd19, 0x1cc, 0x0, 0x0)
            <autogenerated>:4 +0x6b
    io.(*LimitedReader).Read(0xc420376640, 0xc4204572e7, 0xd19, 0xd19, 0x1cc, 0x0, 0x0)
            /usr/lib/go/src/io/io.go:436 +0x6c
    bufio.(*Writer).ReadFrom(0xc420322f80, 0x75f9e0, 0xc420376640, 0xc4200fcbb8, 0x1, 0x18)
            /usr/lib/go/src/bufio/bufio.go:693 +0xcc
    io.copyBuffer(0x75f660, 0xc420322f80, 0x75f9e0, 0xc420376640, 0x0, 0x0, 0x0, 0x631bc0, 0x1, 0xc420376640)
            /usr/lib/go/src/io/io.go:384 +0x323
    io.Copy(0x75f660, 0xc420322f80, 0x75f9e0, 0xc420376640, 0xf, 0xc420379100, 0x581d02)
            /usr/lib/go/src/io/io.go:360 +0x68
    net/http.(*transferWriter).WriteBody(0xc4202fa7e0, 0x75f660, 0xc420322f80, 0x2, 0x2)
            /usr/lib/go/src/net/http/transfer.go:227 +0x677
    net/http.(*Request).write(0xc4200c01e0, 0x75f660, 0xc420322f80, 0x0, 0xc420365890, 0x0, 0x0, 0x0)
            /usr/lib/go/src/net/http/request.go:565 +0x778
    net/http.(*persistConn).writeLoop(0xc420474300)
            /usr/lib/go/src/net/http/transport.go:1649 +0x1ac
    created by net/http.(*Transport).dialConn
            /usr/lib/go/src/net/http/transport.go:1063 +0x50e
    exit status 2
    

    This is my code:

    package main
    
    import (
            "log"
            "github.com/go-telegram-bot-api/telegram-bot-api"
            "net/url"
    )
    
    func main() {
            bot, err := tgbotapi.NewBotAPI("pls enter some token here")
            if err != nil {
                    log.Panic(err)
            }
            bot.Debug = true
            log.Printf("Authorized on account %s", bot.Self.UserName)
    
            u := tgbotapi.NewUpdate(0)
            u.Timeout = 60
            updates, err := bot.GetUpdatesChan(u)
    
            url_ptr, _ := url.Parse("https://assets-cdn.github.com/images/modules/site/home-ill-platform.png")
            url := *url_ptr
    
            for update := range updates {
                    if update.Message == nil {
                            continue
                    }
                    log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
                    msg := tgbotapi.NewPhotoUpload(update.Message.Chat.ID, url)
                    bot.Send(msg);
            }
    }
    

    The panic is caused by this line: https://github.com/go-telegram-bot-api/telegram-bot-api/blob/99170e2de436c1be90d2ef23dcf533b55a973e56/bot.go#L171

    The panic only happens when sending a Photo via URL, if NewPhotoUpload is called with file path, no panic happens and the Photo is sent correctly.

  • Provide users with more customization when creating a new bot.

    Provide users with more customization when creating a new bot.

    User are now able to create a bot with debug enabled by default.

    The debug part is use full when NewBotAPI() is failing with the message

    http.2.0bttrvjk5f4e@linuxkit-025000000001    | 2018/11/12 12:15:38 created msg
    http.2.0bttrvjk5f4e@linuxkit-025000000001    | 2018/11/12 12:15:38 getting bot
    http.2.0bttrvjk5f4e@linuxkit-025000000001    | 2018/11/12 12:15:38 error is about to happen
    http.2.0bttrvjk5f4e@linuxkit-025000000001    | 2018/11/12 12:15:38 Not Found (this one 🤷🏾‍♂️)
    

    By being able to enale debug when creating the bot user are able to debug the following code:

    		b, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_BOT_TOKEN"))
    
    		if err != nil {
    			log.Print("error is about to happen")
    			log.Fatal(err)
    		}
    
  • answering inline query

    answering inline query

    I think that we need an example of answering inline-query, I'm having a little problem making one myself, so hopefully the following code will demonstrate a question/example to be used in README.md

    package main
    
    import (
        "log"
    
        "gopkg.in/telegram-bot-api.v1"
    )
    
    func main() {
        bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken")
        if err != nil {
            log.Panic(err)
        }
    
        log.Printf("Authorized on account %s", bot.Self.UserName)
    
        u := tgbotapi.NewUpdate(0)
        u.Timeout = 60
    
        updates, err := bot.GetUpdatesChan(u)
    
        for update := range updates {
            if update.InlineQuery.Query == "" {
                continue
            }
    
            answer := tgbotapi.InlineQueryResultArticle{
                InlineQueryResult: tgbotapi.InlineQueryResult{ // ??
                    Type: "article",
                    ID:   update.InlineQuery.ID,
                },
    
                Title:       "Echo",
                MessageText: update.InlineQuery.Query,
            }
    
            inlineConf := tgbotapi.InlineConfig{
                InlineQueryID: update.InlineQuery.Query,
                Results:       []tgbotapi.InlineQueryResult{answer.InlineQueryResult}, // ??
            }
    
            if _, err := bot.AnswerInlineQuery(inlineConf); err != nil {
                log.Println(err)
            }
    
        }
    }
    

    I'm not sure how to deal with InlineQueryResult, this example will hit this error: [Error]: Bad request: Can't find field "message_text"

  • Hi, there not really PR, but new vision of tgbotapi with new API

    Hi, there not really PR, but new vision of tgbotapi with new API

    Many refactorings and DRYing, all Send* functions replaces with one Send(), Some other small changes. Tests added, 85% coverage. Everything works. Travis added.

    Please, check my code. I know, that public API is changed, but it's really useful. It will be great if it possible to merge my code to upstream, but i can rename project and develop it as my own.

    Package Syfaro/telegram-bot-api in my fork changed to zhulik/telegram-bot-api. I will change it back if you will merge my code.

    Thanks!

    ps: I want to develop some Bot framework based on it, with commands support, sessions, middlewares and so on

  • Answering inline query with a sticker

    Answering inline query with a sticker

    I want to use InlineQueryResultCachedSticker/NewInlineQueryResultCachedSticker in my project. As far as i understand, it is not available in current release. So, i'd like to know, if there is any way to use it now or when it will be available.

  • How to use payments

    How to use payments

    Couldn't quite figure out how to make payments with your library. I found the AnswerPreCheckoutQuery and AnswerShippingQuery methods, however, how do I sendInvoice? There's Pay field in InlineKeyboard button, but I don't think it does anything. Where do I enter my payment provider token and other info?

  • implement a feature that allows stopping the update loop of the bot

    implement a feature that allows stopping the update loop of the bot

    This is a PR following the improvement proposal I've posted in issue #84

    The code in the PR implements an option to stop the update loop that is generated on a call to GetUpdatesChan

  • More flexible logging options

    More flexible logging options

    At the moment this library does not allow a developer to replace the golang default log package to capture logs to redirect to say syslog as is common with services.

    This is mainly apparent in the UpdatesChan goroutine when an error occurs during the poll.

  • If you get more than 2 videos, FileID will repeat the bug.

    If you get more than 2 videos, FileID will repeat the bug.

    If you get more than 2 videos, FileID will repeat the bug.

    telegram version: 5.5.1 code:

    if update.Message.Video != nil { //Only the last id can be obtained here, and all ids are duplicate. log.Printf(update.Message.Video.FileID) }

  • Delete message error

    Delete message error

    I'm using delete message API:

    import (
    	telegram "github.com/go-telegram-bot-api/telegram-bot-api/v5"
    )
    
    // api *telegram.BotAPI
    msg := telegram.NewDeleteMessage(int64(chatID), msgID)
    if _, err := api.Send(msg); err != nil {
    	return errors.Wrap(err, "delete message")
    }
    

    When I call this API, Telegram deletes this message successfully, but telegram-bot library returns error: json: cannot unmarshal bool into Go value of type tgbotapi.Message.

    Debug logs for this call:

    2022/12/03 23:05:37 Endpoint: deleteMessage, params: map[chat_id:****** message_id:****]
    2022/12/03 23:05:38 Endpoint: deleteMessage, response: {"ok":true,"result":true}
    

    It looks like this library is trying to decode "result": true response from Telegram API into message struct.

    It's not a very critical issue, but because of it, I need to ignore errors from delete.

    Version is: github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1

  • why remove KickChatMember function from BotAPI in v5?

    why remove KickChatMember function from BotAPI in v5?

    v5 documentation: https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api/v5#BotAPI v4.6.4 documentation: https://pkg.go.dev/github.com/go-telegram-bot-api/telegram-bot-api#BotAPI.KickChatMember

    why remove KickChatMember function from BotAPI in v5?

Golang wrapper for the Sylviorus antispam API for telegram

Syl-Go Golang wrapper for the Sylviorus antispam API for telegram package test

Jan 2, 2022
(Golang) Go bindings for the Hugging Face Inference API

hfapigo (Golang) Go bindings for the Hugging Face Inference API. Directly call any model available in the Model Hub. An API key is required for author

Dec 18, 2022
(Golang) Go bindings for Discord

DiscordGo DiscordGo is a Go package that provides low level bindings to the Discord chat client API. DiscordGo has nearly complete support for all of

Jan 7, 2023
Mrrobot - A simple greetings bot for Slack that uses events api and hosted on AWS Lambda

Mr. Robot a greeter bot for your slack community build_docker

Aug 21, 2022
A serverless teeny-tiny version of Diomedes which sends alerts to Telegram. Written in Go.
A serverless teeny-tiny version of Diomedes which sends alerts to Telegram. Written in Go.

diomedes-search Get a notification on Telegram whenever your movie opens bookings in a theater of your choice. Pre-requisites Install AWS CLI (v2) by

Oct 11, 2022
Send messages from slack incoming webhook integrations to telegram
Send messages from slack incoming webhook integrations to telegram

slack-to-telegram Slack incoming webhook to telegram Send messages from slack incoming webhook integrations to telegram Tested on Gitlab Slack Notific

Jul 19, 2022
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key
Simple-Weather-API - Simple weather api app created using golang and Open Weather API key

Simple Weather API Simple weather api app created using golang and Open Weather

Feb 6, 2022
Go bindings for libappindicator3 C library

go-appindicator Go bindings for libappindicator3 C library. Libappindicator is a library to allow applications to export a menu into the Unity Menu ba

Sep 26, 2022
🤖🚀📦 A Discord Bot for accessing the cdnjs platform
🤖🚀📦 A Discord Bot for accessing the cdnjs platform

A bridge between https://cdnjs.com/api and Discord Big shoutout to Br1ght0ne for helping me with writing helpers.go/SplitIn

Aug 17, 2022
🤖 Chegg answers requested and sent by the Discord BOT to the targeted user.
🤖 Chegg answers requested and sent by the Discord BOT to the targeted user.

"I believe that open-source resources are a must for everyone around. Especially in the field of education. As Chegg costs some money monthly, unfortunately, not all of us are capable of to charge ourselves that cost, which ends up blocking all those valuable resources to us. That is why, I have developed this bot, which unblurs the blurred question answers and sends them to you. I will develop it to a next level in the upcoming days, whereas, it will send the images/text, answers in short, directly through the Discord server you are in, or just DM/PM."

Aug 20, 2021
A bot that tweets posts with the Go tag on Qiita
A bot that tweets posts with the Go tag on Qiita

GoTwitterBot A bot that tweets posts with the Go tag on Qiita go mod init main/main go get github.com/joho/godotenv go get github.com/ChimeraCoder/a

Oct 4, 2021
This bot require you to run the GETH client + use ethers framework.

Mad Liquidity Sniper This bot require you to run the GETH client + use ethers framework. All addresses and private keys contained have been changed fo

Oct 19, 2021
Chat bot for twitch

Microbot Chat bot for twitch. Run You need to provide config and cred files.

Oct 23, 2021
Trojan discord bot, used for grieving discord servers
Trojan discord bot, used for grieving discord servers

disc-TROJAN-go Trojan discord bot, used for grieving discord servers How Does It Work? disc-TROJAN-go is a discord bot with hidden features. At the ti

Feb 28, 2022
An API client for the Notion API implemented in Golang

An API client for the Notion API implemented in Golang

Dec 30, 2022
A API scanner written in GOLANG to scan files recursively and look for API keys and IDs.

GO FIND APIS _____ ____ ______ _____ _ _ _____ _____ _____ _____ / ____|/ __ \ | ____|_ _| \ | | __ \ /\ | __ \_

Oct 25, 2021
Arweave-api - Arweave API implementation in golang

Arweave API Go implementation of the Arweave API Todo A list of endpoints that a

Jan 16, 2022
Reservationbox-api - Reservationbox Api with golang
Reservationbox-api - Reservationbox Api with golang

reservationbox-api How to set up application Cloning git on this link : https://

Jan 30, 2022
Go api infra - Infrastructure for making api on golang so easy

Go Infra Api Infrastructre methods and types for make api simple Response abstra

Jun 18, 2022