Build Telegram Bots in .NET with the simplicity of Minimal APIs.
TeleFrame is a lightweight Telegram Bot Framework for .NET that brings Dependency Injection, Middleware, Filters, Routing, and State Management to Telegram bot development.
Instead of dealing with large update switch statements and repetitive Telegram Bot API boilerplate, TeleFrame lets you define commands, messages, update handlers, middleware, filters, and conversation states using a clean and familiar developer experience.
bot.MapCommand("/start", () => "Welcome to TeleFrame!");- 📦 Installation
- 🚀 Quick Start
- 💉 Dependency Injection
- ⌨️ Commands
- 💬 Message Handlers
- 🎙️ Voice Messages
- 🔄 Update Handlers
- 🛠️ Middleware
- 🛡️ Filters
- 🧠 State Management
- 📌 UpdateContext
- 📨 Results API
- 📋 Logging
- 🎯 Example Application
- 🤔 Why TeleFrame?
- 🗺️ Roadmap
- 🤝 Contributing
- 📄 License
Install the package from NuGet:
dotnet add package TeleFrameTeleFrame loads the bot token from the application configuration. By default, the framework looks for a botConfig.json file in the application root.
Create a botConfig.json file next to your application's executable:
{
"Token": "YOUR_BOT_TOKEN"
}Instead of storing your bot token inside a configuration file, you can use .NET User Secrets:
dotnet user-secrets init
dotnet user-secrets set "Token" "YOUR_BOT_TOKEN"TeleFrame automatically loads User Secrets from the entry assembly, allowing you to keep sensitive credentials out of source control.
Configuration sources are loaded in the following order:
botConfig.json- .NET User Secrets
If the same key exists in multiple sources, the value from the last loaded source is used.
Important: Never commit real bot tokens to a public repository. For local development, User Secrets are the recommended approach.
var builder = new TelegramBotBuilder(args);
var bot = builder.Build();
bot.MapCommand("/start", () => "Welcome to TeleFrame!");
bot.Run();TeleFrame integrates with Microsoft's Dependency Injection container.
Register services:
builder.Services.AddScoped<AdminsService>();Inject them directly into handlers:
bot.MapCommand("/admins", (AdminsService service) =>
{
return string.Join(", ", service.Admins);
});No manual service resolution required.
Commands are the most common way to interact with users.
bot.MapCommand("/start", () =>
{
return "Welcome to TeleFrame!";
});bot.MapCommand("/hi", () =>
{
return Results.Reply("Hello World");
});bot.MapCommand("/help", (UpdateContext ctx) =>
{
var username = ctx.Update.Message!.From!.Username;
return Results.Reply(
$"Hello {username}",
messageEffect: MessageEffects.Heart);
});Handle specific message types.
bot.MapMessage(MessageType.Text, () =>
{
return "Text message received";
});Example:
bot.MapMessage(MessageType.Photo, () =>
{
return "Nice photo!";
});Handle voice messages with a dedicated API.
bot.MapVoice(() =>
{
return Results.Reply("You sent a voice message!");
});Handle Telegram updates directly.
Example:
bot.MapUpdate(UpdateType.EditedMessage, (UpdateContext ctx) =>
{
var message = ctx.Update.EditedMessage!;
return Results.Reply(
$"You edited: {message.Text}");
});Example for boost notifications:
bot.MapUpdate(UpdateType.ChatBoost,
(UpdateContext ctx, AdminsService service) =>
{
foreach (var admin in service.Admins)
{
ctx.Client.SendMessage(
admin.Id,
"Channel boosted");
}
});TeleFrame provides a middleware pipeline similar to ASP.NET Core.
Middleware can inspect, modify, or stop processing updates.
builder.Services.AddScoped<BlackListMiddleware>();
bot.Use<BlackListMiddleware>();bot.Use(next => (context, ct) =>
{
Console.WriteLine("Update received");
return next(context, ct);
});public class BlackListMiddleware : IUpdateMiddleware
{
public async Task InvokeAsync(
UpdateContext context,
UpdateDelegate next,
CancellationToken ct)
{
var blocked = false;
if (blocked)
return;
await next(context, ct);
}
}Filters allow validation and authorization before executing handlers.
public class OnlyAdminsFilter
: IUpdateHandlerFilter
{
public Task InvokeAsync(
UpdateContext context,
UpdateHandlerFilterDelegate next,
CancellationToken ct)
{
var isAdmin = true;
if (isAdmin)
return next(context, ct);
return Task.CompletedTask;
}
}bot.MapCommand("/admins", () =>
{
return "Admin panel";
})
.Filter<OnlyAdminsFilter>();TeleFrame includes a simple conversation state system.
Perfect for multi-step user interactions.
bot.MapCommand("/verify",
(IStateManager stateManager) =>
{
stateManager.SetState(
"awaiting_phone_number");
return "Please enter your phone number.";
});bot.MapMessage(MessageType.Text,
(UpdateContext ctx,
IStateManager stateManager) =>
{
var input = ctx.Update.Message!.Text!;
stateManager.ClearState();
return "Verification complete.";
})
.RequireState("awaiting_phone_number");stateManager.ClearState();UpdateContext gives you access to:
- Telegram Client
- Current Update
- User Information
- Chat Information
- Services
- State Management
- Request Context
Example:
bot.MapCommand("/me", (UpdateContext ctx) =>
{
var user = ctx.Update.Message!.From!;
return Results.Reply(
$"Hello {user.FirstName}");
});Return rich responses using the Results helper.
Results.Reply("Hello");Results.Reply(
"Welcome!",
messageEffect: MessageEffects.Heart);Enable update logging with a single line.
Register:
builder.Services.AddUpdateLogging();Use:
bot.UseUpdateLogging();var builder = new TelegramBotBuilder(args);
builder.Services.AddScoped<AdminsService>();
var bot = builder.Build();
bot.MapCommand("/start",
() => "Welcome to TeleFrame!");
bot.MapVoice(
() => "Voice message received!");
bot.MapCommand("/verify",
(IStateManager stateManager) =>
{
stateManager.SetState("awaiting_phone");
return "Enter your phone number.";
});
bot.Run();Telegram bot development often starts simple but quickly becomes difficult to maintain as your bot grows.
TeleFrame solves this by bringing proven ASP.NET Core concepts to Telegram bots:
- Routing
- Middleware
- Dependency Injection
- Filters
- State Management
- Clean Architecture Friendly
You focus on business logic.
TeleFrame handles the plumbing.
- Callback Query Routing
- Inline Query Support
- Webhook Hosting
- Background Jobs
- Localization Support
- Built-in Authorization
Contributions, ideas, bug reports, and pull requests are welcome.
If you find TeleFrame useful, consider giving the repository a ⭐.
Licensed under the MIT License.