NAME
Langertha::Raider::Hall::Telegram - Internal multi-bot Telegram long-poll adapter for the raider hall
VERSION
version 0.504
DESCRIPTION
Internal module. Its interface may change without notice.
Long-polls every Telegram bot configured for a Langertha::Raider::Hall, routes incoming messages to raiders and sends replies.
Access is fail-closed and checked per message:
telegram:
bots:
ops:
token: '...'
allowlist: [1234567890] # Telegram user ids (message.from.id)
allowed_chats: [-1001234567890] # optional: group chats to answer in
A message is accepted only when its sender (from.id) is in allowlist and its chat is either the private chat with that sender or listed in allowed_chats. An empty or missing allowlist accepts nobody. Rejected messages emit a telegram.rejected event and are neither stored nor routed.
A routed message runs in the session bound to its chat -- telegram:BOT:CHAT_ID, with :THREAD for a forum topic -- so the conversation continues across messages (see "session_bindings" in Langertha::Raider::Hall). The raider's telegram_reply answers into the same chat and forum topic.
A mission the hall refuses (raider.refused, see "EVENT BUS" in Langertha::Raider::Hall) -- at once or when it is pulled from a queue -- is answered in its chat and topic with the short mission not started (configuration), see the hall log; the reason stays in the event and the slot log.
/new (or /new@BOTNAME) from an accepted sender is not a mission: the chat's (topic's) next message starts a new session, and the bot confirms with a short message. The old journal stays.
When a module the https connection to the Bot API needs does not load (IO::Async::SSL and what it needs, see Langertha::Raider::ConnectCheck), a bot does not poll: the hall warns and emits telegram.poll_error with the module's name, and a reply is an error result. Nothing is sent, so nothing waits for a connection that cannot open.
Poll errors. Every getUpdates answer that is not a usable result emits telegram.poll_error with the bot, the HTTP status (when there was an answer) and an error of the form HTTP 409: description, and the bot polls again only after a wait, never at once:
a non-2xx status, or
ok: falsein the body, is an error answer;a 2xx answer whose body cannot be read as the Bot API's JSON object (
HTTP 200: unreadable response) counts as an error answer as well, and no update of it is handled;a failure of the request itself (network, TLS, timeout) emits the event without a
status;429waits theretry_afterseconds Telegram sent; every other failure waits 5 s, doubling with each consecutive one up to 300 s, and the wait starts over after an answer that was usable;401(the token is wrong or revoked) stops the bot with a warning instead of retrying;the bot's token is masked (
***) in the reportederror.
An update whose handling dies does not stop the loop: it emits telegram.update_error with the bot, the update_id and the error, and polling continues with the offset behind that update.
SUPPORT
Issues
Please report bugs and feature requests at https://github.com/Getty/langertha-raider/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.