Skip to main content
Defined in: user/types.ts:91 Persistent, per-user key/value profile — ctx.user in handlers and bot.user(userId) anywhere else. Scope. Keyed by the canonical sender (ctx.sender, the provider-resolved senderId), so it is shared across every chat that person writes from (DM and groups) and survives conversations and restarts (with a persistent store). It lives inside the bot’s store namespace (tenant / environment / bot / provider / connection), so two bots sharing one backend never see each other’s profiles. Namespaces. ctx.user is the 'default' namespace; ctx.user.ns('game') returns the same API scoped to 'game'. Namespace names are flat and absolute (ctx.user.ns('a').ns('b') is namespace 'b'). Use one per feature/plugin to avoid key collisions. Paths. Every method takes a dot path: 'name', 'address.city', 'items.0'. The FIRST segment is the top-level key, which is the unit the store persists atomically; deeper segments are resolved inside its JSON value (array elements by index). Keys cannot contain dots; __proto__, prototype, constructor, empty segments and control characters are rejected with UserDataError('INVALID_PATH'). Values are JSON data: they are deep-copied through JSON on write (a Date becomes its ISO string, undefined members vanish) and every read returns a fresh copy. BigInt, functions, symbols and cycles reject with UserDataError('INVALID_VALUE'). Writing undefined deletes the path. Concurrency. The dispatcher’s per-chat FIFO does NOT serialise one user across several chats (the same person can be handled in a group and in a DM at the same time), so the profile serialises writes itself: inside one process, every write of a user (set / update / delete / clear and the bot’s subject erasure) runs in call order, one at a time. A top-level set/delete is a single atomic store write; a nested write is a read-modify-write of its top-level key. Across several bot replicas sharing a store, top-level writes stay atomic (last writer wins) but two replicas writing nested paths of the SAME top-level key concurrently can lose one update — keep such keys owned by one replica or write whole top-level values. Reads never wait for writes; await your writes before reading them back.

Example

Properties

userId

Defined in: user/types.ts:93 Subject this profile belongs to (ctx.sender).

namespace

Defined in: user/types.ts:95 Namespace this handle reads and writes ('default' for ctx.user).

Methods

get()

Defined in: user/types.ts:101 Value at path, or undefined when missing or expired. T is an unchecked convenience cast — validate untrusted shapes yourself.

Type Parameters

Parameters

Returns

Promise<T | undefined>

all()

Defined in: user/types.ts:103 Every live top-level key of this namespace as a plain object ({} when empty).

Returns

Promise<Record<string, unknown>>

set()

Defined in: user/types.ts:105 Write value at path (see UserSetOptions.ttl for expiry). undefined deletes.

Parameters

Returns

Promise<void>

update()

Defined in: user/types.ts:118 Apply several writes: each own enumerable property of values is a PATH ({ name: 'Juan', 'address.city': 'Bogotá' }), applied in object key order like set; keys not mentioned are left alone. Paths, values, ttl and array indexes (against the stored values) are validated before anything is written, so an invalid batch writes nothing. All paths under one top-level key become a single store write; the batch as a whole is not atomic: each top-level key is its own write, so if the STORE fails one of them the others may already be persisted. The call rejects with the first store error only after every write of the batch has settled, so the next write (or erasure) of this user never overlaps it.

Parameters

Returns

Promise<void>

delete()

Defined in: user/types.ts:120 Remove path (a top-level key or a nested member). Missing paths are a no-op.

Parameters

Returns

Promise<void>

clear()

Defined in: user/types.ts:122 Remove every key of THIS namespace for this user (other namespaces are untouched).

Returns

Promise<void>

ns()

Defined in: user/types.ts:124 Same API scoped to namespace name. Throws UserDataError('INVALID_NAMESPACE') synchronously.

Parameters

Returns

UserData