← All articles

Telegram Webhook Integration in .NET

May 22, 2026 · 14 min read

When a Telegram bot runs in production, long polling—constantly asking Telegram "any new messages?"—works, but it is not ideal. Webhooks flip the model: Telegram pushes each update to your HTTPS endpoint as soon as it happens. That means lower latency, cleaner scaling behind a load balancer, and a bot that lives naturally inside an ASP.NET Core app alongside your REST APIs.

This guide shows how to integrate Telegram webhooks in .NET: when to choose them, what Telegram requires, a complete ASP.NET Core example, local development with a tunnel, and practical use cases.

Prerequisite: If you have not created a bot yet, start with How to Build a Telegram Bot with C# for BotFather setup and Telegram.Bot basics.

What is a Telegram webhook?

With a webhook, you register a public HTTPS URL with Telegram. When a user sends a message, taps a button, or triggers any subscribed event, Telegram sends an HTTP POST to that URL with a JSON Update payload. Your server processes the update and calls the Bot API (for example sendMessage) to respond.

sequenceDiagram participant User participant Telegram participant App as ASP.NET_Core User->>Telegram: Send message Telegram->>App: POST /telegram/webhook (Update JSON) App->>Telegram: Bot API call (SendMessage) Telegram->>User: Bot reply

Your handler should return 200 OK quickly. Telegram may retry if the response is slow or missing—design for idempotency when side effects matter.

Webhook vs long polling

Aspect Long polling Webhook
Connection model Bot pulls updates (getUpdates) Telegram pushes updates to your URL
Hosting Any machine with outbound HTTPS Public HTTPS URL required
Latency Small poll interval delay Near-instant delivery
Scale One active poller per bot token Stateless handlers behind a load balancer
Local dev Simple (dotnet run) Needs a tunnel (ngrok, Cloudflare Tunnel)
Best for Prototyping, local testing Production, alerts, multi-instance deploys

The long-polling guide is the fastest way to get a bot running on your laptop. For 24/7 cloud deployment, webhooks are the production default.

When to use webhooks

Use webhooks when:

  • The bot runs 24/7 on Azure App Service, AWS, a VPS, or Kubernetes
  • You need low-latency delivery—alerts, support replies, transactional notifications
  • You want horizontal scaling: multiple app instances share one webhook URL behind a load balancer
  • The bot is part of a larger ASP.NET service—same host as REST APIs, background jobs, or admin dashboards

Stick with long polling when you are prototyping locally and do not want to expose a public URL yet.

Requirements

Before calling setWebhook, make sure you have:

  1. Valid HTTPS URL — Telegram requires HTTPS with a trusted certificate. Self-signed certs are rejected in normal setups.
  2. Bot token — from @BotFather. Load from environment variables, Azure Key Vault, or .NET user secrets—never commit tokens to source control.
  3. Secret token (recommended) — a random string you pass to setWebhook. Telegram sends it back in the X-Telegram-Bot-Api-Secret-Token header so you can reject forged requests.
  4. Reverse proxy awareness — if you terminate TLS at nginx, Azure Front Door, or Cloudflare, enable ASP.NET Core Forwarded Headers middleware so your app sees the correct scheme and client IP.

Complete example: ASP.NET Core webhook bot

This echo bot mirrors the long-polling tutorial but uses webhooks and ASP.NET Core minimal APIs.

Create the project

dotnet new web -n TelegramWebhookBot
cd TelegramWebhookBot
dotnet add package Telegram.Bot

Pin a local port in Properties/launchSettings.json:

"applicationUrl": "http://localhost:5140"

Configuration

Add to appsettings.Development.json:

{
  "Telegram": {
    "BotToken": "YOUR_BOT_TOKEN_HERE"
  }
}

Minimal API implementation

Update Program.cs:

using System.Text.Json;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<ITelegramBotClient>(_ =>
{
    var token = builder.Configuration["Telegram:BotToken"]
        ?? throw new InvalidOperationException("Bot token missing");

    return new TelegramBotClient(token);
});

var app = builder.Build();

app.MapGet("/", () => "Telegram bot is running");

app.MapPost("/telegram/webhook", async (
    Update update,
    ITelegramBotClient botClient,
    ILogger<Program> logger) =>
{
    try
    {
        if (update.Type == UpdateType.Message &&
            update.Message?.Text is not null)
        {
            var chatId = update.Message.Chat.Id;
            var text = update.Message.Text;

            logger.LogInformation("Message received: {Text}", text);

            await botClient.SendMessage(
                chatId: chatId,
                text: $"Echo: {text}");
        }

        return Results.Ok();
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Webhook processing failed");
        return Results.Problem();
    }
});

