{"id":13409404,"url":"https://github.com/zhulik/margelet","last_synced_at":"2026-01-12T00:37:38.205Z","repository":{"id":44465757,"uuid":"46615496","full_name":"zhulik/margelet","owner":"zhulik","description":"Telegram Bot Framework for Go","archived":false,"fork":false,"pushed_at":"2022-09-16T19:05:24.000Z","size":132,"stargazers_count":83,"open_issues_count":2,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-07-31T20:36:23.899Z","etag":null,"topics":[],"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/zhulik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-21T13:02:17.000Z","updated_at":"2024-06-13T19:06:25.000Z","dependencies_parsed_at":"2023-01-18T11:17:33.482Z","dependency_job_id":null,"html_url":"https://github.com/zhulik/margelet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zhulik/margelet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhulik%2Fmargelet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhulik%2Fmargelet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhulik%2Fmargelet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhulik%2Fmargelet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhulik","download_url":"https://codeload.github.com/zhulik/margelet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhulik%2Fmargelet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28329806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"ssl_error","status_checked_at":"2026-01-12T00:36:15.229Z","response_time":60,"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":[],"created_at":"2024-07-30T20:01:00.513Z","updated_at":"2026-01-12T00:37:38.190Z","avatar_url":"https://github.com/zhulik.png","language":"Go","funding_links":[],"categories":["Bot Building","Bot建设","Miscellaneous","机器人相关` 构建和使用机器人的库`","Uncategorized","杂项","其他","雜項","机器人相关","\u003cspan id=\"其他-miscellaneous\"\u003e其他 Miscellaneous\u003c/span\u003e"],"sub_categories":["Advanced Console UIs","Contents","Free e-books","高级控制台界面","交流","高級控制台界面","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"readme":"[![Build Status](https://travis-ci.org/zhulik/margelet.svg?branch=master)](https://travis-ci.org/zhulik/margelet)\n# Margelet\nTelegram Bot Framework for Go is based on [telegram-bot-api](https://gopkg.in/telegram-bot-api.v4)\n\nIt uses Redis to store it's states, configs and so on.\n\nAny low-level interactions with Telegram Bot API(downloading files, keyboards and so on) should be performed through\n[telegram-bot-api](https://gopkg.in/telegram-bot-api.v4).\n\nMargelet is just a thin layer, that allows you to solve\nbasic bot tasks quickly and easy.\n\n## Installation\n`go get github.com/zhulik/margelet`\n\n## Simple usage\n```go\npackage main\n\nimport (\n\t\"github.com/zhulik/margelet\"\n)\n\nfunc main() {\n\tbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\terr = bot.Run()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n\nOut of the box, margelet supports only `/help` command, it responds something like this\n\n`/help - Show bot help`\n\n## Concept\nMargelet is based on some concepts:\n* Message handlers\n* Command handlers\n* Session handlers\n* Chat configs\n* Inline handlers\n\n### Message handlers\nMessage handler is a struct that implements Handler interface. It receives all chat messages dependant on bot's\n[Privacy mode](https://core.telegram.org/bots#privacy-mode). It doesn't receive commands.\n\nSimple example:\n```go\npackage margelet_test\n\nimport (\n\t\"../margelet\"\n)\n\n// EchoHandler is simple handler example\ntype EchoHandler struct {\n}\n\n// Response send message back to author\nfunc (handler EchoHandler) HandleMessage(m margelet.Message) error {\n\t_, err := m.QuickSend(m.Message().Text)\n\treturn err\n}\n\n```\n\nThis handler will repeat any user's message back to chat.\n\nMessage helpers can be added to margelet with `AddMessageHandler` function:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\nbot.AddMessageHandler(EchoHandler{})\nbot.Run()\n```\n\n### Command handlers\nCommand handler is struct that implements CommandHandler interface. CommandHandler can be subscribed on any command you need\nand will receive all message messages with this command, only if there is no active session with this user in this chat\n\nSimple example:\n```go\npackage margelet\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// HelpHandler Default handler for /help command. Margelet will add this automatically\ntype HelpHandler struct {\n\tMargelet *Margelet\n}\n\n// HandleCommand sends default help message\nfunc (handler HelpHandler) HandleCommand(message Message) error {\n\tlines := []string{}\n\tfor command, h := range handler.Margelet.CommandHandlers {\n\t\tlines = append(lines, fmt.Sprintf(\"/%s - %s\", command, h.handler.HelpMessage()))\n\t}\n\n\tfor command, h := range handler.Margelet.SessionHandlers {\n\t\tlines = append(lines, fmt.Sprintf(\"/%s - %s\", command, h.handler.HelpMessage()))\n\t}\n\n\t_, err := message.QuickSend(strings.Join(lines, \"\\n\"))\n\treturn err\n}\n\n// HelpMessage return help string for HelpHandler\nfunc (handler HelpHandler) HelpMessage() string {\n\treturn \"Show bot help\"\n}\n```\n\nCommand handlers can be added to margelet with `AddCommandHandler` function:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\nbot.AddCommandHandler(\"help\", HelpHandler{bot})\nbot.Run()\n```\n\n### Session handlers\nSession here is an interactive dialog with user, like [@BotFather](https://telegram.me/botfather) does. User runs session\nwith a command and then response to bot's questions until bot collects all needed information. It can be used for bot\nconfiguration, for example.\n\n**Session handlers API is still developing**\n\nSession handler is struct that implements SessionHandler interface. Simple example:\n```go\npackage margelet_test\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"../margelet\"\n\t\"gopkg.in/telegram-bot-api.v4\"\n)\n\n// SumSession - simple example session, that can sum numbers\ntype SumSession struct {\n}\n\n// HandleResponse - Handlers user response\nfunc (s SumSession) HandleSession(session margelet.Session) error {\n\tswitch len(session.Responses()) {\n\tcase 0:\n\t\tsession.QuickReply(\"Hello, please, write one number per message, after some iterations write 'end'.\")\n\tdefault:\n\t\tif session.Message().Text == \"end\" {\n\t\t\tvar sum int\n\t\t\tfor _, m := range session.Responses() {\n\t\t\t\tn, _ := strconv.Atoi(m.Text)\n\t\t\t\tsum += n\n\t\t\t}\n\t\t\tsession.QuickReply(fmt.Sprintf(\"Your sum: %d\", sum))\n\t\t\tsession.Finish()\n\t\t\treturn nil\n\t\t}\n\n\t\t_, err := strconv.Atoi(session.Message().Text)\n\t\tif err != nil {\n\t\t\tsession.QuickReply(\"Sorry, not a number\")\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CancelResponse - Chance to clean up everything\nfunc (s SumSession) CancelSession(session margelet.Session) {\n\t//Clean up all variables only used in the session\n\n}\n\nfunc (session SumSession) response(bot margelet.MargeletAPI, message *tgbotapi.Message, msg tgbotapi.MessageConfig) {\n\tmsg.ChatID = message.Chat.ID\n\tmsg.ReplyToMessageID = message.MessageID\n\tmsg.ReplyMarkup = tgbotapi.ForceReply{ForceReply: true, Selective: true}\n\tbot.Send(msg)\n}\n\n// HelpMessage return help string for SumSession\nfunc (session SumSession) HelpMessage() string {\n\treturn \"Sum your numbers and print result\"\n}\n```\n\nSession handlers can be added to margelet with `AddSessionHandler` function:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\nbot.AddSessionHandler(\"help\", SumSession{})\nbot.Run()\n```\n\nOn each user response it receives all previous user responses, so you can restore session state. HandleResponse return values\nit important:\n* first(bool), means that margelet should finish session, so return true if you receive all needed info from user, false otherwise\n* second(err), means that bot cannot handle user's message. This message will not be added to session dialog history.\nReturn any error if you can handle user's message and return nil if message is accepted.\n\n### Inline handlers\nInline handler is struct that implements InlineHandler interface. InlineHandler can be subscribed on any inline queries.\n\nSimple example:\n```go\npackage margelet_test\n\nimport (\n\t\"github.com/zhulik/margelet\"\n\t\"gopkg.in/telegram-bot-api.v4\"\n)\n\ntype InlineImage struct {\n}\n\nfunc (handler InlineImage) HandleInline(bot margelet.MargeletAPI, query *tgbotapi.InlineQuery) error {\n\ttestPhotoQuery := tgbotapi.NewInlineQueryResultPhoto(query.ID, \"https://telegram.org/img/t_logo.png\")\n\ttestPhotoQuery.ThumbURL = \"https://telegram.org/img/t_logo.png\"\n\n\tconfig := tgbotapi.InlineConfig{\n\t\tInlineQueryID: query.ID,\n\t\tCacheTime:     2,\n\t\tIsPersonal:    false,\n\t\tResults:       []interface{}{testPhotoQuery},\n\t\tNextOffset:    \"\",\n\t}\n\n\tbot.AnswerInlineQuery(config)\n\treturn nil\n}\n```\n\nInline handler can be added to margelet by `InlineHandler` assignment:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\nm.InlineHandler = \u0026InlineImage{}\nbot.Run()\n```\n\n### Callback handlers\nCallback handler is struct that implements CallbackHandler interface. CallbackHandler can be subscribed on any callback queries.\n\nSimple example:\n```go\npackage margelet_test\n\nimport (\n\t\"../margelet\"\n\t\"gopkg.in/telegram-bot-api.v4\"\n)\n\ntype CallbackMessage struct {\n}\n\nfunc (handler CallbackMessage) HandleCallback(query margelet.CallbackQuery) error {\n\tconfig := tgbotapi.CallbackConfig{\n\t\tCallbackQueryID: query.Query().ID,\n\t\tText:            \"Done!\",\n\t\tShowAlert:       false,\n\t}\n\n\tquery.Bot().AnswerCallbackQuery(config)\n\treturn nil\n}\n```\n\nCallback handler can be added to margelet by `CallbackHandler` assignment:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\nm.CallbackHandler = \u0026CallbackMessage{}\nbot.Run()\n```\n\n### Chat configs\nBots can store any config string(you can use serialized JSON) for any chat. It can be used for storing user's\nconfigurations and other user-related information. Simple example:\n```go\nbot, err := margelet.NewMargelet(\"\u003cyour awesome bot name\u003e\", \"\u003credis addr\u003e\", \"\u003credis password\u003e\", 0, \"your bot token\", false)\n...\nbot.GetConfigRepository().Set(\u003cchatID\u003e, \"\u003cinfo\u003e\")\n...\ninfo := bot.GetConfigRepository().Get(\u003cchatID\u003e)\n\nOR\n\ntype userInfo struct{\n  FavColor string // First character has to be Capital otherwise it wont be saved\n}\n...\nuser := userInfo{FavColor: \"Green\"}\nbot.GetConfigRepository().SetWithStruct(\u003cchatID\u003e, user)\n...\nvar user userInfo\nbot.GetConfigRepository().GetWithStruct(\u003cchatID\u003e, \u0026user)\n```\nChat config repository can be accessed from session handlers.\n\n## Example project\nSimple and clean example project can be found [here](https://github.com/zhulik/cat_bot). It provides command handling\nand session configuration.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhulik%2Fmargelet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhulik%2Fmargelet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhulik%2Fmargelet/lists"}