Back to projects
project

Laraue.Telegram.NET β€” Write Telegram Bots Like ASP.NET Controllers in C#

If you've built ASP.NET Core APIs before, writing a Telegram bot shouldn't feel like starting over. Laraue.Telegram.NET brings the controller/middleware pattern you already know to Telegram bot development β€” routing, dependency injection, authentication, roles, and localization, all wired together cleanly.

NuGet Downloads MIT License


The Problem With Typical Telegram Bot Code

Most Telegram bots start clean and degrade fast. The Bot API gives you an update object and leaves routing entirely up to you, which typically results in something like this:

if (update.Message?.Text == "/start") Start();
else if (update.Message?.Text == "/settings") OpenSettings();
else if (update.CallbackQuery?.Data.StartsWith("/change")) ChangeSettings();
// ...grows forever

This is hard to navigate, impossible to test cleanly, and a nightmare to maintain as commands multiply.


The Solution: Controllers and Attributes

Laraue.Telegram.NET lets you declare routes using attributes on controller methods β€” the same mental model as ASP.NET Core MVC:

public class MenuController : TelegramController
{
    private readonly IMenuService _service;

    public MenuController(IMenuService service) => _service = service;

    [TelegramMessageRoute("/start")]
    public Task ShowMenuAsync(TelegramRequestContext ctx)
        => _service.HandleStartAsync(ctx.Update.Message!);

    [TelegramCallbackRoute("/open-settings")]
    public Task OpenSettingsAsync(TelegramRequestContext ctx)
        => _service.OpenSettingsAsync(ctx.Update.CallbackQuery!);
}

Services are resolved from Microsoft's standard DI container. All commands are visible at a glance.


Getting Started

Install the core package:

dotnet add package Laraue.Telegram.NET.Core

Webhooks (production):

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTelegramCore(new TelegramBotClientOptions("YOUR_BOT_TOKEN"));
var app = builder.Build();
app.MapTelegramRequests("your-secret-webhook-path");
app.Run();

Long polling (local development):

builder.Services.AddTelegramCore(new TelegramBotClientOptions("YOUR_BOT_TOKEN"));
builder.Services.AddTelegramLongPoolingService();

No infrastructure needed β€” just swap the registration and go.


Authentication & Authorization

Enable user authentication by wiring up a query service that handles user lookup:

services.AddTelegramCore()
    .AddTelegramAuthentication<User, Guid, TelegramUserQueryService, RequestContext>();

Protect endpoints with role-based authorization:

public class AdminController : TelegramController
{
    [RequiresUserRole(Roles.Admin)]
    [TelegramMessageRoute("/stats")]
    public Task SendStatsAsync(RequestContext ctx, CancellationToken ct)
    {
        // Only admins reach here
    }
}

Roles are resolved via your own IUserRoleProvider implementation, or via the built-in StaticUserRoleProvider loaded from app configuration.


Middleware

Intercept requests before they reach your controllers, just like IMiddleware in ASP.NET:

public class LogExceptionsMiddleware : ITelegramMiddleware
{
    private readonly ITelegramMiddleware _next;

    public LogExceptionsMiddleware(ITelegramMiddleware next) => _next = next;

    public async Task<object?> InvokeAsync(CancellationToken ct = default)
    {
        try { return await _next.InvokeAsync(ct); }
        catch (Exception ex) { /* log */ }
        return null;
    }
}

Register with:

services.AddTelegramMiddleware<LogExceptionsMiddleware>();

Localization

Support multiple languages by implementing BaseCultureInfoProvider to detect the user's preferred language, then use standard .resx resource files:

Resources/Buttons.resx      ← English
Resources/Buttons.fr.resx   ← French

Access strings via Resources.Buttons.Menu β€” the correct translation is resolved automatically per user.


Packages

Package Purpose
Laraue.Telegram.NET.Core Routing, controllers, DI
Laraue.Telegram.NET.Authentication User auth + role-based access
Laraue.Telegram.NET.Localization Per-user language resolution

Install only what you need β€” the packages are independent.


Real-World Usage

This library powers two production projects: a language learning app and a real estate monitoring bot, both using Telegram as their primary user interface.

Source: github.com/win7user10/Laraue.Telegram.NET