Deployment¶
TeleFlow deployment is normal .NET deployment. The framework does not require a custom process model.
Choose the transport first:
- long polling: one long-running worker owns
getUpdates; - webhooks: ASP.NET Core receives HTTPS requests from Telegram;
- raw transports: your application owns dispatching, queueing, and acknowledgement semantics.
Long Polling Worker¶
Long polling is easiest to deploy as a worker process. In a normal .NET worker, use IWF.TeleFlow.Framework.Hosting and let the Generic Host own startup, shutdown, logging, and cancellation:
using Microsoft.Extensions.Hosting;
using TeleFlow.Framework.Hosting;
using TeleFlow.Telegram;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddTelegramBot(options => options.Token = token);
builder.Services.AddTelegramHandlersFromAssembly(typeof(Program).Assembly);
builder.Services.AddLongPolling();
builder.Services.AddTeleFlowHostedService();
await builder.Build().RunAsync();
The hosted service creates the TeleFlow application from the host service provider. It does not create a second DI container and does not dispose the host-owned provider.
For a smaller console process without Generic Host, run the TeleFlow application directly:
var builder = TeleFlowApplication.CreateBuilder(args);
builder.Services.AddTelegramBot(options => options.Token = token);
builder.Services.AddTelegramHandlersFromAssembly(typeof(Program).Assembly);
builder.Services.AddLongPolling();
await using var app = builder.Build();
await app.RunAsync();
Operational rules:
- run one active long polling worker per bot token unless you intentionally coordinate workers;
- make handlers idempotent where possible;
- pass cancellation from the host;
- use durable state storage before multi-instance or restart-sensitive workflows;
- keep logs searchable by update id, chat id, handler, and exception type.
Webhook App¶
Webhook deployment is an ASP.NET Core app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTelegramBot(options => options.Token = token);
builder.Services.AddTelegramHandlersFromAssembly(typeof(Program).Assembly);
builder.Services.AddWebhook(options =>
{
options.Path = "/telegram/webhook";
options.SecretToken = webhookSecret;
});
var app = builder.Build();
app.MapTelegramWebhook();
await app.RunAsync();
Do not add AddTeleFlowHostedService() to webhook apps. Webhooks are driven by ASP.NET Core endpoint routing; the process lifetime is already owned by WebApplication.
Operational rules:
- expose HTTPS;
- keep the webhook path stable;
- configure Telegram webhook URL outside the request handler;
- validate
SecretToken; - keep request handling short;
- move long-running work behind your own queue when needed.
Configuration¶
Production tokens should come from the platform, not from committed files:
options.Token = configuration["Telegram:BotToken"]
?? throw new InvalidOperationException("Telegram:BotToken is not configured.");
Use environment variables, secret managers, CI/CD variables, Docker secrets, Kubernetes secrets, or your cloud provider's secret storage.
See Configuration and secrets.
Docker¶
A TeleFlow bot can be published like any .NET app:
For containers:
- pass the token through environment or secrets;
- do not bake secrets into the image;
- send logs to stdout/stderr;
- configure graceful shutdown;
- avoid memory storage for workflows that must survive container restarts.
Long polling containers should usually run as one replica per bot token. Webhook containers can scale horizontally if your handlers and storage are safe for concurrency.
Lifecycle Tasks In Production¶
TeleFlow startup and shutdown tasks run per application instance:
builder.Services.AddTeleFlowStartupTask<ConfigureBotCommands>();
builder.Services.AddTeleFlowShutdownTask<FlushMetrics>();
Good startup task examples:
- configure Telegram bot commands;
- warm local caches;
- validate required external dependencies;
- prepare process-local resources.
Bad startup task examples:
- non-idempotent database migrations;
- global resource creation without a distributed lock;
- long-running background loops;
- work that should belong to deployment infrastructure.
In multi-replica deployments, every replica runs the same startup tasks. Keep them idempotent or guard them with infrastructure-level coordination. Shutdown tasks run after the update source stops and should stay short enough to fit the platform's graceful shutdown window.
systemd¶
For a small Linux host, run long polling under systemd:
[Service]
WorkingDirectory=/opt/teleflow-bot
ExecStart=/usr/bin/dotnet /opt/teleflow-bot/MyBot.dll
Restart=on-failure
Environment=Telegram__BotToken=123456:ABC
Keep secrets in an environment file with restricted permissions when possible.
Kubernetes¶
For Kubernetes:
- use a
Deploymentfor webhook apps; - use one replica for long polling unless worker coordination exists;
- store tokens in
Secret; - expose webhooks through ingress with TLS;
- use readiness/liveness probes for ASP.NET Core webhook apps;
- use external storage for state.
Pending Updates¶
Telegram can keep updates while the bot is offline. With long polling, pending updates can be delivered after restart.
Current public TeleFlow docs do not claim a drop_pending_updates option. Until such an API exists, treat startup behavior as an operational decision:
- handlers should tolerate duplicate or delayed user actions;
- critical flows should be idempotent;
- deployments should avoid long downtime;
- if old updates are harmful for your product, plan a release task for explicit drop-pending support before production launch.
Release Checklist¶
Before production:
- generated registration is used or reflection use is documented;
IWF.TeleFlow.Generatorsis private;- token and webhook secret are not committed;
- transport choice is documented;
- state storage is suitable for the deployment topology;
- logs and errors are observable;
- CI runs build and tests;
- smoke test covers
/start, one callback, one state flow, and one Telegram API call.