Zaiets.TelegramBot.Lite 1.0.0

dotnet add package Zaiets.TelegramBot.Lite --version 1.0.0
                    
NuGet\Install-Package Zaiets.TelegramBot.Lite -Version 1.0.0
                    
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="Zaiets.TelegramBot.Lite" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zaiets.TelegramBot.Lite" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Zaiets.TelegramBot.Lite" />
                    
Project file
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 Zaiets.TelegramBot.Lite --version 1.0.0
                    
#r "nuget: Zaiets.TelegramBot.Lite, 1.0.0"
                    
#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 Zaiets.TelegramBot.Lite@1.0.0
                    
#: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=Zaiets.TelegramBot.Lite&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Zaiets.TelegramBot.Lite&version=1.0.0
                    
Install as a Cake Tool

Zaiets.TelegramBot.Lite

NuGet License: MIT .NET

Lightweight Telegram Bot API client for .NET 10 — send messages, build keyboards, handle webhooks and file uploads with minimal dependencies and a clean fluent API.

Author: Vladyslav Zaiets — CTO & Software Architect
Website: sarmkadan.com
Repository: github.com/Sarmkadan/Zaiets.TelegramBot.Lite


Installation

dotnet add package Zaiets.TelegramBot.Lite

Quick Start

// Program.cs
builder.Services.AddTelegramBotClient("YOUR_BOT_TOKEN");

// Or bind from appsettings.json:
// builder.Services.AddTelegramBotClientFromConfiguration();
// appsettings.json
{
  "Telegram": {
    "Token": "123456789:AABBCCDDaabbccdd",
    "DefaultParseMode": "HTML",
    "HttpTimeout": "00:00:30"
  }
}

Inject and use:

public class NotificationService(ITelegramBotClient bot)
{
    public Task SendAsync(long chatId, string text, CancellationToken ct) =>
        bot.SendMessageAsync(chatId, text, ct: ct);
}

Standalone (no DI)

var services = new ServiceCollection();
services.AddTelegramBotClient("YOUR_BOT_TOKEN");
var provider = services.BuildServiceProvider();

var bot = provider.GetRequiredService<ITelegramBotClient>();
var me = await bot.GetMeAsync();
Console.WriteLine($"Running as @{me.Username}");

Sending Messages

// Plain text
await bot.SendMessageAsync(chatId, "Hello!");

// HTML-formatted
await bot.SendMessageAsync(chatId, "<b>Bold</b> and <i>italic</i>", parseMode: "HTML");

// Disable notifications
await bot.SendMessageAsync(chatId, "Silent update", disableNotification: true);

// Reply to a message
await bot.SendMessageAsync(chatId, "Got it!", replyToMessageId: originalMessageId);

MessageBuilder — HTML helper

var text = MessageBuilder.Create()
    .Bold("Order Confirmed")
    .NewLine(2)
    .Text("Reference: ")
    .Code("ORD-20250501-001")
    .NewLine()
    .Text("Total: ")
    .Bold("$49.99")
    .NewLine(2)
    .Link("View details", "https://example.com/orders/1")
    .Build();

await bot.SendMessageAsync(chatId, text);

Keyboards

Inline Keyboard

var keyboard = InlineKeyboard.Create()
    .AddRow()
        .AddButton("Approve ✅", "action:approve")
        .AddButton("Reject ❌", "action:reject")
    .AddRow()
        .AddUrlButton("Open Dashboard", "https://example.com/dashboard")
    .Build();

await bot.SendMessageAsync(chatId, "Review request:", replyMarkup: keyboard);

Reply Keyboard

var keyboard = ReplyKeyboard.Create()
    .AddRow("📦 Orders", "👤 Profile")
    .AddRow("⚙️ Settings", "❓ Help")
    .ResizeKeyboard()
    .WithPlaceholder("Choose an option…")
    .Build();

await bot.SendMessageAsync(chatId, "Main menu:", replyMarkup: keyboard);

Remove Keyboard

var remove = ReplyKeyboardRemoveMarkup.Create();
await bot.SendMessageAsync(chatId, "Keyboard dismissed.", replyMarkup: remove);

Handling Callback Queries

// Inside your update handler:
if (update.CallbackQuery is { } query)
{
    await bot.AnswerCallbackQueryAsync(query.Id, "Processing…");

    // ... handle query.Data

    await bot.EditMessageTextAsync(
        query.Message!.Chat.Id,
        query.Message.MessageId,
        "Done!");
}

