What it does
Watches crm.item.list for deals with id > lastSeenDealId and base stage NEW. For every new deal it loads the related contact (crm.item.get), formats an HTML card, and posts it to a Telegram chat via grammy. Provides /start and /status slash commands.
Stack
Node.js 18+, grammy, node-cron.
Install
pnpm add grammy node-cron
Environment
export B24_HOOK='https://your.bitrix24.com/rest/1/secret'
export TELEGRAM_BOT_TOKEN='...' # @BotFather
export TELEGRAM_CHAT_ID='...' # destination chat
Run
npx tsx 06-telegram-bot.ts
Source
skills/b24jssdk-recipes/examples/06-telegram-bot.ts.
Notes
lastSeenDealIdlives in memory — persist it to survive restarts.- For interactive actions (assign, mark as junk) extend with grammy's
InlineKeyboard. - HTML escaping is handled inline. If you change the message format keep
parse_mode: 'HTML'and escape user-controlled strings. - When the per-tick batch is large (lots of new deals at once), replace the per-deal
fetchContactNamecall with a singleactions.v2.batch.makethat fetches every contact in one round-trip. Example shape:actions.v2.batch.make({ calls: deals.map((d) => ['crm.item.get', { entityTypeId: 3, id: d.contactId }]) }).