Top Related Projects
Golang bindings for the Telegram Bot API
Telebot is a Telegram bot framework in Go.
Quick Overview
go-telegram/bot is a Go library for creating Telegram bots. It provides a simple and intuitive API for interacting with the Telegram Bot API, allowing developers to easily build and deploy Telegram bots using Go.
Pros
- Easy to use and well-documented API
- Supports all Telegram Bot API methods
- Includes convenient helpers for common bot tasks
- Actively maintained and regularly updated
Cons
- Limited built-in middleware support
- Lacks advanced features like conversation management
- May require additional libraries for complex bot scenarios
- Documentation could be more comprehensive for advanced use cases
Code Examples
Creating a simple bot that echoes messages:
package main
import (
"log"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)
func main() {
b, err := bot.New("YOUR_BOT_TOKEN")
if err != nil {
log.Fatalf("Error creating bot: %v", err)
}
b.RegisterHandler(bot.HandlerTypeMessage, "/echo", bot.MatchTypePrefix, func(ctx *bot.Context) error {
return ctx.Reply(ctx.Message.Text, nil)
})
b.Start()
}
Sending a photo with a caption:
func sendPhoto(ctx *bot.Context) error {
photo := &models.InputFileString{Data: "https://example.com/image.jpg"}
_, err := ctx.Bot.SendPhoto(ctx.Chat.ID, "Check out this photo!", photo, nil)
return err
}
Using inline keyboards:
func inlineKeyboard(ctx *bot.Context) error {
keyboard := &models.InlineKeyboardMarkup{
InlineKeyboard: [][]models.InlineKeyboardButton{
{
{Text: "Button 1", CallbackData: "btn1"},
{Text: "Button 2", CallbackData: "btn2"},
},
},
}
return ctx.Reply("Choose an option:", &bot.SendOptions{ReplyMarkup: keyboard})
}
Getting Started
-
Install the library:
go get -u github.com/go-telegram/bot
-
Create a new bot instance:
b, err := bot.New("YOUR_BOT_TOKEN") if err != nil { log.Fatalf("Error creating bot: %v", err) }
-
Register handlers for different types of updates:
b.RegisterHandler(bot.HandlerTypeMessage, "/start", bot.MatchTypeExact, handleStart)
-
Start the bot:
b.Start()
Competitor Comparisons
Golang bindings for the Telegram Bot API
Pros of telegram-bot-api
- More mature and widely adopted project with a larger community
- Comprehensive documentation and examples
- Supports more Telegram Bot API features out of the box
Cons of telegram-bot-api
- Larger codebase, potentially more complex for simple use cases
- Less frequent updates compared to bot
- Higher memory usage due to more extensive feature set
Code Comparison
bot:
bot, err := bot.New("BOT_TOKEN")
if err != nil {
log.Fatal(err)
}
updates := bot.GetUpdatesChan(bot.NewUpdate(0))
telegram-bot-api:
bot, err := tgbotapi.NewBotAPI("BOT_TOKEN")
if err != nil {
log.Panic(err)
}
u := tgbotapi.NewUpdate(0)
updates := bot.GetUpdatesChan(u)
Both libraries offer similar basic functionality for creating a bot and receiving updates. The bot library has a slightly more concise syntax, while telegram-bot-api provides more options for customization.
telegram-bot-api is generally better suited for complex bots with advanced features, while bot may be preferable for simpler applications or those prioritizing a lightweight implementation.
When choosing between the two, consider factors such as project requirements, desired features, and community support. Both libraries are viable options for developing Telegram bots in Go, with telegram-bot-api offering more comprehensive features at the cost of increased complexity.
Telebot is a Telegram bot framework in Go.
Pros of telebot
- More active development with frequent updates and contributions
- Extensive documentation and examples for easier onboarding
- Built-in middleware support for enhanced request handling
Cons of telebot
- Slightly more complex API compared to bot's simpler approach
- May have a steeper learning curve for beginners
- Less flexible in terms of low-level customization
Code Comparison
telebot:
bot, err := telebot.NewBot(telebot.Settings{
Token: "YOUR_TOKEN_HERE",
Poller: &telebot.LongPoller{Timeout: 10 * time.Second},
})
bot.Handle("/start", func(m *telebot.Message) {
bot.Send(m.Sender, "Hello!")
})
bot:
bot, err := bot.New("YOUR_TOKEN_HERE")
bot.Handle("/start", func(c *bot.Context) error {
return c.Send("Hello!")
})
Both libraries offer similar functionality for creating and handling Telegram bots. telebot provides more built-in features and abstractions, while bot focuses on simplicity and ease of use. The choice between them depends on project requirements and developer preferences.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Golang Telegram Bot
â Present in the list of libraries https://core.telegram.org/bots/samples#go
Supports Bot API version: 8.3 from February 12, 2025
It's a Go zero-dependencies telegram bot framework
A simple example echo-bot
:
package main
import (
"context"
"os"
"os/signal"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)
// Send any text message to the bot after the bot has been started
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
opts := []bot.Option{
bot.WithDefaultHandler(handler),
}
b, err := bot.New("YOUR_BOT_TOKEN_FROM_BOTFATHER", opts...)
if err != nil {
panic(err)
}
b.Start(ctx)
}
func handler(ctx context.Context, b *bot.Bot, update *models.Update) {
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.Message.Chat.ID,
Text: update.Message.Text,
})
}
You can find more examples in the examples folder.
To run the examples, set the EXAMPLE_TELEGRAM_BOT_TOKEN
environment variable to your bot token.
Getting started
Go version: 1.18
Install the dependencies:
go get -u github.com/go-telegram/bot
Initialize and run the bot:
b, err := bot.New("YOUR_BOT_TOKEN_FROM_BOTFATHER")
b.Start(context.TODO())
On create bot will call the getMe
method (with 5 sec timeout). And returns error on fail.
If you want to change this timeout, use option bot.WithCheckInitTimeout
You can define a default handler for the bot:
b, err := bot.New("YOUR_BOT_TOKEN_FROM_BOTFATHER", bot.WithDefaultHandler(handler))
func handler(ctx context.Context, b *bot.Bot, update *models.Update) {
// this handler will be called for all updates
}
Webhooks
If you want to use webhooks, instead of using bot.Start
, you should use the bot.StartWebhook
method to start the bot.
Also, you should use bot.WebhookHandler()
method as HTTP handler for your server.
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
opts := []bot.Option{
bot.WithDefaultHandler(handler),
bot.WithWebhookSecretToken(os.Getenv("EXAMPLE_TELEGRAM_WEBHOOK_SECRET_TOKEN"))
}
b, _ := bot.New(os.Getenv("EXAMPLE_TELEGRAM_BOT_TOKEN"), opts...)
// call methods.SetWebhook if needed
go b.StartWebhook(ctx)
http.ListenAndServe(":2000", b.WebhookHandler())
// call methods.DeleteWebhook if needed
}
func handler(ctx context.Context, b *bot.Bot, update *models.Update) {
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.Message.Chat.ID,
Text: update.Message.Text,
})
}
Also, you can manually process updates with bot.ProcessUpdate
method.
update := models.Update{}
json.NewDecoder(req.Body).Decode(&update)
b.ProcessUpdate(ctx, &update)
Middlewares
You can use middlewares with WithMiddlewares(middlewares ...Middleware)
option.
See an example in examples
Available methods
All available methods are listed in the Telegram Bot API documentation
You can use all these methods as bot funcs. All methods have name like in official documentation, but with capital first letter.
bot.SendMessage
, bot.GetMe
, bot.SendPhoto
, etc
All methods have signature (ctx context.Context, params <PARAMS>) (<response>, error)
.
Except GetMe
, Close
and Logout
which are have not params
<PARAMS>
is a struct with fields that corresponds to Telegram Bot API parameters.
All Params structs have name like for corresponded methods, but with Params
suffix.
SendMessageParams
for SendMessage
method etc.
You should pass params by pointer
bot.SendMessage(ctx, &bot.SendMessageParams{...})
Options
You can use options to customize the bot.
b, err := bot.New("YOUR_BOT_TOKEN_FROM_BOTFATHER", opts...)
Options list (see options.go for more details)
WithCheckInitTimeout(timeout time.Duration)
- timeout for check init botWithMiddlewares(middlewares ...Middleware)
- add middlewaresWithMessageTextHandler(pattern string, matchType MatchType, handler HandlerFunc)
- add handler for Message.Text fieldWithCallbackQueryDataHandler(pattern string, matchType MatchType, handler HandlerFunc)
- add handler for CallbackQuery.Data fieldWithPhotoCaptionHandler
- add handler for Message.Caption fieldWithDefaultHandler(handler HandlerFunc)
- add default handlerWithDebug()
- enable debug modeWithErrorsHandler(handler ErrorsHandler)
- add errors handlerWithDebugHandler(handler DebugHandler)
- add debug handlerWithHTTPClient(pollTimeout time.Duration, client HttpClient)
- set custom http clientWithServerURL(serverURL string)
- set server urlWithSkipGetMe()
- skip call GetMe on bot initWithAllowedUpdates(params AllowedUpdates)
- set allowed_updates for getUpdates methodWithUpdatesChannelCap(cap int)
- set updates channel capacity, by default 1024WithWebhookSecretToken(webhookSecretToken string)
- set X-Telegram-Bot-Api-Secret-Token header sent from telegram servers to confirm validity of updateWithWorkers
- set the number of workers that are processing the Updates channel, by default 1UseTestEnvironment()
- use test environmentWithNotAsyncHandlers()
- allows to run handlers in the main goroutineWithInitialOffset(offset int64)
- allows to set initial offset for getUpdates method
Message.Text and CallbackQuery.Data handlers
For your convenience, you can use Message.Text
, CallbackQuery.Data
and Message.Caption
handlers.
An example:
b, err := bot.New("YOUR_BOT_TOKEN_FROM_BOTFATHER")
b.RegisterHandler(bot.HandlerTypeMessageText, "/start", bot.MatchTypeExact, myStartHandler)
b.Start(context.TODO())
also you can use bot init options
WithMessageTextHandler
andWithCallbackQueryDataHandler
In this example, the handler will be called when the user sends /start
message. All other messages will be handled by the default handler.
Handler Types:
HandlerTypeMessageText
- for Update.Message.Text fieldHandlerTypeCallbackQueryData
- for Update.CallbackQuery.Data fieldHandlerTypePhotoCaption
- for Update.Message.Caption field
RegisterHandler returns a handler ID string. You can use it to remove the handler later.
b.UnregisterHandler(handlerID)
Match Types:
MatchTypeExact
MatchTypePrefix
MatchTypeContains
You can use RegisterHandlerRegexp
to match by regular expression.
re := regexp.MustCompile(`^/start`)
b.RegisterHandlerRegexp(bot.HandlerTypeMessageText, re, myStartHandler)
If you want to use custom handler, use RegisterHandlerMatchFunc
matchFunc := func(update *models.Update) bool {
// your checks
return true
}
b.RegisterHandlerMatchFunc(bot.HandlerTypeMessageText, matchFunc, myHandler)
InputFile
For some methods, like SendPhoto
, SendAudio
etc, you can send file by file path or file contents.
To send a file by URL or FileID, you can use &models.InputFileString{Data: string}
:
// file id of uploaded image
inputFileData := "AgACAgIAAxkDAAIBOWJimnCJHQJiJ4P3aasQCPNyo6mlAALDuzEbcD0YSxzjB-vmkZ6BAQADAgADbQADJAQ"
// or URL image path
// inputFileData := "https://example.com/image.png"
params := &bot.SendPhotoParams{
ChatID: chatID,
Photo: &models.InputFileString{Data: inputFileData},
}
bot.SendPhoto(ctx, params)
To send an image file by its contents, you can use &models.InputFileUpload{Filename: string, Data: io.Reader}
:
fileContent, _ := os.ReadFile("/path/to/image.png")
params := &bot.SendPhotoParams{
ChatID: chatID,
Photo: &models.InputFileUpload{Filename: "image.png", Data: bytes.NewReader(fileContent)},
}
bot.SendPhoto(ctx, params)
InputMedia
For methods like SendMediaGroup
or EditMessageMedia
you can send media by file path or file contents.
Official documentation InputMedia
field
media
: File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass âattach://<file_attach_name>â to upload a new one using multipart/form-data under <file_attach_name> name.
If you want to use attach://
format, you should to define MediaAttachment
field with file content reader.
fileContent, _ := os.ReadFile("/path/to/image.png")
media1 := &models.InputMediaPhoto{
Media: "https://telegram.org/img/t_logo.png",
}
media2 := &models.InputMediaPhoto{
Media: "attach://image.png",
Caption: "2",
MediaAttachment: bytes.NewReader(fileContent),
}
params := &bot.SendMediaGroupParams{
ChatID: update.Message.Chat.ID,
Media: []models.InputMedia{
media1,
media2,
},
}
bot.SendMediaGroup(ctx, params)
Helpers
EscapeMarkdown(s string) string
Escape special symbols for Telegram MarkdownV2 syntax
EscapeMarkdownUnescaped(s string) string
Escape only unescaped special symbols for Telegram MarkdownV2 syntax
RandomString(n int) string
Returns fast random a-zA-Z string with n length
True() bool
, False() bool
Allows you to define *bool
values for params, which require *bool
, like SendPollParams
p := &bot.SendPollParams{
ChatID: chatID,
Question: "Question",
Options: []string{"Option 1", "Option 2"},
IsAnonymous: bot.False(),
}
b.SendPoll(ctx, p)
ValidateWebappRequest(values url.Values, token string) (user *WebAppUser, ok bool)
Validate request from Telegram Webapp
https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app
// get url values from request
values := req.URL.Query()
user, ok := bot.ValidateWebappRequest(values, os.Getenv("TELEGRAM_BOT_TOKEN"))
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
FileDownloadLink(f *models.File) string
Return file download link after call method GetFile
See documentation
Errors
This library includes error handling. It provides the following error types:
- ErrorForbidden (403): This error occurs when the bot has no access to the action, such as when the user has blocked the bot.
- ErrorBadRequest (400): This error indicates a bad request made to the bot's API.
- ErrorUnauthorized (401): This error occurs when the bot's access is unauthorized for the requested action.
- TooManyRequestsError: (429) This error indicates that the bot has received too many requests within a short period. It includes a RetryAfter value indicating when to retry the request.
- ErrorNotFound (404): This error indicates that the requested resource was not found.
- ErrorConflict (409): This error indicates a conflict occurred during the request.
Usage:
_, err := b.SendMessage(...)
if errors.Is(err, mybot.ErrorForbidden) {
// Handle the ErrorForbidden (403) case here
}
if errors.Is(err, mybot.ErrorBadRequest) {
// Handle the ErrorBadRequest (400) case here
}
if errors.Is(err, mybot.ErrorUnauthorized) {
// Handle the ErrorUnauthorized (401) case here
}
if mybot.IsTooManyRequestsError(err) {
// Handle the TooManyRequestsError (429) case here
fmt.Println("Received TooManyRequestsError with retry_after:", err.(*mybot.TooManyRequestsError).RetryAfter)
}
if errors.Is(err, mybot.ErrorNotFound) {
// Handle the ErrorNotFound (404) case here
}
if errors.Is(err, mybot.ErrorConflict) {
// Handle the ErrorConflict (409) case here
}
Other
bot.ID() int64
- returns bot ID. Bot ID is a unique identifier for the bot, obtained from the token as first part before:
. Example:110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
- bot ID is110201543
. If the bot token is invalid, the bot ID will be 0.bot.Token() string
- returns bot tokenbot.SetToken()
- set new bot token
MiniApp misc
Check the repo go-telegram/miniapp for Telegram MiniApp example.
Repo go-telegram/miniapp-types contains TypeScript types definitions for Telegram MiniApp object.
UI Components
In the repo https://github.com/go-telegram/ui you can find a some UI elements for your bot.
- datepicker
- inline_keyboard
- slider
- paginator
and more...
Please, check the repo for more information and live demo.
Top Related Projects
Golang bindings for the Telegram Bot API
Telebot is a Telegram bot framework in Go.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot