{"id":26355760,"url":"https://github.com/zelenin/grabot","last_synced_at":"2025-03-16T13:17:44.320Z","repository":{"id":144214295,"uuid":"146141057","full_name":"zelenin/grabot","owner":"zelenin","description":" Go wrapper for Telegram Bot API ","archived":false,"fork":false,"pushed_at":"2019-01-26T07:09:33.000Z","size":41,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-19T06:49:03.353Z","etag":null,"topics":["api","bot","telegram"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zelenin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2018-08-26T01:08:17.000Z","updated_at":"2021-12-10T17:31:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"e6fa29de-82e6-4a1a-9b55-d3e30d0e1ae8","html_url":"https://github.com/zelenin/grabot","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zelenin%2Fgrabot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zelenin%2Fgrabot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zelenin%2Fgrabot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zelenin%2Fgrabot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zelenin","download_url":"https://codeload.github.com/zelenin/grabot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243871913,"owners_count":20361380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","bot","telegram"],"created_at":"2025-03-16T13:17:43.440Z","updated_at":"2025-03-16T13:17:44.297Z","avatar_url":"https://github.com/zelenin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grabot\n\nGo wrapper for [Telegram Bot API](https://core.telegram.org/bots/api) with full support of Bot API 4.1.\n\n## API client\n\n```go\nimport (\n    \"github.com/zelenin/grabot/client\"\n)\n\n...\n\nvar chatId int64 = 12345678\nvar channelName = \"@channelname\"\n\ntoken := \"\u003cbot_token\u003e\"\n\napiClient, _ := client.New(token/*, client.WithStdLogger*/)\n\napiClient.SendMessage(\u0026client.SendMessageRequest{\n    ChatId: client.IntChatId(chatId),\n    Text:   \"Hello. I'm bot.\",\n})\n\nfile, _ := client.NewFileInputFile(\"/path/to/image.jpg\")\n\n// or\n// file := client.NewUrlInputFile(\"https://example.com/path/to/image.jpg\")\n\napiClient.SendPhoto(\u0026client.SendPhotoRequest{\n    ChatId:  client.StringChatId(channelName),\n    Photo:   file,\n    Caption: client.OptionalString(\"Your answer?\"),\n    ReplyMarkup: \u0026client.InlineKeyboardMarkup{\n        InlineKeyboard: [][]client.InlineKeyboardButton{\n            {\n                {Text: \"Variant 1\", Url: client.OptionalString(\"https://example.com/variant/1\")},\n                {Text: \"Variant 2\", Url: client.OptionalString(\"https://example.com/variant/2\")},\n            },\n            {\n                {Text: \"Variant 3\", Url: client.OptionalString(\"https://example.com/variant/3\")},\n                {Text: \"Variant 4\", Url: client.OptionalString(\"https://example.com/variant/4\")},\n            },\n        },\n    },\n})\n```\n\n## Updates\n\n### Webhook\n\n```go\nimport (\n    \"net/http\"\n    \"log\"\n    \"github.com/zelenin/grabot/updates\"\n    \"github.com/zelenin/grabot/client\"\n    \"context\"\n)\n\n...\n\ntoken := \"\u003cbot_token\u003e\"\napiClient, _ := client.New(token/*, client.WithStdLogger*/)\nsetWebhook(apiClient)\n\nwebhookHandler := updates.NewWebhookHandler(func(ctx context.Context, update *client.Update) {\n    log.Printf(\"%#v\", update)\n})\n\nmux := http.NewServeMux()\nmux.HandleFunc(\"/webhook\", webhookHandler.ServeHTTP)\nsrv := \u0026http.Server{\n    Addr:    \":8443\",\n    Handler: mux,\n}\nlog.Fatal(srv.ListenAndServeTLS(\"./server.crt\", \"./server.key\"))\n```\n\n### Long polling\n\n```go\nimport (\n    \"log\"\n    \"context\"\n    \"time\"\n    \"github.com/zelenin/grabot/updates\"\n    \"github.com/zelenin/grabot/client\"\n)\n\n... \n\ntoken := \"\u003cbot_token\u003e\"\n\napiClient, _ := client.New(token/*, client.WithStdLogger*/)\n\nctx, _ := context.WithCancel(context.Background())\n\nlongPoller := updates.NewLongPoller(apiClient)\nupdatesChan, errsChan := longPoller.LongPoll(ctx, \u0026client.GetUpdatesRequest{\n    Offset: client.OptionalInt(0),\n}, 1*time.Second)\n\nfor {\n    select {\n    case update := \u003c-updatesChan:\n        log.Printf(\"%#v\", update)\n    \n    case err := \u003c-errsChan:\n        log.Printf(\"error: %s\", err)\n    }\n}\n```\n\n## Bot\n\n```go\n\nimport (\n    \"github.com/zelenin/grabot/client\"\n    \"github.com/zelenin/grabot/bot\"\n    \"github.com/zelenin/grabot/updates\"\n    \"log\"\n    \"time\"\n    \"context\"\n)\n\ntoken := \"\u003cbot_token\u003e\"\napiClient, _ := client.New(token/*, client.WithStdLogger*/)\n\nrouter := bot.NewRouter()\n\nrouter.AddRoute(bot.NewRoute(bot.BotCommandMatcher(\"/start\"), func(ctx context.Context, update *client.Update, updateHandler updates.UpdateHandler) {\n    log.Printf(\"Handle update #%d [bot command]\", update.UpdateId)\n    \n    updateHandler(ctx, update)\n}))\n\nrouter.AddRoute(bot.NewRoute(bot.HashtagMatcher(\"#hashtag\"), func(ctx context.Context, update *client.Update, updateHandler updates.UpdateHandler) {\n    log.Printf(\"Handle update #%d [hashtag]\", update.UpdateId)\n    \n    updateHandler(ctx, update)\n}))\n\nrouter.AddRoute(bot.NewRoute(bot.MentionMatcher(\"@NameOfTheBot\"), func(ctx context.Context, update *client.Update, updateHandler updates.UpdateHandler) {\n    log.Printf(\"Handle update #%d [mention]\", update.UpdateId)\n    \n    updateHandler(ctx, update)\n}))\n\nrouter.AddRoute(bot.NewRoute(\n    func(update *client.Update) bool {\n        return update.Message != nil \u0026\u0026 update.Message.From != nil \u0026\u0026 *update.Message.From.Username == \"username\"\n    },\n    func(ctx context.Context, update *client.Update, updateHandler updates.UpdateHandler) {\n        log.Printf(\"Handle update #%d [from %s]\", update.UpdateId, *update.Message.From.Username)\n        \n        updateHandler(ctx, update)\n    }, \n))\n\nrouter.AddRoute(bot.NewRoute(bot.MessageMatcher(), func(ctx context.Context, update *client.Update, updateHandler updates.UpdateHandler) {\n    log.Printf(\"Handle update #%d [message #%d]\", update.UpdateId, update.Message.MessageId)\n    \n    updateHandler(ctx, update)\n}))\n\ngrabot := bot.NewBot(apiClient)\n\ngrabot.Add(bot.NewRouteMiddleware(router))\n\nctx, _ := context.WithCancel(context.Background())\n\nlongPoller := updates.NewLongPoller(apiClient)\nupdatesChan, errsChan := longPoller.LongPoll(ctx, \u0026client.GetUpdatesRequest{\n    Offset: client.OptionalInt(0),\n}, 1*time.Second)\n\nfor {\n    select {\n    case update := \u003c-updatesChan:\n        ctx := context.Background()\n        go grabot.Handle(ctx, update)\n        \n    case err := \u003c-errsChan:\n        log.Printf(\"error: %s\", err)\n    }\n}\n```\n\n## Rate limiter\n\n```go\nimport (\n    \"github.com/zelenin/grabot/client\"\n    \"github.com/zelenin/grabot/ratelimiter\"\n)\n\n...\n\nvar chatId int64 = 12345678\n\ntoken := \"\u003cbot_token\u003e\"\napiClient, _ := client.New(token, client.WithStdLogger)\n\nrlimiter := ratelimiter.New()\n\nfor i := 0; i \u003c 100; i++ {\n    rlimiter.AddTask(ratelimiter.NewTask(client.IntChatId(chatId), func() {\n        apiClient.SendMessage(\u0026client.SendMessageRequest{\n            ChatId: client.IntChatId(chatId),\n            Text:   \"Hello. I'm bot.\",\n        })\n    }))\n}\n```\n\n## Author\n\n[Aleksandr Zelenin](https://github.com/zelenin/), e-mail: [aleksandr@zelenin.me](mailto:aleksandr@zelenin.me)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzelenin%2Fgrabot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzelenin%2Fgrabot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzelenin%2Fgrabot/lists"}