TelegramUpdater 1.8.1-preview.0.0

This is a prerelease version of TelegramUpdater.
dotnet add package TelegramUpdater --version 1.8.1-preview.0.0
                    
NuGet\Install-Package TelegramUpdater -Version 1.8.1-preview.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TelegramUpdater" Version="1.8.1-preview.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TelegramUpdater" Version="1.8.1-preview.0.0" />
                    
Directory.Packages.props
<PackageReference Include="TelegramUpdater" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TelegramUpdater --version 1.8.1-preview.0.0
                    
#r "nuget: TelegramUpdater, 1.8.1-preview.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=TelegramUpdater&version=1.8.1-preview.0.0&prerelease
                    
Install TelegramUpdater as a Cake Addin
#tool nuget:?package=TelegramUpdater&version=1.8.1-preview.0.0&prerelease
                    
Install TelegramUpdater as a Cake Tool

TelegramUpdater (Preview)

Nuget Version Nuget Downloads Docs Ask DeepWiki

TelegramUpdater is feature-rich super customizable framework library for building telegram bots in c#.

Features

  • Telegram updater manages update handling process from receiving updates to queuing them filtering them, answering them, handling exceptions, managing state and more ...
  • Updater ensures that only a limited number of updates are begin processed in parallel, and if the user id can be figured out, the updates are processed in sequence per each user.
  • Benefiting from queuing the incoming updates, you can have access to the future by ReadNext.
  • Singleton and Scoped handlers which can enable you to use DI and scoped services.
  • Rich filter system by allowing to combine filters or applying them as attributes.
  • Containers with access to a lot of resources like Update and inner update, Updater itself and more. This can enable you to have, use or create a lot of extension methods on them.
  • Update channels can make a channel from your current handler to the updating pipeline and fetch future updates, like waiting for text input right inside the handler.
  • Handling exceptions whiling filtering them by type or message.
  • Hosting support as mentioned before, to have access to DI and webhook.
  • Managing state and integrating them with filters and container's extension methods.
  • Many helper (extension) methods and types.
  • Super abstraction over any thing! You can create your own filter, handler, container, update channels, extension methods and even update writers.

Getting Started

Let's get started with this package and learn how to implement some of above features.

Installation

The package is available inside Nuget.

TelegramUpdater uses Telegram.Bot: .NET Client for Telegram Bot API package as an C# wrapper over Telegram bot api.

Documentations

Documentations can be found at Here.

Code sample

Console app

A very minimal yet working example of TelegramUpdater usage is something like this.

using TelegramUpdater;
using TelegramUpdater.UpdateContainer;
using TelegramUpdater.UpdateContainer.UpdateContainers;

var updater = new Updater("YOUR_BOT_TOKEN")
    .AddDefaultExceptionHandler()
    .QuickStartCommandReply("Hello there!");

await updater.Start();

This setups Updater with your bot token, adds a default exception handler that logs errors, a (singleton) update handler that works on /start command on private chats and finally starts up the updater.

Updater can automatically collect your handlers as statics methods like example below

var updater = new Updater("YOUR_BOT_TOKEN")
    .AddDefaultExceptionHandler()
    .CollectHandlingCallbacks();

await updater.Start();

partial class Program
{
    [Command("start"), Private]
    [HandlerCallback(UpdateType.Message)]
    public static async Task Start(IContainer<Message> container)
    {
        await container.Response("Hello World");
    }
}

This should work the same as before. (Filters are applied as attributes)

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 if its filters passes, by its parameterless constructor.

Worker service

If your project is a worker service or anything that has HostBuilder and DI (dependency injection) in it, you can setup updater like this.

var builder = Host.CreateApplicationBuilder(args);

// this will collect updater options like BotToken, AllowedUpdates and ...
// from configuration section "TelegramUpdater". in this example from appsettings.json
builder.AddTelegramUpdater(
    (builder) => builder
        // Modify the actual updater
        .Execute(updater => updater
            // Collects static methods marked with `HandlerCallback` attribute.
            .CollectHandlingCallbacks())
        // Collect scoped handlers located for example at UpdateHandlers/Messages for messages.
        .CollectHandlers()
        .AddDefaultExceptionHandler());

var host = builder.Build();
await host.RunAsync();

The configuration are automatically figured out if they're exists somewhere like in appsettings.json. You can add them like this:

{
  
  ...

  "TelegramUpdater": {
    "BotToken": "",
    "AllowedUpdates": [ "Message", "CallbackQuery" ]
  },
  
  ...
}

Updater can and will figure out AllowedUpdates if not specified by looking into you registered handlers.

For singleton handlers it's just like before, but if your going to use scoped handlers, put them into the right place as mentioned in the example.

For example create a file at UpdateHandlers/Messages like UpdateHandlers/Messages/Start.cs

The Start.cs should look like this:

using TelegramUpdater.FilterAttributes.Attributes;
using TelegramUpdater.UpdateContainer;
using TelegramUpdater.UpdateContainer.UpdateContainers;
using TelegramUpdater.UpdateHandlers.Scoped.ReadyToUse;

namespace GettingStarted.UpdateHandlers.Messages;

[Command("start"), Private]
internal class Start : MessageHandler
{
    protected override async Task HandleAsync(MessageContainer container)
    {
        await container.Response("Hello World");
    }
}

