go-telegram/bot

repository·main·Indexed 23 days ago

https://github.com/go-telegram/bot

A high-level, idiomatic Golang wrapper for the Telegram Bot API. It supports long-polling and webhook modes, built-in middleware, and worker concurrency. The framework provides all Telegram Bot API methods as PascalCase functions on the bot instance and includes utilities for MarkdownV2 escaping, WebApp request validation, and handler registration for message text and callback data.

Tokens
9.8K
Snippets
12
Records
78
Agent score
83%

What's inside go-telegram/bot

  1. Create and start a basic echo bot

    main

    To initialize a bot, use bot.New with your token from BotFather. You can provide bot.Options to customize behavior, such as setting a default handler. Use b.Start(ctx) to begin polling for updates.

    package main
    
    import (
    	"context"
    	"os"
    	"os/signal"
    
    	"github.com/go-telegram/bot"
    	"github.com/go-telegram/bot/models"
    )
    
    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,
    	})
    }
  2. Use Webhooks to receive updates

    main

    Instead of polling with bot.Start, use bot.StartWebhook to run the bot in webhook mode. You must also provide an HTTP handler using b.WebhookHandler() to your web server. For security, it is recommended to use bot.WithWebhookSecretToken to verify the X-Telegram-Bot-Api-Secret-Token header sent by Telegram.

    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,
    	})
    }
  3. Handle Telegram API errors

    main

    The library provides specific error types to handle different Telegram API error codes. You can use errors.Is() for standard error codes and bot.IsTooManyRequestsError() for rate-limiting errors.

    Error Types

    • ErrorForbidden (403): Bot has no access (e.g., user blocked the bot).
    • ErrorBadRequest (400): Bad request made to the API.
    • ErrorUnauthorized (401): Bot access is unauthorized.
    • TooManyRequestsError (429): Rate limit hit. Includes a RetryAfter value.
    • ErrorNotFound (404): Resource not found.
    • ErrorConflict (409): A conflict occurred during the request.

    Error Handling Example

    _, 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
    }
  4. Configure the bot using Options

    main
    The bot package uses the functional options pattern for configuration. An Option is a function that modifies a *Bot instance during initialization. You can pass multiple Option functions to your bot constructor to customize behavior such as timeouts, middlewares, handlers, and networking settings.
  5. Define boolean pointers using True() and False()

    main

    Some Telegram API parameters require a pointer to a boolean (*bool). Instead of manually creating pointers, use bot.True() and bot.False() to define these values.

    Example for SendPollParams:

    p := &bot.SendPollParams{
        ChatID: chatID,
        Question: "Question",
        Options: []string{"Option 1", "Option 2"},
        IsAnonymous: bot.False(),
    }
    
    b.SendPoll(ctx, p)
  6. Register handlers for Message Text and Callback Data

    main

    You can register specific handlers for different update types using b.RegisterHandler. This allows you to respond to specific text patterns or callback data without using a single default handler.

    Handler Types:

    • bot.HandlerTypeMessageText: For Update.Message.Text.
    • bot.HandlerTypeCallbackQueryData: For Update.CallbackQuery.Data.
    • bot.HandlerTypeCallbackQueryGameShortName: For Update.CallbackQuery.GameShortName.
    • bot.HandlerTypePhotoCaption: For Update.Message.Caption.

    Match Types:

    • bot.MatchTypeExact: Exact match.
    • bot.MatchTypePrefix: Prefix match.
    • bot.MatchTypeContains: Contains match.
    • bot.MatchTypeCommand: Command match.
    • bot.MatchTypeCommandStartOnly: Command match that only works if it's the start of the text.

    Advanced Matching:

    • Use RegisterHandlerRegexp for regular expressions.
    • Use RegisterHandlerMatchFunc for custom logic functions.
  7. Send media groups using InputMedia

    main

    To send multiple media items (e.g., SendMediaGroup), use the models.InputMedia interface. To upload new files via multipart/form-data instead of using a URL or FileID, use the attach://<name> syntax in the Media field and provide the content in the MediaAttachment field.

    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,
        },
    }
    
    b.SendMediaGroup(ctx, params)
  8. Call Telegram Bot API methods

    main

    The framework provides all Telegram Bot API methods as functions on the *bot.Bot instance. Method names match the official documentation but use PascalCase (e.g., bot.SendMessage, bot.SendPhoto).

    Most methods follow this signature: (ctx context.Context, params <PARAMS>) (<response>, error)

    Where <PARAMS> is a pointer to a struct named after the method with a Params suffix (e.g., bot.SendMessageParams).

    Exceptions:

    • GetMe, Close, and Logout have no parameters.
  9. Validate Telegram WebApp requests

    main

    To ensure a request received from a Telegram Mini App is authentic, use ValidateWebappRequest. This validates the data against your bot token.

    // 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
    }