npm node-telegram-bot-api 2.2.0-rc0

4 hours ago

Sessions

  • Added opt-in session middleware: createSession<T>(options) (aliased session)
    attaches a persistent, keyed bag reached with ctx.getSession<T>(). The store
    is required - there is no implicit default, so the durability choice is always
    explicit. The returned middleware also carries .get(ctx) / .find(ctx), typed
    once at construction.
  • Added the SessionStore contract: a value-agnostic string KV -
    read(key), write(key, value, { ttlSeconds }), delete(key), plus optional
    touch(key, ttlSeconds), init() and close(). Encoding happens once in the
    middleware's codec, never inside a store, so an in-memory store round-trips
    exactly like a durable one.
  • Added the stores: MemorySessionStorage (core, edge-safe, optional TTL),
    FileSessionStorage (/node, one file per key, atomic temp-file + rename),
    and, behind the new ./bun subpath, SqliteSessionStorage,
    SqlSessionStorage and RedisSessionStorage.
  • The persisted value is a versioned envelope, { v, data, ext, createdAt, updatedAt }. ext is a namespace map that layers built on sessions claim a
    slot in; the timestamps are first-seen / last-active, and the two SQL stores
    mirror them as created_at / updated_at columns.
  • The flush is skipped when the encoded envelope is unchanged, so an untouched
    chat costs one read and no write; touch() refreshes a TTL in that case.
    ctx.getSession().delete() evicts a key.
  • Updates for one key are serialized in-process by a per-key lock, so concurrent
    webhook invocations cannot interleave read-modify-write. Across processes it is
    last-writer-wins.

Reply and callback tracking

  • Added expectReply(ctx, messageId, marker?, { ttlSeconds? }),
    matchReply<M>(ctx) and forgetReply(ctx, messageId) - "awaiting a reply to
    this message" recorded as persisted data (matched on
    reply_to_message.message_id), never a live continuation, so it survives a
    restart and works on serverless.
  • Added the callback-query peers expectCallback(ctx, messageId, marker?, { ttlSeconds? }),
    matchCallback<M>(ctx, { once? }) and forgetCallback(ctx, messageId), keyed on
    callback_query.message.message_id. Matching a press does not consume the marker
    by default (a keyboard usually stays live for several presses); { once: true }
    makes a button fire at most once - it consumes only that message's marker, and
    consumption happens before the handler runs. Plain callback_data remains the
    idiomatic router - these are for a marker over 64 bytes, one the client must not
    read, or a one-shot press.
  • Replies and presses are kept in separate tables, so a quoted reply to a
    message that also carries an inline keyboard cannot consume the button's marker.
  • Expectations never expire on their own (a prompt answered tomorrow is normal);
    ttlSeconds bounds one, and expired entries are pruned the next time the layer
    touches the session, so a bot that sets a TTL cannot grow its envelope without
    limit. There is no cap and no default.
  • Added taggedReplies<Tag>(ctx) - expect / match / forget / expectPress /
    matchPress / forgetPress for plain string tags, typing both ends with one union.
  • Note the default session key is per chat, so in a group any member's reply or
    press matches a marker; carry the asker's id in the marker and check it when
    that matters.

Bot lifecycle

  • Added bot.init() and bot.close(). A middleware carrying init / close is
    picked up by use() and by on / command / hears; setup runs once at
    startup (awaited by startPolling() and handleUpdate()) and teardown runs in
    reverse. run() (/node) closes on shutdown.
  • init() tracks completion per plugin, so a failure retries from the plugin that
    failed instead of re-running the ones that succeeded; close() closes only what
    initialized, attempts every teardown even if one throws, and reports failures
    afterwards (an AggregateError when several failed).

Full diff: v2.1.0...v2.2.0-rc0

Don't miss a new node-telegram-bot-api release

NewReleases is sending notifications on new releases.