Navigation: Project README · Engineering Reference · Integrations
Telegram is part of the unified notifications subsystem.
Runtime flow:
- runtime settings are stored in
RTC::NotificationData NotificationSettingsServiceexposes those settings over HTTP and persists themTelegramNotifierqueues outbound messagesNotificationWorkerdrives actual delivery and optional inbound pollingTelegramWorkerusesTelegramClientfor HTTPS calls and command polling- command handlers live in
src/notifications/telegram/commands/
The normal operating path is runtime configuration through the notifications API and UI.
The main settings endpoint is:
GET /api/notifications/settingsPOST /api/notifications/settings
Authentication: admin.
Relevant Telegram fields:
telegram_enabledbot_tokenchat_idcommands_enabled
Important behavior from the current implementation:
chat_idis treated as read-only from the frontend side.chat_idis auto-discovered from the first incoming Telegram message and then persisted.- changing
bot_tokenclearschat_id, forcing discovery again. - every settings change is applied in RTC immediately and persisted to LittleFS through
CONFIG::save(...).
Factory fallback values still exist in src/config/App.h, but routine operation should
be managed through the runtime notifications settings.
Outbound Telegram delivery goes through:
NotificationSettingsServiceTelegramNotifierTELEGRAM::MessageQueueNotificationWorkerTelegramWorker::processOutbound()TelegramClient
Practical consequence:
- having only
bot_tokenis enough for Telegram to be considered "enabled/configured" by settings - actual outbound delivery also needs a valid
chat_id - the normal way to obtain
chat_idis to send any message to the bot once and let the firmware auto-discover it
Inbound polling is only active when at least one of these is true:
commands_enabledis truechat_idstill needs auto-discovery
Command dispatch is implemented under src/notifications/telegram/commands/ and uses
the shared CommandRegistry.
The test route is:
POST /api/notifications/telegram/test
Authentication: admin.
Request body:
{
"text": "debug test"
}The backend accepts message as a compatibility alias for text.
Current behavior is intentionally asynchronous:
- the HTTP handler validates input
- spawns a background task
- returns immediately
Typical success response:
{
"ok": true,
"status": "queued"
}Important implication:
- this endpoint confirms that the test task was queued
- it does not wait for Telegram's final HTTP response
- delivery failures must be diagnosed through serial logs and runtime behavior, not from the immediate HTTP response alone
Telegram delivery is intentionally strict.
Before sending or polling, the firmware requires:
- Wi-Fi mode is not
WIFI_OFF - Wi-Fi is connected
- DNS resolution for
api.telegram.orgsucceeds - TCP connect to
api.telegram.org:443succeeds - system time is in a valid year window
Those checks are implemented in src/notifications/telegram/client/TelegramConnectionValidator.cpp.
The code supports two TLS modes:
- insecure TLS via
setInsecure() - Root CA validation via a pinned PEM certificate
Project nuance:
src/config/App.hdefinesTELEGRAM_TLS_VERIFYdefault as0- the current
platformio.inifor this project overrides it to-DTELEGRAM_TLS_VERIFY=1
So for the current firmware environment, certificate verification is enabled.
Verification is implemented in src/notifications/telegram/client/TelegramTlsConfig.cpp
using a pinned Root CA, not a CA bundle. That keeps firmware size under control on this
target.
The most relevant runtime failure reasons are:
offline/wifi_offoffline/wifi_not_connectedoffline/dns_failedoffline/tcp_connect_failedoffline/time_invalid
Common API-layer failures for the test route:
- empty
text/message busy/telegram_test_in_progress- task allocation / task creation failure
If Telegram is enabled but nothing is sent, check in this order:
- Is
telegram_enabledtrue? - Is
bot_tokenset? - Has
chat_idalready been discovered or configured? - Does the device have internet and valid time?
- Do serial logs show TLS or Telegram HTTP failures?
- Read current settings from
/api/notifications/settings. - If
chat_idis empty, send a message to the bot from the target chat. - Trigger
/api/notifications/telegram/test. - Inspect serial logs for online-check, TLS, or Telegram API failures.
Use this document as the current operating model. Historical compile-time-only guidance is obsolete for this repo.
Navigation: Project README · Engineering Reference · Integrations