Skip to main content

nestjs-telegraf

Build Telegram bots with NestJS using nestjs-telegraf (Telegraf v4 wrapper). Use when writing or reviewing bot update handlers, wiring TelegrafModule (forRoot/forRootAsync), using decorators (@Update, @Ctx, @Start, @Command, @On, @Hears, @Action, @InjectBot), scenes/wizard flows, middleware, handling group updates (new_chat_members/left_chat_member), mentioning users via message entities, batching mentions under Telegram limits, choosing long polling vs webhook, or handling Telegram errors and rate limits (429/flood). Triggers on "telegraf", "nestjs-telegraf", "@Update", "@Ctx", "telegram bot", "tag all", "mention users", "webhook", "flood control".

Zur Installation springen

Quellinformationen

Repository
1t1sCooL/zazyvala-bot
Letzte Quellaktivität
5. Juni 2026 um 09:33
Erkannte Sprache von SKILL.md
Englisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
nestjs-telegraf
description
Build Telegram bots with NestJS using nestjs-telegraf (Telegraf v4 wrapper). Use when writing or reviewing bot update handlers, wiring TelegrafModule (forRoot/forRootAsync), using decorators (@Update, @Ctx, @Start, @Command, @On, @Hears, @Action, @InjectBot), scenes/wizard flows, middleware, handling group updates (new_chat_members/left_chat_member), mentioning users via message entities, batching mentions under Telegram limits, choosing long polling vs webhook, or handling Telegram errors and rate limits (429/flood). Triggers on "telegraf", "nestjs-telegraf", "@Update", "@Ctx", "telegram bot", "tag all", "mention users", "webhook", "flood control".
metadata
{"author":"aif-skill-generator","version":"1.0","category":"backend"}
# nestjs-telegraf — Telegram bots on NestJS Production patterns for `nestjs-telegraf` (wraps **Telegraf v4**). Keep Telegram handlers thin: decode the update, call a domain service, reply. Business logic lives in injectable services, never in `@Update` classes. Package versions referenced: `nestjs-telegraf@^2.7`, `telegraf@^4.16`. ## 1. Module setup Always configure async with `ConfigService`. Token from env, never hard-coded. ```ts // app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { TelegrafModule } from 'nestjs-telegraf'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), TelegrafModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (config: ConfigService) => ({ token: config.getOrThrow<string>('BOT_TOKEN'), // dev: long polling. Omit `launchOptions` to default to polling. launchOptions: config.get('BOT_MODE') === 'webhook' ? { webhook: { domain: config.getOrThrow('BOT_WEBHOOK_DOMAIN'), path: '/telegram/webhook', }, } : undefined, // long polling }), }), BotModule, ], }) export class AppModule {} ``` - **Long polling** (dev): no public URL needed; `launchOptions` undefined. - **Webhook** (prod): set `launchOptions.webhook.domain` + `path`. Telegram pushes updates to `https://<domain><path>`. Set the webhook secret via Telegram and validate `X-Telegram-Bot-Api-Secret-Token` when terminating TLS yourself. - Use `TelegrafModule.forRootAsync` only; do not mix `forRoot` static token. ## 2. Update handlers (the thin layer) An `@Update()` class is a NestJS provider — full DI works. ```ts // bot.update.ts import { Update, Ctx, Start, Help, Command, On, Hears, InjectBot } from 'nestjs-telegraf'; import { Telegraf } from 'telegraf'; import { Context } from './context.interface'; import { SummonService } from '../summon/summon.service'; @Update() export class BotUpdate { constructor( @InjectBot() private readonly bot: Telegraf<Context>, private readonly summon: SummonService, // domain logic injected ) {} @Start() async onStart(@Ctx() ctx: Context) { await ctx.reply('Привет! Добавь меня в группу и используй /call для зова.'); } @Help() async onHelp(@Ctx() ctx: Context) { await ctx.reply('/call <текст> — позвать всех. /join — подписаться. /leave — отписаться.'); } @Command('call') // matches /call async onCall(@Ctx() ctx: Context) { await this.summon.callAll(ctx); // all logic in the service } @Hears(/^(зов|@all)/i) // regex on text async onHears(@Ctx() ctx: Context) { await this.summon.callAll(ctx); } @On('text') async onText(@Ctx() ctx: Context) { // track activity for opt-in registry, etc. } } ``` Define a typed `Context` once and reuse it everywhere: ```ts // context.interface.ts import { Context as TelegrafContext } from 'telegraf'; export interface Context extends TelegrafContext { // augment with session/scene types if used } ``` Decorator cheatsheet: | Decorator | Fires on | |-----------|----------| | `@Start()` / `@Help()` | `/start`, `/help` | | `@Command('name')` | `/name` | | `@Hears(string \| RegExp)` | text matches | | `@On('text' \| 'new_chat_members' \| 'callback_query' \| ...)` | update type | | `@Action(string \| RegExp)` | inline button `callback_query` data | | `@Ctx()` | injects the update context into a handler param | | `@Message()`, `@Sender()` | inject parts of the update | ## 3. Group membership tracking Telegram does not let a bot list all members. Build a registry from updates. ```ts @On('new_chat_members') async onJoin(@Ctx() ctx: Context) { const members = ctx.message?.new_chat_members ?? []; for (const u of members) { if (u.is_bot) continue; await this.members.upsert(ctx.chat.id, u); // persist via Prisma service } } @On('left_chat_member') async onLeave(@Ctx() ctx: Context) { const u = ctx.message?.left_chat_member; if (u) await this.members.markLeft(ctx.chat.id, u.id); } ``` Also upsert on any `@On('text')`/message to catch members who were already in the chat before the bot joined (opt-in by activity). Offer `/join` and `/leave`. ## 4. Mentioning users — the core of a "tag" bot Two ways to mention. See [references/mentions-and-batching.md](references/mentions-and-batching.md) for the full rationale and limits. - **@username** — works only if the user has a public username. Plain text `@durov` becomes a notifying mention automatically. - **text_mention entity** — works for anyone (even without a username) by linking to their user id. Required for reliable "tag everyone". ```ts // Build text + entities for users WITHOUT usernames: const name = 'Иван'; const text = `${name} `; const entities = [{ type: 'text_mention', offset: 0, length: [...name].length, // length in UTF-16 code units — see reference note user: { id: userId, is_bot: false, first_name: name }, }]; await ctx.telegram.sendMessage(chatId, text, { entities }); ``` **Batching is mandatory.** Telegram silently caps notifying mentions per message (~5 effectively notify) and messages are limited to 4096 chars / 100 entities. Split the member list into batches and send sequentially with a small delay. Full helper in [references/mentions-and-batching.md](references/mentions-and-batching.md). ## 5. Scenes & wizard (multi-step flows) Use scenes for setup dialogs (e.g. configuring a custom tag group). See [references/scenes.md](references/scenes.md) for the complete example. ```ts import { Scene, SceneEnter, On, Ctx } from 'nestjs-telegraf'; import { SceneContext } from 'telegraf/typings/scenes'; @Scene('create-group') export class CreateGroupScene { @SceneEnter() async enter(@Ctx() ctx: SceneContext) { await ctx.reply('Название группы тегов?'); } @On('text') async onName(@Ctx() ctx: SceneContext) { // save, then ctx.scene.leave() await ctx.scene.leave(); } } ``` Register `session()` middleware + `TelegrafModule` stage; details in the reference. ## 6. Middleware, guards, filters `nestjs-telegraf` supports NestJS guards, interceptors, pipes and exception filters on handlers. Use a guard for "who may summon" and a global Telegraf exception filter for API errors. ```ts bot.use(session()); // Telegraf middleware (for scenes) @UseGuards(CanSummonGuard) // NestJS guard on @Command('call') ``` ## 7. Errors & rate limits (429 / flood control) Telegram returns `429` with `parameters.retry_after` (seconds) under flood. Never hammer; respect `retry_after`. Wrap sends in a retry-with-backoff helper and use a small inter-batch delay. See [references/mentions-and-batching.md](references/mentions-and-batching.md) for `sendWithRetry`. Add a global catch filter: ```ts import { Catch, ArgumentsHost } from '@nestjs/common'; import { TelegrafArgumentsHost } from 'nestjs-telegraf'; @Catch() export class TelegrafExceptionFilter { async catch(err: unknown, host: ArgumentsHost) { const ctx = TelegrafArgumentsHost.create(host).getContext<Context>(); // log; optionally notify; never rethrow into the polling loop } } ``` ## Checklist when building a handler - [ ] Handler is thin; logic in an injected service. - [ ] Token & secrets from `ConfigService`, not literals. - [ ] Group updates (`new_chat_members`/`left_chat_member`) update the registry. - [ ] Mass mentions are batched and rate-limited. - [ ] `text_mention` used for users without a username. - [ ] Telegram errors caught; `retry_after` respected. - [ ] Permission guard enforces who may trigger a summon. ## References - [references/mentions-and-batching.md](references/mentions-and-batching.md) — mention entities, limits, batching, retry/backoff. - [references/scenes.md](references/scenes.md) — scenes/wizard setup with session middleware.
Auf GitHub ansehen