Wiki
猫Table of Contents
- Webhook Runtime
- When to use webhook runtime
- Entry points
- What the bot-level runtime owns
- Runtime guarantees shared with polling
- Main webhook options
- URL
- Path
- LocalPort
- SecretToken
- AllowedUpdates
- MaxConnections
- DropPendingUpdates
- Certificate
- UseStatusPath
- IPAddress
- HTTP and TLS behavior
- Request handling behavior
- Security and exposure guidance
- Relation to tgapi webhook methods
- Common mistakes
- Related pages
Webhook Runtime
Russian version: Webhook-Runtime-RU
This page explains the bot-level webhook runtime in Laniakea: how RunWebhookWithContext(...) works, what it owns, how it differs from low-level tgapi webhook calls, and what runtime guarantees it shares with polling mode.
Important naming note:
- the current public API uses the historical
WebHookspelling in identifiers such asRunWebhookWithContext(...),RunWebhook(...), andBotWebhookOpts; - this page uses the more common English term "webhook" for readability, but examples keep the actual Go API names.
When to use webhook runtime
Use webhook runtime when Telegram should push updates to your bot over HTTP instead of your bot pulling updates through long polling.
This is usually a good fit when:
- your bot runs behind a stable public HTTPS endpoint;
- you already have reverse-proxy or ingress infrastructure;
- you want Telegram to deliver updates directly instead of keeping a polling loop open.
Use polling when:
- you want the simplest local or small-server setup;
- you do not want to expose an incoming HTTP endpoint;
- you do not need webhook-style deployment.
Entry points
The main bot-level entry points are:
RunWebhookWithContext(ctx, opts, tlsFiles...)RunWebhook(opts, tlsFiles...)NewBotWebhookOpts()
RunWebhook(...) is only a shorthand for RunWebhookWithContext(context.Background(), ...).
The usual pattern looks like:
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
bot, err := laniakea.NewBot[*App](opts)
if err != nil {
return err
}
defer bot.Close()
bot.SetAppData(app)
bot.AddPlugins(plugin)
webhookOpts := laniakea.NewBotWebhookOpts().
SetURL("https://bot.example.com").
SetPath("/telegram").
SetLocalPort(8080).
SetSecretToken("shared-secret")
if err := bot.RunWebhookWithContext(ctx, webhookOpts); err != nil {
return err
}
What the bot-level runtime owns
RunWebhookWithContext(...) is more than a wrapper around Telegram's setWebhook.
It:
- validates bot startup preconditions such as prefixes and registered plugins;
- keeps the same single-use runtime model as polling;
- starts registered runners;
- configures Telegram webhook delivery;
- starts a local HTTP server owned by the bot;
- accepts incoming updates and feeds them into the same internal queue and worker pool used by polling;
- shuts down gracefully when
ctx.Done()fires.
This means webhook mode is part of the main runtime model, not just a low-level transport setting.
Runtime guarantees shared with polling
Webhook runtime shares the same main guarantees as RunWithContext(...):
- the bot is single-use;
- updates go through the internal queue;
BotOpts.MaxWorkersstill controls concurrent handler execution;- runners start at runtime entry, not at
NewBot(...); - shutdown drains already accepted work before returning;
Close()is still required afterward to release local resources.
If you already understand Bot-Lifecycle, the webhook mode should feel like a different update ingress path, not a second framework.
Main webhook options
BotWebhookOpts controls both Telegram webhook registration and the local server behavior.
Fields you will care about first:
URL
This is the public base URL Telegram will call.
If:
URL == "https://bot.example.com"Path == "/telegram"
then Telegram is registered with:
https://bot.example.com/telegram
URL is required.
Path
This is the local HTTP path the bot serves.
Use it to keep webhook traffic off / and make reverse-proxy routing explicit.
LocalPort
This is the local server port the bot binds to.
Common deployment pattern:
- public TLS terminates at a reverse proxy;
- the bot itself listens on an internal HTTP port such as
8080.
SecretToken
This is the shared secret expected in Telegram's X-Telegram-Bot-Api-Secret-Token header.
You should almost always set it.
Without it, the endpoint still works, but the bot has to trust that only Telegram reaches that path.
AllowedUpdates
If you call SetAllowedUpdates(...) explicitly, those update kinds are registered for webhook delivery.
If you leave it empty, Laniakea falls back to the bot's configured update types from:
SetUpdateTypes(...)AddUpdateType(...)
That keeps webhook mode aligned with the rest of your bot configuration by default.
MaxConnections
This maps to Telegram's webhook max_connections setting.
Laniakea currently enforces the Telegram 1..100 range before startup.
DropPendingUpdates
Use this when you want Telegram to discard already queued updates while replacing the webhook.
This is a deployment decision, not a normal runtime requirement.
Certificate
Set this when you need to upload a self-signed certificate to Telegram.
The bot then uses uploader-based webhook registration internally.
UseStatusPath
If enabled, the bot also serves /status, which returns the current Telegram webhook info as JSON.
This endpoint requires a non-empty SecretToken. Laniakea rejects startup if you enable /status without setting one.
Treat this as an operational endpoint, not a public user-facing route.
IPAddress
Use this only when you specifically need Telegram's ip_address webhook option.
HTTP and TLS behavior
By default, RunWebhookWithContext(...) starts a plain HTTP server on LocalPort.
If you pass two TLS files, it starts HTTPS locally instead.
Important:
- the current public API expects the existing key-then-cert argument order when calling
RunWebhookWithContext(...); - that differs from the more common
cert, keymental model many Go developers expect fromListenAndServeTLS.
Be explicit in your own setup code so this does not become a deployment footgun.
Request handling behavior
The built-in webhook server currently:
- accepts only
POST; - optionally validates
X-Telegram-Bot-Api-Secret-Token; - decodes the incoming Telegram
Update; - enqueues the update into the normal bot runtime;
- returns
200 OKafter successful enqueue.
If enqueue fails because runtime is shutting down, the server returns 503.
The important design point is that webhook mode does not run handlers inline inside the HTTP request. It hands accepted updates to the same queue and worker pool model used elsewhere.
Security and exposure guidance
At minimum:
- set
SecretToken; - keep the webhook path specific, not guessable by accident;
- expose
/statusonly when you actually need it; - prefer putting the bot behind a real reverse proxy or ingress layer.
Also keep in mind:
URLis what Telegram sees;PathandLocalPortare what your bot actually serves;- these are often not the same thing in production.
- if you switch a running deployment from webhook mode to polling, delete the webhook first with
CloseWebhook()ortgapi.DeleteWebhook(...); Telegram does not stop webhook delivery automatically.
Relation to tgapi webhook methods
Use bot-level webhook runtime when you want Laniakea to own:
- webhook registration;
- the local HTTP server;
- update ingestion into the normal runtime queue;
- worker-pool dispatch and shutdown behavior.
Use lower-level tgapi calls such as:
SetWebhook(...)DeleteWebhook(...)GetWebhookInfo(...)Uploader.SetWebhook(...)
when you need custom infrastructure around the webhook path and do not want the bot to own the HTTP server itself.
In other words:
RunWebhookWithContext(...)is the framework runtime API;tgapiwebhook methods are the lower-level transport primitives.
Common mistakes
- Forgetting that webhook mode is still single-use per bot instance.
- Forgetting to call
Close()after runtime returns. - Switching from webhook mode to polling without deleting the webhook first.
- Mixing up public
URLwith localPathandLocalPort. - Omitting
SecretTokenin production-style deployments. - Assuming TLS file order follows the usual
cert, keyconvention. - Treating
/statuslike a harmless public endpoint.
Related pages
Navigation
Start here
Runtime and Architecture
- Bot-Lifecycle
- Webhook-Runtime
- Middleware
- Runners
- Error-Handling
- Logging
- Update-Routing-Model
- Policies
- Scenes
Interaction and Telegram API
- Inline-Keyboards-and-Payloads
- Auto-Generated-Commands
- Drafts
- Rich-Messages
- Localization
- Rate-Limiting
- tgapi-Overview