@flatscout/notifier-telegram
v1.0.0
Published
A Flatscout **notifier** plugin that delivers scored listing events to a Telegram chat. Built on [grammY](https://grammy.dev), it sends a compact Markdown-like card per `ListingEvent` with inline URL buttons linking to the listing and (when available) its
Readme
@flatscout/notifier-telegram
What it is
A Flatscout notifier plugin that delivers scored listing events to a
Telegram chat. Built on grammY, it sends a compact
Markdown-like card per ListingEvent with inline URL buttons linking to
the listing and (when available) its first photo.
The plugin is send-only: it pushes one message per event via
bot.api.sendMessage and does not register update handlers, webhooks,
long-polling, or any callback-query routing. Telegram is treated as a
notification sink, not an interactive surface.
Install & enable
The plugin is part of the Flatscout monorepo and ships as
@flatscout/notifier-telegram. Enable it in your config.yaml:
notifiers:
- name: telegram
plugin: notifier-telegram
enabled: true
config:
bot_token: "${env.TELEGRAM_BOT_TOKEN}"
chat_id: "${env.TELEGRAM_CHAT_ID}"
format: compactSet the two env vars in your environment (see "Credentials / auth"
below) and run flatscout start. Each scored event above your
notify-threshold will produce one Telegram message in the target chat.
Configuration reference
| Key | Type | Default | Description |
| --- | --- | --- | --- |
| bot_token | string | ${env.TELEGRAM_BOT_TOKEN} | Bot API token issued by @BotFather. Required. |
| chat_id | string | number | ${env.TELEGRAM_CHAT_ID} | Target chat id (user, group, or channel). Required. |
| format | enum (compact | verbose) | compact | Card style. Only compact is rendered today; verbose is reserved. |
Both bot_token and chat_id support env interpolation via the standard
${env.VAR} syntax. The plugin fails fast at notify() time if either
value is still an unresolved placeholder.
Credentials / auth
The plugin needs two pieces of information:
TELEGRAM_BOT_TOKEN
Open Telegram and start a chat with @BotFather.
Send
/newbotand follow the prompts (display name + unique username ending inbot).BotFather replies with an API token. Export it (or put it in your project-root
.env):export TELEGRAM_BOT_TOKEN="<your-token>"Treat this token as a secret — anyone holding it can send messages as your bot. Rotate via
/revokein BotFather if leaked.
TELEGRAM_CHAT_ID
The chat id identifies where the bot will post. To obtain it:
Personal DM — start a chat with your bot, send any message, then fetch the most recent update:
curl "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" \ | jq '.result[-1].message.chat.id'The returned integer (positive) is your personal chat id.
Group chat — add the bot to the group, send a message that mentions it (e.g.
/start@your_bot), then callgetUpdatesas above. Group chat ids are negative (e.g.-100123...).Channel — make the bot a channel admin, post a message, then call
getUpdates(or use a helper like @userinfobot). Channel ids are also negative.
Export it (or put it in your project-root .env):
export TELEGRAM_CHAT_ID="<your-chat-id>"The plugin accepts both string and numeric ids.
Examples
Minimal config (env-driven, recommended):
notifiers:
- name: telegram
plugin: notifier-telegram
enabled: true
config: {}(bot_token and chat_id fall back to their ${env.*} defaults.)
Hard-coded chat id for a shared family group:
notifiers:
- name: family-tg
plugin: notifier-telegram
enabled: true
config:
bot_token: "${env.TELEGRAM_BOT_TOKEN}"
chat_id: -1001234567890Multiple Telegram destinations from a single bot (e.g. a personal DM plus a shared group):
notifiers:
- name: tg-me
plugin: notifier-telegram
enabled: true
config:
bot_token: "${env.TELEGRAM_BOT_TOKEN}"
chat_id: "${env.TELEGRAM_CHAT_ID_ME}"
- name: tg-family
plugin: notifier-telegram
enabled: true
config:
bot_token: "${env.TELEGRAM_BOT_TOKEN}"
chat_id: "${env.TELEGRAM_CHAT_ID_FAMILY}"Troubleshooting
telegram bot_token unresolved (set TELEGRAM_BOT_TOKEN env)— the${env.TELEGRAM_BOT_TOKEN}placeholder was never substituted. Export the env var before launching Flatscout, or setbot_tokenliterally in config.telegram chat_id unresolved (set TELEGRAM_CHAT_ID env)— same as above forTELEGRAM_CHAT_ID.GrammyError: Forbidden: bot was blocked by the user— the recipient blocked the bot in Telegram. Unblock the bot or pick a differentchat_id.GrammyError: Bad Request: chat not found— wrongchat_id, or the bot is not a member of the target group/channel. For channels, ensure the bot is an admin. Re-run thegetUpdatesflow above.GrammyError: Unauthorized— the token is wrong or has been revoked. Generate a new one via @BotFather (/token).- No messages arrive, no error in logs — confirm the scorer is emitting events above the configured notify threshold. The notifier only fires for events that reach it; it does not silently drop.
- HTTP 429 /
Too Many Requests— Telegram rate-limits per-chat at ~1 msg/sec and ~20 msg/min in groups. The orchestrator's per-notifier circuit breaker will pause the sink on repeated failures; reduce scan frequency or raise the notify threshold.
Attribution
- grammY — modern Telegram Bot framework for Deno & Node.js, MIT licensed.
- Telegram Bot API — official
HTTP API used via
bot.api.sendMessage.
License
MIT, matching the rest of the Flatscout project.