app.Run();

How it works

  • ITelegramBotClient — singleton client for Bot API calls (SendMessage, SetWebhook, etc.).
  • MapPost("/telegram/webhook") — ASP.NET Core deserializes the JSON body into an Update automatically.

Run API in cloud

Telegram cannot reach http://localhost:5140 directly. Create Azure Web App and deploy your app there:

dotnet build

dotnet publish -c Release -o publish

cd publish

zip -r app.zip .

az webapp deploy \
  --resource-group rg \
  --name telegram-webhook \
  --src-path app.zip

Register webhook in Telegram

Open browser:

https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook?url=https://<YOUR_SERVER>/telegram/webhook

Telegram should return:

{
  "ok": true,
  "result": true
}

Webhook registration uses Telegram setWebhook.

Test

Send a message to your bot in Telegram.

Your API receives:

{
  "update_id": 123456,
  "message": {
    "text": "hello"
  }
}

And replies:

Echo: hello

Useful Telegram API endpoints

Set webhook:

https://api.telegram.org/bot<BOT_TOKEN>/setWebhook?url=<URL>

Get webhook info:

https://api.telegram.org/bot<BOT_TOKEN>/getWebhookInfo

Delete webhook:

https://api.telegram.org/bot<BOT_TOKEN>deleteWebhook

Production checklist

  • Secrets — store BotToken in Key Vault or environment variables, not appsettings.json in the repo.
  • Return 200 quickly — offload heavy work (LLM calls, database writes, external APIs) to a background queue if processing takes more than a second or two.
  • Structured logging — log update.Id and chat.Id; avoid dumping full message bodies in production logs.
  • Idempotency — Telegram may retry failed deliveries; track processed update IDs if your handler has side effects.
  • TLS at the edge — terminate HTTPS at your ingress; do not expose plain HTTP publicly.

Use cases

Webhooks fit any scenario where Telegram is a real-time notification or interaction channel for your .NET backend.

  1. DevOps and SRE alerts — CI pipeline failures, deployment status, and monitoring thresholds pushed to a team channel. Your ASP.NET app receives GitHub/Azure DevOps webhooks and forwards summaries to Telegram.
  2. Customer support bot — inbound user messages arrive via webhook; your handler creates tickets in Jira, Zendesk, or a custom CRM and replies with a case number.
  3. E-commerce notifications — order confirmed, shipped, and delivered updates triggered from your order service without a polling loop.
  4. Internal command bot/deploy, /status, or /rollback commands parsed in the webhook handler and routed to internal APIs on the same host.
  5. Payment and fintech alerts — transaction confirmations and fraud flags delivered instantly; outbound API calls from the handler use proper auth and audit logging.
  6. IoT and edge alerts — device offline or threshold breach events from your telemetry pipeline forwarded to on-call engineers in Telegram.
  7. Lead capture — website form submission hits your API; the handler posts a formatted summary to a sales Telegram group.
  8. Multi-tenant SaaS — one ASP.NET service hosts multiple bots on different webhook paths (/telegram/webhook/{tenantId}), each with its own token and secret.

Webhook-driven alerting is a common pattern in API monitoring products—push a failure notification the moment a health check fails instead of waiting for the next poll cycle.

Troubleshooting

Symptom Likely cause
SetWebhook returns an error Invalid HTTPS certificate, URL not publicly reachable, or wrong port
No updates received Webhook not registered, wrong WebhookUrl, or firewall blocking Telegram
401 Unauthorized on webhook SecretToken mismatch between config and SetWebhook call
Duplicate replies Both polling and webhook active, or multiple instances without idempotency
Slow or timing out Handler does too much work synchronously—move to a background queue
Wrong scheme behind proxy Missing UseForwardedHeaders() — Telegram sees HTTP instead of HTTPS

Use GetWebhookInfo to inspect the registered URL, last error message, and pending update count:

var info = await bot.GetWebhookInfo();
Console.WriteLine($"URL: {info.Url}, LastError: {info.LastErrorMessage}");

Conclusion

Telegram webhooks turn your bot into a standard HTTP endpoint: Telegram pushes updates, your ASP.NET Core app handles them, and you scale like any other web service. Start with the echo example, tunnel locally for testing, then add secret token validation, background processing, and deployment behind HTTPS.

For the first bot and local prototyping, use How to Build a Telegram Bot with C# with long polling. When you deploy to the cloud, switch to webhooks with the pattern above.

Related articles