Watch out for name space where the MessageHandler came from, it must be ...Scoped.ReadyToUse not Singleton.

And the filters are now applied on class.

The handler will be automatically collected by the updater if you call CollectHandlers. An now you can use your IFancyService which is available in DI right into Start's constructor.

Instead of using HandleAsync(MessageContainer container), you use a more contextual overload like this:

HandleAsync(
    MessageContainer input,
    IServiceScope? scope,
    CancellationToken cancellationToken)

But remember not to override both! (The one with less parameters will be ignored).

Minimals

Instead using scoped handlers as classes you can also create your handlers Minimally!


// This is a minimal handler
updater.Handle(
    UpdateType.Message,
    async (IContainer<Message> container, IFancyService service) =>
    {
        // Do something with the container and service
    },
    ReadyFilters.OnCommand("command"))

Controllers

Controller handlers are scoped handlers where you're not restricted to a single HandleAsync method. This enables you to reuse filters and injected services for different but related handling logics.

If you want a method to recognize as a controller's action, you need to add the HandlerAction attribute to it. You can apply filters to the action methods as well as the controller it self to further filter the action methods.

If you need an extra service inside your action method, you need to mark them with [ResolveService] attribute (Not to mess with big boy's [FromServices]). This will resolve the service from DI and inject it into your action method.

You can have access to the IContainer<T> inside your actions if needed.


[Command("about")]
internal class About(IFancyOverallService overallService) : MessageControllerHandler
{
    [HandlerAction]
    [ChatType(ChatTypeFlags.Private)]
    public async Task Private([ResolveService] IFancyService service)
    {
        // Do something with your service or overallService.
        await Response($"This's what you need to know about me: ");
    }

    [HandlerAction]
    [ChatType(ChatTypeFlags.Group | ChatTypeFlags.SuperGroup)]
    public async Task Group(IContainer<Message> container)
    {
        // Do something with your overallService.
        await container.Response(
            "Theses are private talks!",
            replyMarkup: new InlineKeyboardMarkup(aboutButton));
    }
}

There are other attributes like [ExtraData], [CommandArg] or [RegexMatchingGroup] that can be used on actions parameter to have access to extra data based on filters (See PlayGround About, Update or InsertSeen handlers).

Typically Methods like updater.Handle(...) refers to a singleton handler and updater.AddHandler(...) or updater.Add...Handler refer to an scoped handler. Minimal handlers are actually singleton handlers but you can use DI inside them.

Something cool?!

[Command("about"), Private]
[HandlerCallback(UpdateType.Message)]
public static async Task AboutCommand(IContainer<Message> container)
{
    var message = await container.Response("Wanna know more about me?! Answer right now!",
        replyMarkup: new InlineKeyboardMarkup([[
            InlineKeyboardButton.WithCallbackData("Yes"),
            InlineKeyboardButton.WithCallbackData("No")]]));

    // Wait for short coming answer right here
    var answer = await container.ChannelButtonClick(TimeSpan.FromSeconds(5), new(@"Yes|No"));

    switch (answer)
    {
        case { Update.Data: { } data }:
            {
                // User did answer
                if (data == "Yes")
                    await answer.Edit("Well me too :)");
                else
                    await answer.Edit("Traitor!");

                await answer.Answer();

                break;
            }
        default:
            {
                // Likely timed out.
                await message.Edit("Slow");
                break;
            }
    }
}

Extension methods return containerized results.

The package is still in preview and the API may change in the future (for sure). It's actually changing right now, so be careful when using it.

Examples

Examples inside /Examples folder are up to date with latest package changes and are good start points to begin.

  • ConsoleApp: Usage of updater inside a console app.
  • WorkerService: Usage of the updater inside a worker service where IServiceCollection, IConfigurations can be used by the updater (This's preferred to the console app as you can use scoped handlers)
  • Webhook: Setting up a telegram bot using webhooks and updater. (Most of this are as same as WorkerSerivce)
  • Playground: This is a good worker service example that uses many of TelegramUpdater's features (not all!).

What's Next ?!

The package has also some extension packages:

Help is always needed!

If you think this package worths it, then help and contribute. It will be always appreciated!

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on TelegramUpdater:

Package Downloads
TelegramUpdater.Hosting

Hosting extension package for TelegramUpdater

TelegramUpdater.FillMyForm

This is an extension package for TelegramUpdater to help you fill a form in a blink of an eye.

GettingStarted

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.8.1-preview.0.0 180 5/12/2025
1.8.0-preview.1.0 60 5/9/2025
1.8.0-preview.0.1 106 5/8/2025
1.8.0-preview.0.0 106 5/7/2025
1.6.0-preview.0.0 81 4/26/2025
1.5.0-preview.1.8 89 4/25/2025
1.5.0-preview.1.7 83 4/25/2025
1.4.0-preview.5.3 253 4/28/2022
1.4.0-preview.5.2 165 4/10/2022
1.4.0-preview.4.9 146 4/4/2022
1.4.0-preview.4.4 200 4/3/2022
1.4.0-preview.4.1 146 4/1/2022
1.4.0-preview.3.3 164 3/14/2022
1.4.0-preview.2.3 150 3/10/2022
1.4.0-preview.2.2 167 3/8/2022
1.4.0-preview.1.4 174 3/7/2022

Watch out for breaking changes.