File Uploads

// Upload a photo from a stream
await using var stream = File.OpenRead("report.png");
await bot.SendPhotoAsync(chatId, stream, "report.png", caption: "Monthly report");

// Upload a document
await using var pdf = File.OpenRead("invoice.pdf");
await bot.SendDocumentAsync(chatId, pdf, "invoice.pdf", caption: "Invoice #42");

// Re-use an existing file_id (no re-upload)
await bot.SendPhotoAsync(chatId, existingFileId, caption: "Cached photo");

Downloading Files

var fileInfo = await bot.GetFileAsync(fileId);
await using var dest = File.Create("download.jpg");
await bot.DownloadFileAsync(fileInfo.FilePath!, dest);

Webhooks

// Register webhook
await bot.SetWebhookAsync("https://yourdomain.com/bot/webhook", new SetWebhookParameters
{
    MaxConnections = 40,
    AllowedUpdates = [UpdateTypes.Message, UpdateTypes.CallbackQuery],
    SecretToken = "my-secret-token",
    DropPendingUpdates = true
});

// Check status
var info = await bot.GetWebhookInfoAsync();
Console.WriteLine($"Pending: {info.PendingUpdateCount}, Active: {info.IsActive}");

// Remove webhook (switch to long-polling)
await bot.DeleteWebhookAsync(dropPendingUpdates: true);

Minimal API webhook endpoint

app.MapPost("/bot/webhook", async (
    TelegramUpdate update,
    ITelegramBotClient bot,
    CancellationToken ct) =>
{
    if (update.Message?.Text is { } text)
        await bot.SendMessageAsync(update.Message.Chat.Id, $"Echo: {text}", ct: ct);
    return Results.Ok();
});

Long-Polling with UpdateDispatcher

var dispatcher = new UpdateDispatcher(bot, loggerFactory.CreateLogger<UpdateDispatcher>());

dispatcher.OnMessage += async (msg, ct) =>
{
    if (msg.Text == "/start")
        await bot.SendMessageAsync(msg.Chat.Id, "Welcome!", ct: ct);
};

dispatcher.OnCallbackQuery += async (query, ct) =>
{
    await bot.AnswerCallbackQueryAsync(query.Id, $"You pressed: {query.Data}", ct: ct);
};

dispatcher.OnError += (ex, _) =>
{
    Console.Error.WriteLine($"Handler error: {ex.Message}");
    return Task.CompletedTask;
};

await dispatcher.StartAsync(cancellationToken);

Chat Actions

// Show "typing…" indicator while processing
await bot.SendChatActionAsync(chatId, "typing");

Supported actions: typing, upload_photo, record_video, upload_video, record_voice, upload_voice, upload_document, choose_sticker, find_location, record_video_note, upload_video_note.


Error Handling

All API errors throw TelegramBotException:

try
{
    await bot.SendMessageAsync(chatId, text);
}
catch (TelegramBotException ex) when (ex.IsRateLimited)
{
    var delay = ex.RetryAfter ?? 5;
    await Task.Delay(TimeSpan.FromSeconds(delay));
    // retry…
}
catch (TelegramBotException ex) when (ex.IsForbidden)
{
    // User blocked the bot — remove from your DB
}
catch (TelegramBotException ex)
{
    logger.LogError("Telegram error {Code}: {Message}", ex.ErrorCode, ex.Message);
}

API Reference

Method Description
GetMeAsync Fetch bot identity
SendMessageAsync Send a text message
EditMessageTextAsync Edit a previously sent message
DeleteMessageAsync Delete a message
ForwardMessageAsync Forward a message between chats
SendPhotoAsync Send a photo (stream or file_id/URL)
SendDocumentAsync Send a file (stream or file_id/URL)
SendChatActionAsync Show typing/uploading indicator
AnswerCallbackQueryAsync Answer inline keyboard callbacks
GetUpdatesAsync Long-poll for updates
SetWebhookAsync Register a webhook URL
DeleteWebhookAsync Remove the webhook
GetWebhookInfoAsync Get webhook status
GetFileAsync Get file metadata for download
DownloadFileAsync Stream a file to a local Stream

License

MIT © 2025 Vladyslav Zaiets — sarmkadan.com

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 100 5/3/2026