TelegramBotFramework
.NET Telegram Bot Framework is a modular, context-based framework for building advanced Telegram bots in .NET. It offers forms, controls, state management, session serialization, command handling, navigation, localization, and group management for interactive and maintainable bots.
Install / Use
/learn @MajMcCloud/TelegramBotFrameworkREADME
.NET Telegram Bot Framework - Context based addon
Showcase: @TGBaseBot
Support group: @tgbotbase
Discord Server: https://discord.gg/V3PxreDYfE
Releases: GitHub
Need your own bot? Get in touch https://t.me/botbasebuilder
on X: @florian_zevedei
Donate
Paypal: https://paypal.me/majmccloud
Bitcoin: 1GoUJYMwAvBipQTfw2FKydAz12J8RDyeJs / bc1qqwlp0p5ley29lsu6jhe0qv7s7963kfc7d0m53d
Etherium: 0xAf3835104c2C3E5b3e721FA2c7365955e87DB931
Litecoin: LRhF1eB7kneFontcDRDU8YjJhEm2GoYHch
Dashcoin: XudiUwWtSmAJj1QDdVW7jocQumJFLsyoGZ
Tron: TYVZSykaVT1nKZnz9hjDgBRNB9VavU1bpW
BitTorrent: TYVZSykaVT1nKZnz9hjDgBRNB9VavU1bpW
Index
- Quick start
- Simplified builder
- Features
- Message Loops
- Special Forms
- Controls
- Localizations
- Groups
- State Machine and Session Serialization (v3.0.0)
- Navigation and NavigationController (v4.0.0)
- Threading & Performance
- Action Manager (Extension)
- Extensions
- Test Project
- Examples
Quick start
First of all, create a new empty dotnet console project and paste some code:
// public async Task Main(string[] args)
var bot = BotBaseBuilder
.Create()
.WithAPIKey("{YOUR API KEY}") // do not store your API key as plain text in project sources
.DefaultMessageLoop()
.WithStartForm<StartForm>()
.NoProxy()
.CustomCommands(a =>
{
a.Start("Starts the bot");
})
.NoSerialization()
.UseEnglish()
.UseSingleThread()
.Build();
// Upload bot commands to BotFather
await bot.UploadBotCommands();
// Start your Bot
await bot.Start();
The BotBase class will manage a lot of things for you, like bot commands, action events and so on.
StartForm is your first form which every user will get internally redirected to, just like a start page.
It needs to be a subclass of FormBase you will find in namespace TelegramBotBase.Base
Every Form has some events which will get raised at specific times.
In every form, you are able to get notes about
the Remote Device,
like ChatId and other stuff your carrying.
From there you build up your bots:
public class Start : FormBase
{
public Start()
{
//Additional event handlers
Init += Start_Init;
Opened += Start_Opened;
Closed += Start_Closed;
}
// Gets invoked on initialization, before navigation
private async Task Start_Init(object sender, Args.InitEventArgs e)
{
}
// Gets invoked after opened
private async Task Start_Opened(object sender, EventArgs e)
{
}
// Gets invoked after form has been closed
private async Task Start_Closed(object sender, EventArgs e)
{
}
// Gets invoked during Navigation to this form
public override async Task PreLoad(MessageResult message)
{
}
// Gets invoked on every Message/Action/Data in this context
public override async Task Load(MessageResult message)
{
// `Device` is a wrapper for current chat - you can easily respond to the user
await this.Device.Send("Hello world!");
}
// Gets invoked on edited messages
public override async Task Edited(MessageResult message)
{
}
// Gets invoked on Button clicks
public override async Task Action(MessageResult message)
{
}
// Gets invoked on Data uploades by the user (of type Photo, Audio, Video, Contact, Location, Document)
public override async Task SentData(DataResult data)
{
}
//Gets invoked on every Message/Action/Data to render Design or Response
public override async Task Render(MessageResult message)
{
}
}
Send a message after loading a specific form:
await this.Device.Send("Hello world!");
Want to go to a different form? Go ahead, create it, initialize it and navigate to it:
var form = new TestForm();
await this.NavigateTo(form);
Simplified builder
When migrating from a previous version or starting completely new, all these options can be a bit overwhelming.
There's a function called QuickStart that simplifies building a bit.
var bot = BotBaseBuilder
.Create()
.QuickStart<StartForm>("{YOUR API KEY}")
.Build();
await bot.Start();
Features
System calls & bot commands
Using BotFather you can add Commands to your bot. The user will see them as popups in a dialog. Before starting (and later, for sure), you could add them to your BotBase. If the message contains a command, a special event handler will get raised.
Below we have 4 commands.
/start - opens the start form
/form1 - navigates in this context to form1
/form2 - navigates in this context to form2
/params - demonstrates the use of parameters per command (i.e. /params 1 2 3 test ...)
var bot = BotBaseBuilder
.Create()
.WithAPIKey("{YOUR API KEY}")
.DefaultMessageLoop()
.WithStartForm<Start>()
.NoProxy()
.CustomCommands(a =>
{
a.Start("Starts the bot");
a.Add("form1","Opens test form 1");
a.Add("form2", "Opens test form 2");
a.Add("params", "Returns all send parameters as a message.");
})
.NoSerialization()
.UseEnglish()
.UseSingleThread()
.Build();
bot.BotCommand += async (s, en) =>
{
switch (en.Command)
{
case "/form1":
var form1 = new TestForm();
await en.Device.ActiveForm.NavigateTo(form1);
break;
case "/form2":
var form2 = new TestForm2();
await en.Device.ActiveForm.NavigateTo(form2);
break;
case "/params":
string m = en.Parameters.DefaultIfEmpty("").Aggregate((a, b) => a + " and " + b);
await en.Device.Send("Your parameters are " + m, replyTo: en.Device.LastMessage);
break;
}
};
await bot.UploadBotCommands()
await bot.Start();
On every input the user is sending back to the bot, the Action event gets raised. So here we could manage to send
something back to him.
Text messages
<img src=".github/images/example1.PNG" />public class SimpleForm : AutoCleanForm
{
public SimpleForm()
{
DeleteSide = EDeleteSide.Both;
DeleteMode = EDeleteMode.OnLeavingForm;
Opened += SimpleForm_Opened;
}
private async Task SimpleForm_Opened(object sender, EventArgs e)
{
await Device.Send("Hello world! (send 'back' to get back to Start)\r\nOr\r\nhi, hello, maybe, bye and ciao");
}
public override async Task Load(MessageResult message)
{
// message.MessageText will work also, cause it is a string you could manage a lot different scenerios here
var messageId = message.MessageId;
switch (message.Command)
{
case "hello":
case "hi":
// Send a simple message
