{"id":13409203,"url":"https://github.com/go-telegram/bot","last_synced_at":"2026-01-23T14:49:04.973Z","repository":{"id":40559876,"uuid":"485438083","full_name":"go-telegram/bot","owner":"go-telegram","description":"Telegram Bot API Go framework","archived":false,"fork":false,"pushed_at":"2025-08-18T14:05:09.000Z","size":407,"stargazers_count":1295,"open_issues_count":10,"forks_count":100,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-08-18T14:19:02.236Z","etag":null,"topics":["bot","go","golang","telegram","telegram-bot","telegram-bot-api"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-telegram.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-04-25T15:57:38.000Z","updated_at":"2025-08-18T14:04:48.000Z","dependencies_parsed_at":"2022-08-09T23:10:26.632Z","dependency_job_id":"8d0cdbbf-f152-4fc3-bf25-1c6194fc28fd","html_url":"https://github.com/go-telegram/bot","commit_stats":null,"previous_names":[],"tags_count":85,"template":false,"template_full_name":null,"purl":"pkg:github/go-telegram/bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-telegram%2Fbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-telegram%2Fbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-telegram%2Fbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-telegram%2Fbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-telegram","download_url":"https://codeload.github.com/go-telegram/bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-telegram%2Fbot/sbom","scorecard":{"id":376290,"data":{"date":"2025-08-11","repo":{"name":"github.com/go-telegram/bot","commit":"24c36eb620f90fbb8c5668d2dde88e86e530ecf0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Maintained","score":4,"reason":"5 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 11/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/go-telegram/bot/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/go-telegram/bot/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/go-telegram/bot/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/go-telegram/bot/main.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T14:19:36.679Z","repository_id":40559876,"created_at":"2025-08-18T14:19:36.679Z","updated_at":"2025-08-18T14:19:36.679Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28694457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T14:15:13.573Z","status":"ssl_error","status_checked_at":"2026-01-23T14:09:05.534Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","go","golang","telegram","telegram-bot","telegram-bot-api"],"created_at":"2024-07-30T20:00:58.829Z","updated_at":"2026-01-23T14:49:04.965Z","avatar_url":"https://github.com/go-telegram.png","language":"Go","readme":"# Golang Telegram Bot\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/go-telegram/bot)](https://goreportcard.com/report/github.com/go-telegram/bot) [![codecov](https://codecov.io/gh/go-telegram/bot/branch/main/graph/badge.svg?token=57B1OR6PCK)](https://codecov.io/gh/go-telegram/bot)\n\n✅ Present in the list of libraries https://core.telegram.org/bots/samples#go\n\n\u003e [Telegram Group](https://t.me/gotelegrambotui)\n\n\u003e Supports Bot API version: [9.3](https://core.telegram.org/bots/api#december-31-2025) from December 31, 2025\n\nIt's a Go zero-dependencies telegram bot framework\n\nA simple example `echo-bot`:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\n\t\"github.com/go-telegram/bot\"\n\t\"github.com/go-telegram/bot/models\"\n)\n\n// Send any text message to the bot after the bot has been started\n\nfunc main() {\n\tctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)\n\tdefer cancel()\n\n\topts := []bot.Option{\n\t\tbot.WithDefaultHandler(handler),\n\t}\n\n\tb, err := bot.New(\"YOUR_BOT_TOKEN_FROM_BOTFATHER\", opts...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tb.Start(ctx)\n}\n\nfunc handler(ctx context.Context, b *bot.Bot, update *models.Update) {\n\tb.SendMessage(ctx, \u0026bot.SendMessageParams{\n\t\tChatID: update.Message.Chat.ID,\n\t\tText:   update.Message.Text,\n\t})\n}\n```\n\nYou can find more examples in the [examples](examples) folder.\n\nTo run the examples, set the `EXAMPLE_TELEGRAM_BOT_TOKEN` environment variable to your bot token.\n\n## Getting started\n\nGo version: **1.18**\n\nInstall the dependencies:\n\n```bash\ngo get -u github.com/go-telegram/bot\n```\n\nInitialize and run the bot:\n\n```go\nb, err := bot.New(\"YOUR_BOT_TOKEN_FROM_BOTFATHER\")\n\nb.Start(context.TODO())\n```\n\nOn create bot will call the `getMe` method (with 5 sec timeout). And returns error on fail.\nIf you want to change this timeout, use option `bot.WithCheckInitTimeout`\n\nYou can define a default handler for the bot:\n\n```go\nb, err := bot.New(\"YOUR_BOT_TOKEN_FROM_BOTFATHER\", bot.WithDefaultHandler(handler))\n\nfunc handler(ctx context.Context, b *bot.Bot, update *models.Update) {\n\t// this handler will be called for all updates\n}\n```\n\n## Webhooks\n\nIf you want to use webhooks, instead of using `bot.Start`, you should use the `bot.StartWebhook` method to start the bot.\nAlso, you should use `bot.WebhookHandler()` method as HTTP handler for your server.\n\n```go\nfunc main() {\n\tctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)\n\tdefer cancel()\n\n\topts := []bot.Option{\n\t\tbot.WithDefaultHandler(handler),\n\t\tbot.WithWebhookSecretToken(os.Getenv(\"EXAMPLE_TELEGRAM_WEBHOOK_SECRET_TOKEN\"))\n\t}\n\n\tb, _ := bot.New(os.Getenv(\"EXAMPLE_TELEGRAM_BOT_TOKEN\"), opts...)\n\n\t// call methods.SetWebhook if needed\n\n\tgo b.StartWebhook(ctx)\n\n\thttp.ListenAndServe(\":2000\", b.WebhookHandler())\n\n\t// call methods.DeleteWebhook if needed\n}\n\nfunc handler(ctx context.Context, b *bot.Bot, update *models.Update) {\n\tb.SendMessage(ctx, \u0026bot.SendMessageParams{\n\t\tChatID: update.Message.Chat.ID,\n\t\tText:   update.Message.Text,\n\t})\n}\n```\n\n[Demo in examples](examples/echo_with_webhook/main.go)\n\nAlso, you can manually process updates with `bot.ProcessUpdate` method.\n\n```go\nupdate := models.Update{}\n\njson.NewDecoder(req.Body).Decode(\u0026update)\n\nb.ProcessUpdate(ctx, \u0026update)\n```\n\n## Middlewares\n\nYou can use middlewares with `WithMiddlewares(middlewares ...Middleware)` option.\n\nSee an example in [examples](examples/middleware/main.go)\n\n## Available methods\n\nAll available methods are listed in the [Telegram Bot API documentation](https://core.telegram.org/bots/api)\n\nYou can use all these methods as bot funcs. All methods have name like in official documentation, but with capital first letter.\n\n`bot.SendMessage`, `bot.GetMe`, `bot.SendPhoto`, etc\n\nAll methods have signature `(ctx context.Context, params \u003cPARAMS\u003e) (\u003cresponse\u003e, error)`.\nExcept `GetMe`, `Close` and `Logout` which have no params\n\n`\u003cPARAMS\u003e` is a struct with fields that corresponds to Telegram Bot API parameters.\nAll Params structs have name like for corresponded methods, but with `Params` suffix.\n\n`SendMessageParams` for `SendMessage` method etc.\n\nYou should pass params by pointer\n\n```go\nbot.SendMessage(ctx, \u0026bot.SendMessageParams{...})\n```\n\n## Options\n\nYou can use options to customize the bot.\n\n```go\nb, err := bot.New(\"YOUR_BOT_TOKEN_FROM_BOTFATHER\", opts...)\n```\n\n### Options list (see [options.go](options.go) for more details)\n\n- `WithCheckInitTimeout(timeout time.Duration)` - timeout for check init bot\n- `WithMiddlewares(middlewares ...Middleware)` - add middlewares\n- `WithMessageTextHandler(pattern string, matchType MatchType, handler HandlerFunc)` - add handler for Message.Text field\n- `WithCallbackQueryDataHandler(pattern string, matchType MatchType, handler HandlerFunc)` - add handler for CallbackQuery.Data field\n- `WithPhotoCaptionHandler` - add handler for Message.Caption field\n- `WithDefaultHandler(handler HandlerFunc)` - add default handler\n- `WithDebug()` - enable debug mode\n- `WithErrorsHandler(handler ErrorsHandler)` - add errors handler\n- `WithDebugHandler(handler DebugHandler)` - add debug handler\n- `WithHTTPClient(pollTimeout time.Duration, client HttpClient)` - set custom http client\n- `WithServerURL(serverURL string)` - set server url\n- `WithSkipGetMe()` - skip call GetMe on bot init\n- `WithAllowedUpdates(params AllowedUpdates)` - set [allowed_updates](https://core.telegram.org/bots/api#getupdates) for getUpdates method\n- `WithUpdatesChannelCap(cap int)` - set updates channel capacity, by default 1024\n- `WithWebhookSecretToken(webhookSecretToken string)` - set X-Telegram-Bot-Api-Secret-Token header sent from telegram servers to confirm validity of update\n- `WithWorkers` - set the number of workers that are processing the Updates channel, by default 1\n- `UseTestEnvironment()` - use test environment\n- `WithNotAsyncHandlers()` - allows to run handlers in the main goroutine\n- `WithInitialOffset(offset int64)` - allows to set initial offset for getUpdates method\n\n## Message.Text and CallbackQuery.Data handlers\n\nFor your convenience, you can use `Message.Text`, `CallbackQuery.Data` and `Message.Caption` handlers.\n\nAn example:\n\n```go\nb, err := bot.New(\"YOUR_BOT_TOKEN_FROM_BOTFATHER\")\n\nb.RegisterHandler(bot.HandlerTypeMessageText, \"/start\", bot.MatchTypeExact, myStartHandler)\n\nb.Start(context.TODO())\n```\n\n\u003e also you can use bot init options `WithMessageTextHandler` and `WithCallbackQueryDataHandler`\n\n\nIn this example, the handler will be called when the user sends `/start` message. All other messages will be handled by the default handler.\n\nHandler Types:\n- `HandlerTypeMessageText` - for Update.Message.Text field\n- `HandlerTypeCallbackQueryData` - for Update.CallbackQuery.Data field\n- `HandlerTypeCallbackQueryGameShortName` - for Update.CallbackQuery.GameShortName field\n- `HandlerTypePhotoCaption` - for Update.Message.Caption field\n\nRegisterHandler returns a handler ID string. You can use it to remove the handler later.\n\n```\nb.UnregisterHandler(handlerID)\n```\n\nMatch Types:\n- `MatchTypeExact`\n- `MatchTypePrefix`\n- `MatchTypeContains`\n- `MatchTypeCommand`\n- `MatchTypeCommandStartOnly`\n\n\u003e For `MatchTypeCommand` and `MatchTypeCommandStartOnly` usage see an [example](examples/command_handler/main.go)\n\nYou can use `RegisterHandlerRegexp` to match by regular expression.\n\n```go\nre := regexp.MustCompile(`^/start`)\n\nb.RegisterHandlerRegexp(bot.HandlerTypeMessageText, re, myStartHandler)\n```\n\nIf you want to use custom handler, use `RegisterHandlerMatchFunc`\n\n```go\nmatchFunc := func(update *models.Update) bool {\n\t// your checks\n\treturn true\n}\n\nb.RegisterHandlerMatchFunc(bot.HandlerTypeMessageText, matchFunc, myHandler)\n```\n\n## InputFile\n\nFor some methods, like `SendPhoto`, `SendAudio` etc, you can send file by file path or file contents.\n\nTo send a file by URL or FileID, you can use `\u0026models.InputFileString{Data: string}`:\n\n```go\n// file id of uploaded image\ninputFileData := \"AgACAgIAAxkDAAIBOWJimnCJHQJiJ4P3aasQCPNyo6mlAALDuzEbcD0YSxzjB-vmkZ6BAQADAgADbQADJAQ\"\n// or URL image path\n// inputFileData := \"https://example.com/image.png\"\n\nparams := \u0026bot.SendPhotoParams{\n    ChatID:  chatID,\n    Photo:   \u0026models.InputFileString{Data: inputFileData},\n}\n\nbot.SendPhoto(ctx, params)\n```\n\n[Demo in examples](examples/send_photo/main.go)\n\nTo send an image file by its contents, you can use `\u0026models.InputFileUpload{Filename: string, Data: io.Reader}`:\n\n```go\nfileContent, _ := os.ReadFile(\"/path/to/image.png\")\n\nparams := \u0026bot.SendPhotoParams{\n    ChatID:  chatID,\n    Photo:   \u0026models.InputFileUpload{Filename: \"image.png\", Data: bytes.NewReader(fileContent)},\n}\n\nbot.SendPhoto(ctx, params)\n```\n\n[Demo in examples](examples/send_photo_upload/main.go)\n\n## InputMedia\n\nFor methods like `SendMediaGroup` or `EditMessageMedia` you can send media by file path or file contents.\n\n[Official documentation InputMedia](https://core.telegram.org/bots/api#inputmedia)\n\n\u003e 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://\u003cfile_attach_name\u003e” to upload a new one using multipart/form-data under \u003cfile_attach_name\u003e name.\n\nIf you want to use `attach://` format, you should to define `MediaAttachment` field with file content reader.\n\n```go\nfileContent, _ := os.ReadFile(\"/path/to/image.png\")\n\nmedia1 := \u0026models.InputMediaPhoto{\n\tMedia: \"https://telegram.org/img/t_logo.png\",\n}\n\nmedia2 := \u0026models.InputMediaPhoto{\n\tMedia: \"attach://image.png\",\n\tCaption: \"2\",\n\tMediaAttachment: bytes.NewReader(fileContent),\n}\n\nparams := \u0026bot.SendMediaGroupParams{\n    ChatID: update.Message.Chat.ID,\n    Media: []models.InputMedia{\n        media1,\n        media2,\n    },\n}\n\nbot.SendMediaGroup(ctx, params)\n```\n\n[Demo in examples](examples/send_media_group/main.go)\n\n## InputSticker\n\nFor `CreateNewStickerSet` method you can send sticker by file path or file contents.\n\n[Official documentation InputSticker]((https://core.telegram.org/bots/api#inputsticker)\n\n\u003e field `sticker`: The added sticker. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or pass “attach://\u003cfile_attach_name\u003e” to upload a new file using multipart/form-data under \u003cfile_attach_name\u003e name. Animated and video stickers can't be uploaded via HTTP URL.\n\nIf you want to use `attach://` format, you should to define `StickerAttachment` field with file content reader.\n\n```go\nfileContent, _ := os.ReadFile(\"/path/to/telegram.png\")\n\ninputSticker1 := models.InputSticker{\n\tSticker:   \"https://github.com/go-telegram/bot/blob/main/examples/create_new_sticker_set/images/telegram.png?raw=true\",\n\tFormat:    \"static\",\n\tEmojiList: []string{\"1️⃣\"},\n}\n\ninputSticker2 := models.InputSticker{\n\tSticker:           \"attach://telegram.png\",\n\tFormat:            \"static\",\n\tEmojiList:         []string{\"2️⃣\"},\n\tStickerAttachment: bytes.NewReader(fileContent),\n}\n\nparams := \u0026bot.CreateNewStickerSetParams{\n\tUserID: update.Message.Chat.ID,\n\tName:   fmt.Sprintf(\"Example%d_by_%s\", time.Now().Unix(), botUsername),\n\tTitle:  \"Example sticker set\",\n\tStickers: []models.InputSticker{\n\t\tinputSticker1,\n\t\tinputSticker2,\n\t},\n}\n\nb.CreateNewStickerSet(ctx, params)\n```\n\n[Demo in examples](examples/create_new_sticker_set/main.go)\n\n## Helpers\n\n### `EscapeMarkdown(s string) string`\n\nEscape special symbols for Telegram MarkdownV2 syntax\n\n### `EscapeMarkdownUnescaped(s string) string`\n\nEscape only unescaped special symbols for Telegram MarkdownV2 syntax\n\n### `RandomString(n int) string`\n\nReturns fast random a-zA-Z string with n length\n\n### `True() bool`, `False() bool`\n\nAllows you to define `*bool` values for params, which require `*bool`, like `SendPollParams`\n\n```go\np := \u0026bot.SendPollParams{\n    ChatID: chatID,\n    Question: \"Question\",\n    Options: []string{\"Option 1\", \"Option 2\"},\n    IsAnonymous: bot.False(),\n}\n\nb.SendPoll(ctx, p)\n```\n\n### `ValidateWebappRequest(values url.Values, token string) (user *WebAppUser, ok bool)`\n\nValidate request from Telegram Webapp\n\nhttps://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app\n\n```go\n// get url values from request\nvalues := req.URL.Query()\n\nuser, ok := bot.ValidateWebappRequest(values, os.Getenv(\"TELEGRAM_BOT_TOKEN\"))\nif !ok {\n    http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n    return\n}\n```\n\n### `FileDownloadLink(f *models.File) string`\n\nReturn file download link after call method `GetFile`\n\nSee [documentation](https://core.telegram.org/bots/api#getfile)\n\n## Errors\n\nThis library includes error handling. It provides the following error types:\n\n- **ErrorForbidden (403):** This error occurs when the bot has no access to the action, such as when the user has blocked the bot.\n- **ErrorBadRequest (400):** This error indicates a bad request made to the bot's API.\n- **ErrorUnauthorized (401):** This error occurs when the bot's access is unauthorized for the requested action.\n- **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.\n- **ErrorNotFound (404):** This error indicates that the requested resource was not found.\n- **ErrorConflict (409):** This error indicates a conflict occurred during the request.\n\nUsage:\n```go\n_, err := b.SendMessage(...)\n\nif errors.Is(err, mybot.ErrorForbidden) {\n    // Handle the ErrorForbidden (403) case here\n}\n\nif errors.Is(err, mybot.ErrorBadRequest) {\n    // Handle the ErrorBadRequest (400) case here\n}\n\nif errors.Is(err, mybot.ErrorUnauthorized) {\n    // Handle the ErrorUnauthorized (401) case here\n}\n\nif mybot.IsTooManyRequestsError(err) {\n    // Handle the TooManyRequestsError (429) case here\n    fmt.Println(\"Received TooManyRequestsError with retry_after:\", err.(*mybot.TooManyRequestsError).RetryAfter)\n}\n\nif errors.Is(err, mybot.ErrorNotFound) {\n    // Handle the ErrorNotFound (404) case here\n}\n\nif errors.Is(err, mybot.ErrorConflict) {\n    // Handle the ErrorConflict (409) case here\n}\n```\n\n## Other\n\n- `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 is `110201543`. If the bot token is invalid, the bot ID will be 0.\n- `bot.Token() string` - returns bot token\n- `bot.SetToken()` - set new bot token\n\n## MiniApp misc\n\nCheck the repo [go-telegram/miniapp](https://github.com/go-telegram/miniapp) for Telegram MiniApp example.\n\nRepo [go-telegram/miniapp-types](https://github.com/go-telegram/miniapp-types) contains TypeScript types definitions for Telegram MiniApp object.\n\n## UI Components\n\nIn the repo https://github.com/go-telegram/ui you can find a some UI elements for your bot.\n\n- datepicker\n- inline_keyboard\n- slider\n- paginator\n\nand more...\n\nPlease, check the repo for more information and live demo.\n","funding_links":[],"categories":["Bot Building","Bot建设","聊天机器人框架","Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-telegram%2Fbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-telegram%2Fbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-telegram%2Fbot/lists"}