This project aims creating telegram bots in a simplest and more straight way with DRY. ( TelegramUpdater aims .NET 6 and above. )
The package ( should ) handles following:
- Getting updates from telegram ( Customizable )
- Ensures updates are processed in parallel.
- Ensures updates are processed sequential pre each user.
- Ensures a limited count of updates are processed in parallel. ( This count
is specified as
MaxDegreeOfParallelism
, this ensures that parallel running tasks should not be more thanMaxDegreeOfParallelism
. ) - Queuing updates per each user and allows you to semi manage them.
- Handle updates based on created handlers and filters.
- Handle exceptions occurred while handling updates.
- Applies DI ( Dependency Injection ) inside
scoped update Handlers
where anIServiceProvider
is available. - Enable waiting for other updates while handling an update.
- Handle overlapping handlers.
- Some extension methods and properties ( especially in scoped handlers ) to make faster to develop.
- Handle some low level staff like handling commands, deep-links and etc.
- (Recently) Helps you keep state of a user in a simplest way.
Let's get started with this package and learn how to implement some of above features.
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.
Assume you have an empty console application. Put following inside Program.cs
.
using TelegramUpdater;
// Initialize a new instance of Updater using your bot token
var updater = new Updater("<BOT_TOKEN>");
updater.AutoCollectScopedHandlers();
updater.AddDefaultExceptionHandler();
await updater.StartAsync();
Let's explain above code.
-
Initialize
Updater
To do this you need a Telegram bot token. You can create a bot and get it's token from @BotFather.
Then replace you own token with
<BOT_TOKEN>
. -
Add you update handlers
While you can add the update handlers manually using following methods:
updater.AddSingletonUpdateHandler()
updater.AddScopedUpdaterHandler()
But it's better to let's updater fetch them automatically for some reasons:
- You won't miss a handler in case you forgot to add it.
- You will have all your handler in one place and their right place. ...
NOTE:
-
By default, updater will look for handler inside
UpdaterHandlers
namespace followed by updater name.Eg:
UpdateHandler/Messages
for message handlers. -
This method looks only for
ScopedUpdateHandler
.
-
Add exception handler
Method
updater.AddDefaultExceptionHandler()
will add a defaultExceptionHandler
that handles all exceptions occurred while handling updates. -
Start the updater using a default
UpdateWriter
.UpdateWriter
is a class that manages receiving updates from Telegram and writing them to the updater.You can create your own writer by inheriting from
UpdateWriterAbs
, then useawait updater.StartAsync<MyUpdateWriter>()
Now, if you run the app, you will see some logs and nothing else. Since you should add some update handlers yet.
Let's create a command handler for /start
.
-
Since we are using
AutoCollectScopedHandlers
, you should create a folder namedUpdateHandler
( you can change this naming ) and another folder namedMessages
inside it. -
Inside
UpdateHandler/Messages
create a file nameStartCommand.cs
.Inside
StartCommand.cs
should be like this:namespace MyApp.UpdateHandlers.Messages; internal class StartCommand { }
-
Convert your class to an
Scoped message handler
Your class should inherit from
MessageHandler
( fromTelegramUpdater.UpdateHandlers.Scoped.ReadyToUse
namespace )using Telegram.Bot.Types; using TelegramUpdater.UpdateContainer; using TelegramUpdater.UpdateHandlers.Scoped.ReadyToUse; namespace YouKnowIKnowYou.UpdateHandlers.Messages; internal class StartCommand : MessageHandler { protected override Task HandleAsync(IContainer<Message> cntr) { throw new NotImplementedException(); } }
-
Our implementation to handle the update goes inside
HandleAsync
method.For now let's just send a message to the user.
protected override async Task HandleAsync(IContainer<Message> _) { await ResponseAsync("Started from TelegramUpdater"); }
-
Add a filter to look for
/start
commands only.For scoped update handlers, we use
FilterAttributes
to apply filters.using Telegram.Bot.Types; using TelegramUpdater.FilterAttributes.Attributes; using TelegramUpdater.UpdateContainer; using TelegramUpdater.UpdateHandlers.Scoped.ReadyToUse; namespace YouKnowIKnowYou.UpdateHandlers.Messages; [Command(command: "start"), Private] internal class StartCommand : MessageHandler { protected override async Task HandleAsync(IContainer<Message> _) { await ResponseAsync("Started from TelegramUpdater"); } }
This is how a real scoped update handler look like.
Now if you run the app and send /start
to the bot, you'll have a response.
Read more at Wiki.
There're plenty of various examples available at Examples