Skip to content

Options ​

Every option of new EasyTG(...), with its default. All durations are in milliseconds.

ts
new EasyTG<MyContext>({
  storage: new MemoryStorage(),    // default for everything easytg persists (see storage.md)
  keyPrefix: '',
  parseMode: 'markdown',           // 'markdown' | 'html' | 'markdownv2' | 'plain'
  homePage: 'home',                // page id used by nav.home()
  middlewares: [],                 // run before every page render and dialogue start
  logger: console,                 // warnings and errors; a Logger, or false for none; EASYTG_DEBUG=1 adds debug logs
  menu: undefined,                 // replyMenu([...])
  protectContent: false,           // protect_content on everything
  scopeKeysByBot: true,            // bot id in storage keys; false = 0.1 key format
  prepareProactive: undefined,     // (ctx) => … for contexts easytg creates (sendTo, edit, broadcast, tasks, withUser…)
  emitProactiveErrors: false,      // also emit sendTo / edit errors as 'error' events
  sequential: { timeoutMs: 8_000 },// one update per user and chat at a time; or false
  cluster: false,                  // true / a StorageAdapter: share limits, locks and queues between processes
  queues: {},                      // { name: { concurrency, perUser?, maxWaiting?, timeoutMs? } }
  loading: undefined,              // { afterMs, action, text, toast } for every page
  payments: undefined,             // { preCheckout?, onSuccess? }
  relay: undefined,                // { filter? } for relayed messages

  session:   { storage, ttlMs: undefined, refreshOnActivity: true, version: undefined, migrate: undefined },
  buttons:   { storage, params: 'auto', secret, ttlMs: 30 days, doubleTapMs: 700, ownerOnly: true, mediaToText: 'replace' },
  deepLinks: { ttlMs: 365 days },
  dialogues: { cancelOnCommand: true, timeoutMs: undefined, timeZone: undefined }, // timeZone: 'Asia/Jakarta' for date steps
  media:     { cacheFileIds: false, cacheTtlMs: 30 days },
  antiSpam:  { limit: 20, windowMs: 10_000, cooldownMs: 30_000, warn: true, exempt, filter }, // or false
  i18n:      { messages: {}, fallbackLocale: 'en', texts: {}, locales: {}, locale: (ctx, session) => ctx.from?.language_code },
  scheduler: { store, pollMs: 1000, batchSize: 20, leaseMs: 300_000, maxAttempts: 5, retryDelayMs },
});
optionsee
storage, keyPrefix, scopeKeysByBot, session.storage, buttons.storageStorage
parseModeText formatting
homePage, middlewaresPages, middlewares
protectContentMedia
loggeran object with debug, info, warn and error (e.g. pino or console); false silences easytg
sessionSessions
loadingPages
mediaMedia
buttonsButton params, Pages, Anti-spam
deepLinksDeep links
dialoguesDialogues
menuMain menu
antiSpamAnti-spam
sequential, clusterScaling
queuesQueues
schedulerScheduled tasks
paymentsPayments
relayRelays
i18nLanguages
prepareProactive, emitProactiveErrorsSending without an update

With a custom grammY context type, bind the factories once:

ts
export const { page, dialogue, task } = withContext<MyContext>();

MIT licensed