TelegramNotifier 2.0.0
dotnet add package TelegramNotifier --version 2.0.0
NuGet\Install-Package TelegramNotifier -Version 2.0.0
<PackageReference Include="TelegramNotifier" Version="2.0.0" />
<PackageVersion Include="TelegramNotifier" Version="2.0.0" />
<PackageReference Include="TelegramNotifier" />
paket add TelegramNotifier --version 2.0.0
#r "nuget: TelegramNotifier, 2.0.0"
#:package TelegramNotifier@2.0.0
#addin nuget:?package=TelegramNotifier&version=2.0.0
#tool nuget:?package=TelegramNotifier&version=2.0.0
TelegramNotifier
A lightweight .NET library for sending logs and exceptions to Telegram with support for queuing, retries, and background processing.
Key Features
- Sending messages to Telegram with log level prefixes
- Automatic exception reporting via middleware
- Long messages sent as
.txtfile attachments (> 2000 chars) - Support for Telegram forum topics (
MessageThreadId) - Asynchronous queue processing (Channel + BackgroundService)
- Resilient delivery: exponential backoff + rate-limit handling
- Exception type filtering
- Duplicate throttling — suppresses repeated exceptions within a time window
- App name and environment included in notifications automatically
- Custom exception formatter
Supported Platforms
- .NET 6
- .NET 7
- .NET 8
- .NET 9
Installation
dotnet add package TelegramNotifier
See CHANGELOG.md for version history.
Registration
Three ways to register — pick the one that fits your setup.
1. From code only
builder.Services.AddTelegramNotifier(options =>
{
options.BotToken = "YOUR_BOT_TOKEN";
options.ChatId = "-100XXXXXXXXXX";
options.Enabled = true;
});
2. From appsettings.json
{
"TelegramNotifier": {
"Enabled": true,
"BotToken": "YOUR_BOT_TOKEN",
"ChatId": "-100XXXXXXXXXX",
"MessageThreadId": 6
}
}
builder.Services.AddTelegramNotifier(
builder.Configuration.GetSection("TelegramNotifier"));
3. From appsettings.json + override from code
builder.Services.AddTelegramNotifier(
builder.Configuration.GetSection("TelegramNotifier"),
options =>
{
options.DuplicateThrottleWindow = TimeSpan.FromMinutes(5);
options.ExcludedExceptionTypes.Add(typeof(OperationCanceledException));
});
Configuration options
| Parameter | Type | Default | Description |
|---|---|---|---|
BotToken |
string |
— | Telegram bot token |
ChatId |
string |
— | Target chat or group ID |
Enabled |
bool |
true |
Master switch — set to false to silence all sending |
MessageThreadId |
int? |
null |
Topic ID for forum groups |
MaxRetryCount |
int |
3 |
Max retry attempts on HTTP failure |
ApplicationName |
string? |
auto | App name shown in notifications (auto-filled from host) |
EnvironmentName |
string? |
auto | Environment shown in notifications (auto-filled from host) |
DuplicateThrottleWindow |
TimeSpan |
Zero |
Suppress duplicate exception types within this window |
ExcludedExceptionTypes |
ICollection<Type> |
[] |
Exception types (and subclasses) to never send |
ExceptionFormatter |
Func<Exception, HttpContext?, string>? |
null |
Custom formatter for exception body |
Middleware — automatic exception reporting
Add to capture all unhandled exceptions automatically:
app.UseTelegramNotifier();
Usage
Send a message with log level
await _notifier.SendMessageAsync("Server started"); // 🟢 [INFO]
await _notifier.SendMessageAsync("Queue is 80% full", LogLevel.Warning); // 🟡 [WARN]
await _notifier.SendMessageAsync("Database unavailable", LogLevel.Error); // 🔴 [ERROR]
await _notifier.SendMessageAsync("Service crashed", LogLevel.Critical); // 🚨 [CRIT]
Send an exception manually
try
{
// ...
}
catch (Exception ex)
{
await _notifier.SendExceptionAsync(ex);
}
Inject into a controller
public class OrdersController : ControllerBase
{
private readonly ITelegramNotifier _notifier;
public OrdersController(ITelegramNotifier notifier)
{
_notifier = notifier;
}
[HttpPost]
public async Task<IActionResult> Create(OrderDto dto)
{
await _notifier.SendMessageAsync($"New order: {dto.Id}", LogLevel.Information);
return Ok();
}
}
Exception filtering
Suppress specific exception types (including subclasses):
options.ExcludedExceptionTypes.Add(typeof(OperationCanceledException));
options.ExcludedExceptionTypes.Add(typeof(BadHttpRequestException));
Duplicate throttling
Prevent the same exception type from flooding Telegram:
options.DuplicateThrottleWindow = TimeSpan.FromMinutes(5);
One notification per exception type per 5 minutes.
Custom exception formatter
Override the default exception body format:
options.ExceptionFormatter = (ex, ctx) =>
$"Error: {ex.Message}\nPath: {ctx?.Request.Path}\nTime: {DateTime.UtcNow}";
If the result exceeds 2000 characters it is sent as a .txt file — the caption stays auto-generated.
Security
- Never store
BotTokenin source code - Use
appsettings.json, environment variables, or a secrets manager
How to get ChatId
Private chat with the bot
- Send any message to your bot
- Open:
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates - Find
"chat": { "id": 123456789 }— that is yourChatId
Group
- Add the bot to the group and send a message
- Open the same
getUpdatesURL - Find
"chat": { "id": -1001234567890 }— group IDs are negative
Forum group (topics)
ChatId— the group IDMessageThreadId— the topic ID (visible in the URL when you open a topic)
If
getUpdatesreturns nothing, make sure no webhook is set:https://api.telegram.org/bot<YOUR_BOT_TOKEN>/deleteWebhook
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
-
net6.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Hosting (>= 6.0.0)
- Microsoft.Extensions.Http (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
-
net7.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Hosting (>= 6.0.0)
- Microsoft.Extensions.Http (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
-
net8.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Hosting (>= 6.0.0)
- Microsoft.Extensions.Http (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
-
net9.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.Extensions.Hosting (>= 6.0.0)
- Microsoft.Extensions.Http (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
See full changelog: https://github.com/bekov0004/TelegramNotifier/blob/main/CHANGELOG.md