TeleFlow 1.3.1
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package TeleFlow --version 1.3.1
NuGet\Install-Package TeleFlow -Version 1.3.1
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="TeleFlow" Version="1.3.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TeleFlow" Version="1.3.1" />
<PackageReference Include="TeleFlow" />
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 TeleFlow --version 1.3.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: TeleFlow, 1.3.1"
#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.
#:package TeleFlow@1.3.1
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TeleFlow&version=1.3.1
#tool nuget:?package=TeleFlow&version=1.3.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
π§ TeleFlow (Telegram.Bot.Extensions.Handlers)
A modern, extensible Telegram bot framework for .NET β built for structured conversations, FSM-driven flows, and developer joy.
β¨ Key Features
- Multi-Step Commands (FSM) β build rich conversational flows without state spaghetti.
- Built-in DatePicker β interactive inline calendar, no more βenter date in DD/MM/YYYY.β
- Interceptor & Validator pipeline β plug checks or transformations before handlers.
- Navigation between commands β move seamlessly through dialog stages.
- Async first β fully asynchronous execution pipeline.
- Fluent configuration via lambdas β ASP.NET-Core-style setup for familiarity.
- Photo and Media support β receive, process, and send images out of the box.
π Quick Start
1οΈβ£ Install
dotnet add package TeleFlow
2οΈβ£ Create your bot entry point
using demo.Services;
using TeleFlow.Factories;
using TeleFlow.Models;
using TeleFlow.Services;
using Telegram.Bot;
using TeleFlow.Services.Markup;
using TeleFlow.Services.Messaging;
using Telegram.Bot.Types;
using Telegram.Bot.Types.ReplyMarkups;
string BOT_TOKEN = System.IO.File.ReadAllText("bot-token.txt");
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSingleton<IMessageServiceFactory<IMessageServiceWithEdit<Message>, Message>, UniversalMessageServiceFactory>();
builder.Services.AddSingleton<IMessageServiceFactory<string>, UniversalMessageServiceFactory>();
builder.Services.AddSingleton<IMessageServiceFactory<ImageMessageServiceMessage>, UniversalMessageServiceFactory>();
builder.Services.AddSingleton<IReplyMarkupManagerFactory, ReplyMarkupManagerFactory>();
builder.Services.AddSingleton<InlineMarkupManagerFactory, DemoInlineMarkupManagerFactory>();
builder.Services.AddSingleton<IMediaDownloaderServiceFactory, MediaDownloaderServiceFactory>();
builder.Services.AddSingleton<IUpdateDistributorArgsBuilder<UpdateDistributorNextHandlerBuildArgs>, UpdateDistributorArgsBuilder>();
builder.Services.AddSingleton<UpdateDistributorFactory<UpdateDistributorNextHandlerBuildArgs>, DemoUpdateDistributorFactory>();
builder.Services.AddHttpClient("tgwebhook")
.RemoveAllLoggers()
.AddTypedClient<ITelegramBotClient>(httpClient => new TelegramBotClient(BOT_TOKEN, httpClient));
builder.Services.ConfigureTelegramBotMvc();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
3οΈβ£ Define your first command
using TeleFlow.Builders;
using TeleFlow.Factories;
using TeleFlow.Models;
using TeleFlow.Services;
namespace demo;
public class DemoUpdateDistributorFactory : UpdateDistributorFactory<UpdateDistributorNextHandlerBuildArgs>
{
protected override void SetupUpdateListenerFactoryBuilder(UpdateListenerCommandFactoryBuilder<UpdateDistributorNextHandlerBuildArgs> builder)
{
builder.WithLambda("/start", (args) => {
return new SendTextCommand(args.BuildTimeArgs.FromUpdateDistributorArgs.MessageServiceString, "Welcome to the bot!");
});
}
public DemoUpdateDistributorFactory(IUpdateDistributorArgsBuilder<UpdateDistributorNextHandlerBuildArgs> updateDistributorArgsBuilder) : base(updateDistributorArgsBuilder)
{
}
}
π§© Building Multi-Step Commands (FSM)
TeleFlow lets you model interactive dialogs as state machines:
public class DemoUpdateDistributorFactory : UpdateDistributorFactory<UpdateDistributorNextHandlerBuildArgs>
{
protected override void SetupUpdateListenerFactoryBuilder(UpdateListenerCommandFactoryBuilder<UpdateDistributorNextHandlerBuildArgs> builder)
{
builder
.WithMultiStep<DemoViewModel>("/multistep", options =>
{
options
.SetDefaultStateValue(new())
.WithValidation(options =>
{
options
.WithStepWithValidationLambdaFactory((args, next) =>
{
return new ContactShareStepCommand(args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.ReplyMarkupManager, (userInput) =>
{
args.State.CurrentValue.PhoneNumber = userInput.PhoneNumber;
}, "Please Share Your Phone. This will NOT go anywhere", "Share My Phone",
new PhoneNumberBelongsToUserValidator(args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.MessageServiceString, args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.ChatIdProvider, "The input was invalid", "The phone number does not belong to you."),
next);
}, "Phone Number")
.WithStepWithValidationLambdaFactoryGoBackButton((args, next, validator) =>
{
return new TextInputStepCommand(args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.MessageServiceString, "Please enter your full name", async (message) =>
{
args.State.CurrentValue.UserFullName = message;
}, next, validator);
}, "User Full Name")
.WithStepWithValidationLambdaFactory((args, next) =>
{
return new EnumValueSelectionStepCommand<DemoEnum>(args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.MessageService, "Please select one of the values",
async (userInput) =>
{
args.State.CurrentValue.LibraryRating = userInput;
},
(enumValue) =>
{
if (enumValue == DemoEnum.None)
return null;
return enumValue.ToString();
}, new(), next);
}, "Library Rating")
.WithStepWithValidationLambdaFactory((args, next) =>
{
return new ListValueSelectionStepCommand<DemoListObject>(args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.MessageService, "Please select the value.",
async (userInput) =>
{
args.State.CurrentValue.ListObject = userInput;
},
new(3),
async () =>
{
return new List<DemoListObject>() { new() { DisplayName = "List Object 1", Value = "Value 1" }, new() { DisplayName = "List Object 2", Value = "Value 2" } };
},
(listObject) =>
{
return listObject.DisplayName;
}, next);
}, "List Object Selection");
})
.WithLambdaResult(args =>
{
return new LambdaHandler<DemoViewModel>(async (vm) =>
{
StringBuilder sb = new();
sb.AppendLine("You have successfully completed the multi step command. Here is the data you entered:");
sb.AppendLine($"Full Name: {vm.UserFullName}");
sb.AppendLine($"Library Rating: {vm.LibraryRating}");
sb.AppendLine($"List Object: {vm.ListObject.DisplayName} with value {vm.ListObject.Value}");
sb.AppendLine($"Phone: {vm.PhoneNumber}");
await args.BuildTimeArgs.FromUpdateDistributorArgs.MessageServiceString.SendMessage(sb.ToString());
await args.BuildTimeArgs.Navigator.Handle("/start");
});
});
})
}
public DemoUpdateDistributorFactory(IUpdateDistributorArgsBuilder<UpdateDistributorNextHandlerBuildArgs> updateDistributorArgsBuilder) : base(updateDistributorArgsBuilder)
{
}
}
π Using the DatePicker
Inline calendar selection is as simple as:
public class DemoUpdateDistributorFactory : UpdateDistributorFactory<UpdateDistributorNextHandlerBuildArgs>
{
protected override void SetupUpdateListenerFactoryBuilder(UpdateListenerCommandFactoryBuilder<UpdateDistributorNextHandlerBuildArgs> builder)
{
builder
.WithMultiStep<DemoViewModel>("/multistep", options =>
{
options
.SetDefaultStateValue(new())
.WithValidation(options =>
{
options
.WithStepWithValidationLambdaFactory((args, next) =>
{
return new DateSelectionStepCommand(next, args.UpdateListenerBuilderArgs.BuildTimeArgs.FromUpdateDistributorArgs.MessageService, (date) =>
{
args.State.CurrentValue.SelectedDate = date;
}, "Pick a date", new(DateOnly.FromDateTime(DateTime.Today).AddYears(-18), TeleFlow.Services.DateSelectionView.YearSelection), null, new(DateOnly.FromDateTime(DateTime.Today).AddYears(-14), "You are too young!"));
}, "Date");
})
.WithLambdaResult(args =>
{
return new LambdaHandler<DemoViewModel>(async (vm) =>
{
StringBuilder sb = new();
sb.AppendLine("You have successfully completed the multi step command. Here is the data you entered:");
sb.AppendLine($"Date: {vm.SelectedDate.ToShortDateString()}");
await args.BuildTimeArgs.FromUpdateDistributorArgs.MessageServiceString.SendMessage(sb.ToString());
await args.BuildTimeArgs.Navigator.Handle("/start");
});
});
})
}
public DemoUpdateDistributorFactory(IUpdateDistributorArgsBuilder<UpdateDistributorNextHandlerBuildArgs> updateDistributorArgsBuilder) : base(updateDistributorArgsBuilder)
{
}
}
π§ Navigation & Interceptors
Interceptors run before your handler executes β useful for auth, validation, or logging.
π§ Concepts in TeleFlow
| Concept | Purpose |
|---|---|
| Command Handler | Encapsulates single user action. |
| MultiStep Command | Defines sequential interaction with user state. |
| Navigator | Moves user between commands/states. |
| Interceptors / Validators | Pre-processing logic. |
| DatePicker | Inline UI component for dates. |
| Factory Builder | Internal system creating command handlers dynamically. |
π§° Advanced Topics
- Error Handling & Retry Policies
- Dependency Injection
- Custom Interceptors
- Testing Command Flows
π¦ Roadmap
- Inline Keyboards API V2
- JSON-based Dialog Serialization
- Redis state storage extension (
TeleFlow.Redis) - Admin Panel Toolkit
π¬ Community
- Telegram: @TeleFlowDev
- GitHub Discussions: github.com/lamabucket/TeleFlow/discussions
π§© Contributing
- Fork the repo
- Create your feature branch (
git checkout -b feature/foo) - Commit changes (
git commit -m 'Add foo') - Push (
git push origin feature/foo) - Open a PR
π§ License
MIT Β© 2025 β Created by Gleb Bannyy
πͺ One-Sentence Pitch (for NuGet and socials)
TeleFlow β Fluent and async Telegram bot framework for .NET with FSM, interceptors & built-in DatePicker.
β Summary of what you need to add
| Placeholder | What to include |
|---|---|
| Program.cs snapshot | Minimal bot initialization & configuration pipeline |
| StartCommand | Simplest ICommandHandler example |
| MultiStep example | Step-by-step FSM collecting data |
| DatePicker example | Show inline calendar interaction |
| Interceptor example | Auth or validation interceptor |
| Config snapshot | Real lambda setup using your builder |
| Flow diagram (optional) | How Update β Factory β Handler pipeline works |
| Custom Interceptor + DI | Example of advanced extensibility |
| CONTRIBUTING excerpt | How to run/test locally |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Newtonsoft.Json (>= 13.0.3)
- Telegram.Bot (>= 21.7.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on TeleFlow:
| Package | Downloads |
|---|---|
|
TeleFlow.Polling
TeleFlow meta-package with polling hosting support. |
GitHub repositories
This package is not used by any popular GitHub repositories.