{"id":31200614,"url":"https://github.com/telegramupdater/telegramupdater","last_synced_at":"2025-09-20T11:59:49.640Z","repository":{"id":41815886,"uuid":"457298994","full_name":"TelegramUpdater/TelegramUpdater","owner":"TelegramUpdater","description":"Telegram updater is a telegram bot api framework of simplicity.","archived":false,"fork":false,"pushed_at":"2025-07-05T16:28:26.000Z","size":868,"stargazers_count":20,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-01T02:55:32.324Z","etag":null,"topics":["asp-net","bot","csharp","dotnet-core","telegram-bot"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TelegramUpdater.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-09T09:52:10.000Z","updated_at":"2025-07-05T16:25:54.000Z","dependencies_parsed_at":"2025-04-30T21:25:57.045Z","dependency_job_id":"c7eadc6e-b614-484d-ac23-3389fde8e348","html_url":"https://github.com/TelegramUpdater/TelegramUpdater","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/TelegramUpdater/TelegramUpdater","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TelegramUpdater%2FTelegramUpdater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TelegramUpdater%2FTelegramUpdater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TelegramUpdater%2FTelegramUpdater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TelegramUpdater%2FTelegramUpdater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TelegramUpdater","download_url":"https://codeload.github.com/TelegramUpdater/TelegramUpdater/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TelegramUpdater%2FTelegramUpdater/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276092023,"owners_count":25583699,"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","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["asp-net","bot","csharp","dotnet-core","telegram-bot"],"created_at":"2025-09-20T11:59:47.609Z","updated_at":"2025-09-20T11:59:49.634Z","avatar_url":"https://github.com/TelegramUpdater.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TelegramUpdater (Preview)\n\n[![Nuget Version](https://img.shields.io/nuget/v/TelegramUpdater?logo=#00485B)](https://www.nuget.org/packages/TelegramUpdater/)\n[![Nuget Downloads](https://img.shields.io/nuget/dt/TelegramUpdater)](https://www.nuget.org/packages/TelegramUpdater/)\n[![Docs](https://img.shields.io/badge/Docs-Docfx-purple)](https://telegramupdater.github.io/TelegramUpdater)\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/TelegramUpdater/TelegramUpdater)\n\nTelegramUpdater is feature-rich super customizable framework library for building telegram bots in c#.\n\n## Features\n\n- Telegram updater manages update handling process from receiving updates to\nqueuing them filtering them, answering them, handling exceptions, managing state and more ...\n- Updater ensures that only a limited number of updates are begin processed in parallel,\nand if the user id can be figured out, the updates are processed in sequence per each user.\n- Benefiting from queuing the incoming updates, you can have access to the future by `ReadNext`.\n- Singleton and Scoped handlers which can enable you to use DI and scoped services.\n- Rich filter system by allowing to combine filters or applying them as attributes.\n- Containers with access to a lot of resources like `Update` and inner update, `Updater` itself and more. This can enable you to have,\nuse or create a lot of extension methods on them.\n- Update channels can make a channel from your current handler to the updating pipeline and fetch\nfuture updates, like waiting for text input right inside the handler.\n- Handling exceptions whiling filtering them by type or message.\n- Hosting support as mentioned before, to have access to DI and webhook.\n- Managing state and integrating them with filters and container's extension methods.\n- Many helper (extension) methods and types. \n- Super abstraction over any thing! You can create your own filter, handler, container, update channels, extension methods and even update writers.\n\n## Getting Started\n\nLet's get started with this package and learn how to implement some of above\nfeatures.\n\n## Installation\n\nThe package is available inside\n[Nuget](https://www.nuget.org/packages/TelegramUpdater/).\n\nTelegramUpdater uses\n[Telegram.Bot: .NET Client for Telegram Bot API](https://github.com/TelegramBots/Telegram.Bot)\npackage as an C# wrapper over Telegram bot api.\n\n### Documentations\n\nDocumentations can be found at [Here](https://telegramupdater.github.io/TelegramUpdater).\n\n### Code sample\n\n#### Console app\n\nA very minimal yet working example of TelegramUpdater usage is something like this.\n\n```csharp\nusing TelegramUpdater;\nusing TelegramUpdater.UpdateContainer;\nusing TelegramUpdater.UpdateContainer.UpdateContainers;\n\nvar updater = new Updater(\"YOUR_BOT_TOKEN\")\n    .AddDefaultExceptionHandler()\n    .QuickStartCommandReply(\"Hello there!\");\n\nawait updater.Start();\n```\n\nThis setups `Updater` with your bot token, adds a default exception handler that logs errors,\na (singleton) update handler that works on `/start` command on private chats\nand finally starts up the updater.\n\nUpdater can automatically collect your handlers as statics methods like example below\n\n```csharp\nvar updater = new Updater(\"YOUR_BOT_TOKEN\")\n    .AddDefaultExceptionHandler()\n    .CollectHandlingCallbacks();\n\nawait updater.Start();\n\npartial class Program\n{\n    [Command(\"start\"), Private]\n    [HandlerCallback(UpdateType.Message)]\n    public static async Task Start(IContainer\u003cMessage\u003e container)\n    {\n        await container.Response(\"Hello World\");\n    }\n}\n```\n\nThis should work the same as before. (Filters are applied as attributes)\n\n\u003e [!WARNING]\n\u003e If you add scoped handlers but your `Updater` without having access to the DI (`IServiceProvider`), the updater will still try to make an instance of you scoped handler\n\u003e if its filters passes, by its parameterless constructor.\n\n#### Worker service\n\nIf your project is a worker service or anything that has HostBuilder and DI (dependency injection)\nin it, you can setup updater like this.\n\n```csharp\nvar builder = Host.CreateApplicationBuilder(args);\n\n// this will collect updater options like BotToken, AllowedUpdates and ...\n// from configuration section \"TelegramUpdater\". in this example from appsettings.json\nbuilder.AddTelegramUpdater(\n    (builder) =\u003e builder\n        // Modify the actual updater\n        .Execute(updater =\u003e updater\n            // Collects static methods marked with `HandlerCallback` attribute.\n            .CollectHandlingCallbacks())\n        // Collect scoped handlers located for example at UpdateHandlers/Messages for messages.\n        .CollectHandlers()\n        .AddDefaultExceptionHandler());\n\nvar host = builder.Build();\nawait host.RunAsync();\n```\n\nThe configuration are automatically figured out if they're exists somewhere like in `appsettings.json`.\nYou can add them like this:\n\n```json\n{\n  \n  ...\n\n  \"TelegramUpdater\": {\n    \"BotToken\": \"\",\n    \"AllowedUpdates\": [ \"Message\", \"CallbackQuery\" ]\n  },\n  \n  ...\n}\n```\n\u003e [!NOTE]\n\u003e Updater can and will figure out `AllowedUpdates` if not specified by looking\n\u003e into you registered handlers.\n\nFor singleton handlers it's just like before, but if your going to use scoped handlers,\nput them into the right place as mentioned in the example.\n\nFor example create a file at `UpdateHandlers/Messages` like `UpdateHandlers/Messages/Start.cs`\n\nThe `Start.cs` should look like this:\n\n```csharp\nusing TelegramUpdater.FilterAttributes.Attributes;\nusing TelegramUpdater.UpdateContainer;\nusing TelegramUpdater.UpdateContainer.UpdateContainers;\nusing TelegramUpdater.UpdateHandlers.Scoped.ReadyToUse;\n\nnamespace GettingStarted.UpdateHandlers.Messages;\n\n[Command(\"start\"), Private]\ninternal class Start : MessageHandler\n{\n    protected override async Task HandleAsync(MessageContainer container)\n    {\n        await container.Response(\"Hello World\");\n    }\n}\n```\n\nWatch out for name space where the `MessageHandler` came from, it must be `...Scoped.ReadyToUse` not `Singleton`.\n\nAnd the filters are now applied on class.\n\nThe handler will be automatically collected by the updater if you call `CollectHandlers`.\nAn now you can use your `IFancyService` which is available in DI right into `Start`'s constructor.\n\nInstead of using `HandleAsync(MessageContainer container)`, you use a more contextual overload like this:\n\n``` csharp\nHandleAsync(\n    MessageContainer input,\n    IServiceScope? scope,\n    CancellationToken cancellationToken)\n```\n\nBut remember not to override both! (The one with less parameters will be ignored).\n\n### Minimals\n\nInstead using scoped handlers as classes you can also create your handlers Minimally!\n\n```csharp\n\n// This is a minimal handler\nupdater.Handle(\n    UpdateType.Message,\n    async (IContainer\u003cMessage\u003e container, IFancyService service) =\u003e\n    {\n        // Do something with the container and service\n    },\n    ReadyFilters.OnCommand(\"command\"))\n\n```\n\n### Controllers\n\nController handlers are scoped handlers where you're not restricted to a single `HandleAsync` method.\nThis enables you to reuse filters and injected services for different but related handling logics.\n\nIf you want a method to recognize as a controller's action, you need to add the `HandlerAction` attribute to it.\nYou can apply filters to the action methods as well as the controller it self to further filter the action methods.\n\nIf you need an extra service inside your action method, you need to mark them with\n`[ResolveService]` attribute (Not to mess with big boy's `[FromServices]`). This will resolve the service from DI and inject it into your action method.\n\nYou can have access to the `IContainer\u003cT\u003e` inside your actions if needed.\n\n```csharp\n\n[Command(\"about\")]\ninternal class About(IFancyOverallService overallService) : MessageControllerHandler\n{\n    [HandlerAction]\n    [ChatType(ChatTypeFlags.Private)]\n    public async Task Private([ResolveService] IFancyService service)\n    {\n        // Do something with your service or overallService.\n        await Response($\"This's what you need to know about me: \");\n    }\n\n    [HandlerAction]\n    [ChatType(ChatTypeFlags.Group | ChatTypeFlags.SuperGroup)]\n    public async Task Group(IContainer\u003cMessage\u003e container)\n    {\n        // Do something with your overallService.\n        await container.Response(\n            \"Theses are private talks!\",\n            replyMarkup: new InlineKeyboardMarkup(aboutButton));\n    }\n}\n\n```\n\n\u003e [!TIP]\n\u003e There are other attributes like `[ExtraData]`, `[CommandArg]` or `[RegexMatchingGroup]` that can be used\n\u003e on actions parameter to have access to extra data based on filters (See PlayGround About, Update or InsertSeen handlers).\n\n\u003e [!NOTE]\n\u003e Typically Methods like `updater.Handle(...)` refers to a singleton handler\n\u003e and `updater.AddHandler(...)` or  `updater.Add...Handler` refer to an scoped handler.\n\u003e Minimal handlers are actually singleton handlers but you can use DI inside them.\n\n### Something cool?!\n\n```csharp\n[Command(\"about\"), Private]\n[HandlerCallback(UpdateType.Message)]\npublic static async Task AboutCommand(IContainer\u003cMessage\u003e container)\n{\n    var message = await container.Response(\"Wanna know more about me?! Answer right now!\",\n        replyMarkup: new InlineKeyboardMarkup([[\n            InlineKeyboardButton.WithCallbackData(\"Yes\"),\n            InlineKeyboardButton.WithCallbackData(\"No\")]]));\n\n    // Wait for short coming answer right here\n    var answer = await container.ChannelButtonClick(TimeSpan.FromSeconds(5), new(@\"Yes|No\"));\n\n    switch (answer)\n    {\n        case { Update.Data: { } data }:\n            {\n                // User did answer\n                if (data == \"Yes\")\n                    await answer.Edit(\"Well me too :)\");\n                else\n                    await answer.Edit(\"Traitor!\");\n\n                await answer.Answer();\n\n                break;\n            }\n        default:\n            {\n                // Likely timed out.\n                await message.Edit(\"Slow\");\n                break;\n            }\n    }\n}\n```\n\nExtension methods return containerized results.\n\n\u003e [!CAUTION]\n\u003e The package is still in preview and the API may change in the future *(for sure)*.\n\u003e It's actually changing right now, so be careful when using it.\n\n## Examples\n\nExamples inside [/Examples](./Examples) folder are up to date with latest package changes and are good start points to begin.\n\n- [ConsoleApp](./Examples/ConsoleApp): Usage of updater inside a console app.\n- [WorkerService](./Examples/WorkerService): Usage of the updater inside a worker service where `IServiceCollection`, `IConfiguration`s can be used by the updater (This's preferred to the console app as you can use scoped handlers)\n- [Webhook](./Examples/Webhook): Setting up a telegram bot using webhooks and updater. (Most of this are as same as WorkerSerivce)\n- [Playground](./Examples/Playground): This is a good worker service example that uses many of TelegramUpdater's features (not all!).\n\n## What's Next ?!\n\nThe package has also some extension packages:\n\n- [TelegramUpdater.FillMyForm](https://github.com/TelegramUpdater/TelegramUpdater.FillMyForm): which magically fills your forms for you.\n- [TelegramUpdater.Menu](https://github.com/TelegramUpdater/TelegramUpdater.Menu): Work with static menus (InlineKeyboards and more).\n\n## Help is always needed!\n\nIf you think this package worths it, then help and contribute. It will be always appreciated!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftelegramupdater%2Ftelegramupdater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftelegramupdater%2Ftelegramupdater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftelegramupdater%2Ftelegramupdater/lists"}