{"id":13409217,"url":"https://github.com/NicoNex/echotron","last_synced_at":"2025-03-14T14:31:11.778Z","repository":{"id":37207516,"uuid":"198272085","full_name":"NicoNex/echotron","owner":"NicoNex","description":"An elegant and concurrent library for the Telegram bot API in Go.","archived":false,"fork":false,"pushed_at":"2024-10-16T18:51:27.000Z","size":35738,"stargazers_count":368,"open_issues_count":0,"forks_count":26,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-18T09:58:02.239Z","etag":null,"topics":["awesome-go","bot","go","golang","golang-library","library","telegram","telegram-api","telegram-bot","telegram-bot-api"],"latest_commit_sha":null,"homepage":"https://t.me/s/echotronnews","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NicoNex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING.LESSER","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":"2019-07-22T17:31:49.000Z","updated_at":"2024-10-16T18:51:31.000Z","dependencies_parsed_at":"2023-02-19T03:15:29.786Z","dependency_job_id":"bd7f6645-05fa-4b5f-84bc-0009f23d45d7","html_url":"https://github.com/NicoNex/echotron","commit_stats":null,"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicoNex%2Fechotron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicoNex%2Fechotron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicoNex%2Fechotron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NicoNex%2Fechotron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NicoNex","download_url":"https://codeload.github.com/NicoNex/echotron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243593330,"owners_count":20316168,"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":["awesome-go","bot","go","golang","golang-library","library","telegram","telegram-api","telegram-bot","telegram-bot-api"],"created_at":"2024-07-30T20:00:58.944Z","updated_at":"2025-03-14T14:31:06.755Z","avatar_url":"https://github.com/NicoNex.png","language":"Go","readme":"| \u003cimg src=\"assets/readme_banner.png\" alt=\"logo\" width=\"800\"\u003e\u003cbr/\u003e\u003cbr/\u003e [![Language](https://img.shields.io/badge/Language-Go-blue.svg)](https://golang.org/) [![PkgGoDev](https://pkg.go.dev/badge/github.com/NicoNex/echotron/v3)](https://pkg.go.dev/github.com/NicoNex/echotron/v3) [![Go Report Card](https://goreportcard.com/badge/github.com/NicoNex/echotron/v3)](https://goreportcard.com/report/github.com/NicoNex/echotron/v3) [![codecov](https://codecov.io/gh/NicoNex/echotron/graph/badge.svg?token=LVJGOEYL5M)](https://codecov.io/gh/NicoNex/echotron) [![License](http://img.shields.io/badge/license-LGPL3.0-orange.svg?style=flat)](https://github.com/NicoNex/echotron/blob/master/LICENSE) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) [![Telegram](https://img.shields.io/badge/Echotron%20News-blue?logo=telegram\u0026style=flat)](https://t.me/echotronnews) |\n| :------: |\n\n**Echotron** is an elegant and concurrent library for the Telegram bot API in Go.\n\nFetch with\n\n```bash\ngo get github.com/NicoNex/echotron/v3\n```\n\n## Example\n### Simplest implementations\n#### Long polling\n```golang\npackage main\n\nimport \"github.com/NicoNex/echotron/v3\"\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nfunc main() {\n\tapi := echotron.NewAPI(token)\n\n\tfor u := range echotron.PollingUpdates(token) {\n\t\tif u.Message.Text == \"/start\" {\n\t\t\tapi.SendMessage(\"Hello world\", u.ChatID(), nil)\n\t\t}\n\t}\n}\n```\n#### Webhook\n```golang\npackage main\n\nimport \"github.com/NicoNex/echotron/v3\"\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nfunc main() {\n\tapi := echotron.NewAPI(token)\n\n\tfor u := range echotron.WebhookUpdates(\"https://example.com:443/my_token\", token) {\n\t\tif u.Message.Text == \"/start\" {\n\t\t\tapi.SendMessage(\"Hello world\", u.ChatID(), nil)\n\t\t}\n\t}\n}\n```\nFor more scalable and recommended implementations see the other examples.\n\n### Long Polling\n\n```golang\npackage main\n\nimport (\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/NicoNex/echotron/v3\"\n)\n\n// Struct useful for managing internal states in your bot, but it could be of\n// any type such as `type bot int64` if you only need to store the chatID.\ntype bot struct {\n\tchatID int64\n\techotron.API\n}\n\nconst token = \"MY TELEGRAM TOKEN\"\n\n// This function needs to be of type 'echotron.NewBotFn' and is called by\n// the echotron dispatcher upon any new message from a chatID that has never\n// interacted with the bot before.\n// This means that echotron keeps one instance of the echotron.Bot implementation\n// for each chat where the bot is used.\nfunc newBot(chatID int64) echotron.Bot {\n\treturn \u0026bot{\n\t\tchatID,\n\t\techotron.NewAPI(token),\n\t}\n}\n\n// This method is needed to implement the echotron.Bot interface.\nfunc (b *bot) Update(update *echotron.Update) {\n\tif update.Message.Text == \"/start\" {\n\t\tb.SendMessage(\"Hello world\", b.chatID, nil)\n\t}\n}\n\nfunc main() {\n\t// This is the entry point of echotron library.\n\tdsp := echotron.NewDispatcher(token, newBot)\n\tfor {\n\t\tlog.Println(dsp.Poll())\n\t\t// In case of connection issues wait 5 seconds before trying to reconnect.\n\t\ttime.Sleep(5 * time.Second)\n\t}\n}\n```\n\n## Design\n\n**Echotron** makes a new instance of the struct bot for each open chat with a Telegram user, channel or group.\nThis allows to:\n- safely call the `Update(*echotron.Update)` method concurrently\n- give to the user a convenient way to manage the bot internal states across all the chats\n- make sure that, even if one instance of the bot is deadlocked, the other ones keep running just fine, making the bot work for other users without any issues and/or slowdowns.\n\nPlease note that the the aforementioned behaviour is dictated by the `echotron.Dispatcher` object whose usage is not mandatory and for special needs can be ignored and implemented in different ways still keeping all the methods in the `echotron.API` object.\n\n**Echotron** is designed to be as similar to the official [Telegram API](https://core.telegram.org/bots/api) as possible, but there are some things to take into account before starting to work with this library.\n\n- The methods have the exact same name, but with a capital first letter, since in Go methods have to start with a capital letter to be exported.\n_Example: `sendMessage` becomes `SendMessage`_\n- The order of the parameters in some methods is different than in the official Telegram API, so refer to the [docs](https://pkg.go.dev/github.com/NicoNex/echotron/v3) for the correct one.\n- The only `chat_id` (or, in this case, `chatID`) type supported is `int64`, instead of the \"Integer or String\" requirement of the official API. That's because numeric IDs can't change in any way, which isn't the case with text-based usernames.\n- In some methods, you might find a `InputFile` type parameter. [`InputFile`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#InputFile) is a struct with unexported fields, since only three combination of fields are valid, which can be obtained through the methods [`NewInputFileID`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#NewInputFileID), [`NewInputFilePath`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#NewInputFilePath) and [`NewInputFileBytes`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#NewInputFileBytes).\n- In some methods, you might find a `MessageIDOptions` type parameter. [`MessageIDOptions`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#MessageIDOptions) is another struct with unexported fields, since only two combination of field are valid, which can be obtained through the methods [`NewMessageID`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#NewMessageID) and [`NewInlineMessageID`](https://pkg.go.dev/github.com/NicoNex/echotron/v3#NewInlineMessageID).\n- Optional parameters can be added by passing the correct struct to each method that might request optional parameters. If you don't want to pass any optional parameter, `nil` is more than enough. Refer to the [docs](https://pkg.go.dev/github.com/NicoNex/echotron/v3) to check for each method's optional parameters struct: it's the type of the `opts` parameter.\n- Some parameters are hardcoded to avoid putting random stuff which isn't recognized by the Telegram API. Some notable examples are [`ParseMode`](https://github.com/NicoNex/echotron/blob/master/options.go#L21), [`ChatAction`](https://github.com/NicoNex/echotron/blob/master/options.go#L54) and [`InlineQueryType`](https://github.com/NicoNex/echotron/blob/master/inline.go#L27). For a full list of custom hardcoded parameters, refer to the [docs](https://pkg.go.dev/github.com/NicoNex/echotron/v3) for each custom type: by clicking on the type's name, you'll get the source which contains the possible values for that type.\n\n## Additional examples\n### Functional approach to state management\n```golang\npackage main\n\nimport (\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/NicoNex/echotron/v3\"\n)\n\n// Recursive type definition of the bot state function.\ntype stateFn func(*echotron.Update) stateFn\n\ntype bot struct {\n\tchatID int64\n\tstate  stateFn\n\tname   string\n\techotron.API\n}\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nfunc newBot(chatID int64) echotron.Bot {\n\tbot := \u0026bot{\n\t\tchatID: chatID,\n\t\tAPI:\techotron.NewAPI(token),\n\t}\n\t// We set the default state to the bot.handleMessage method.\n\tbot.state = bot.handleMessage\n\treturn bot\n}\n\nfunc (b *bot) Update(update *echotron.Update) {\n\t// Here we execute the current state and set the next one.\n\tb.state = b.state(update)\n}\n\nfunc (b *bot) handleMessage(update *echotron.Update) stateFn {\n\tif strings.HasPrefix(update.Message.Text, \"/set_name\") {\n\t\tb.SendMessage(\"Send me my new name!\", b.chatID, nil)\n\t\t// Here we return b.handleName since next time we receive a message it\n\t\t// will be the new name.\n\t\treturn b.handleName\n\t}\n\treturn b.handleMessage\n}\n\nfunc (b *bot) handleName(update *echotron.Update) stateFn {\n\tb.name = update.Message.Text\n\tb.SendMessage(fmt.Sprintf(\"My new name is %q\", b.name), b.chatID, nil)\n\t// Here we return b.handleMessage since the next time we receive a message\n\t// it will be handled in the default way.\n\treturn b.handleMessage\n}\n\nfunc main() {\n\tdsp := echotron.NewDispatcher(token, newBot)\n\tlog.Println(dsp.Poll())\n}\n```\n\n### Self destruction for lower memory footprint\n```golang\npackage main\n\nimport (\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/NicoNex/echotron/v3\"\n)\n\ntype bot struct {\n\tchatID int64\n\techotron.API\n}\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nvar dsp *echotron.Dispatcher\n\nfunc newBot(chatID int64) echotron.Bot {\n\tbot := \u0026bot{\n\t\tchatID,\n\t\techotron.NewAPI(token),\n\t}\n\tgo bot.selfDestruct(time.After(time.Hour))\n\treturn bot\n}\n\nfunc (b *bot) selfDestruct(timech \u003c-chan time.Time) {\n\t\u003c-timech\n\tb.SendMessage(\"goodbye\", b.chatID, nil)\n\tdsp.DelSession(b.chatID)\n}\n\nfunc (b *bot) Update(update *echotron.Update) {\n\tif update.Message.Text == \"/start\" {\n\t\tb.SendMessage(\"Hello world\", b.chatID, nil)\n\t}\n}\n\nfunc main() {\n\tdsp = echotron.NewDispatcher(token, newBot)\n\tlog.Println(dsp.Poll())\n}\n```\n\n### Webhook\n\n```golang\npackage main\n\nimport \"github.com/NicoNex/echotron/v3\"\n\ntype bot struct {\n\tchatID int64\n\techotron.API\n}\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nfunc newBot(chatID int64) echotron.Bot {\n\treturn \u0026bot{\n\t\tchatID,\n\t\techotron.NewAPI(token),\n\t}\n}\n\nfunc (b *bot) Update(update *echotron.Update) {\n\tif update.Message.Text == \"/start\" {\n\t\tb.SendMessage(\"Hello world\", b.chatID, nil)\n\t}\n}\n\nfunc main() {\n\tdsp := echotron.NewDispatcher(token, newBot)\n\tdsp.ListenWebhook(\"https://example.com:443/my_bot_token\")\n}\n```\n\n\n### Webhook with a custom http.Server\n\nThis is an example for a custom http.Server which handles your own specified routes\nand also the webhook route which is specified by ListenWebhook.\n\n```golang\npackage main\n\nimport (\n\t\"github.com/NicoNex/echotron/v3\"\n\n\t\"context\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\ntype bot struct {\n\tchatID int64\n\techotron.API\n}\n\nconst token = \"MY TELEGRAM TOKEN\"\n\nfunc newBot(chatID int64) echotron.Bot {\n\treturn \u0026bot{\n\t\tchatID,\n\t\techotron.NewAPI(token),\n\t}\n}\n\nfunc (b *bot) Update(update *echotron.Update) {\n\tif update.Message.Text == \"/start\" {\n\t\tb.SendMessage(\"Hello world\", b.chatID, nil)\n\t}\n}\n\nfunc main() {\n\ttermChan := make(chan os.Signal, 1) // Channel for terminating the app via os.Interrupt signal\n\tsignal.Notify(termChan, syscall.SIGINT, syscall.SIGTERM)\n\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/login\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Handle user login\n\t})\n\tmux.HandleFunc(\"/logout\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Handle user logout\n\t})\n\tmux.HandleFunc(\"/about\", func(w http.ResponseWriter, r *http.Request) {\n\t\t// Tell something about your awesome telegram bot\n\t})\n\n\t// Set custom http.Server\n\tserver := \u0026http.Server{Addr: \":8080\", Handler: mux}\n\n\tgo func() {\n\t\t\u003c-termChan\n\t\t// Perform some cleanup..\n\t\tif err := server.Shutdown(context.Background()); err != nil {\n\t\t\tlog.Print(err)\n\t\t}\n\t}()\n\n\t// Capture the interrupt signal for app termination handling\n\tdsp := echotron.NewDispatcher(token, newBot)\n\tdsp.SetHTTPServer(server)\n\t// Start your custom http.Server with a registered /my_bot_token handler.\n\tlog.Println(dsp.ListenWebhook(\"https://example.com/my_bot_token\"))\n}\n```\n","funding_links":[],"categories":["Bot Building","Bot建设","Uncategorized","Go"],"sub_categories":["Contents","Free e-books"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNicoNex%2Fechotron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNicoNex%2Fechotron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNicoNex%2Fechotron/lists"}