new Bot(config). Only provider is required. Every duration option takes
a string ('30s', '5m') or milliseconds; the constructor validates them and throws
ConfigValidationError naming the option.
Example
Properties
session?
tenantId?
local.
environmentId?
default.
botId?
session or the provider id.
connectionId?
session or default.
persistRaw?
splitLongText?
text send longer than the provider’s capabilities.maxTextLength (UTF-16
code units) or capabilities.maxTextBytes (UTF-8) into several messages, sent in
order at paragraph, line, sentence or word boundaries, never inside a grapheme
(emoji, flags) or the chat’s markup (a code block, inline code, a bold run or an HTML
element longer than the limit is closed and reopened; links and URLs stay whole).
before('send') hooks run once on the whole text and what they return is split (so
a footer is added once and every part still fits; a hook that makes a short text too
long gets it split too, its explicit key then suffixed from #1); an abort skips the
whole text. Each part is then a send of its own: after('send') hooks, the message
log and the durable outbox see each part. Only the first part keeps options.quoted;
an explicit idempotencyKey gets a #2, #3… suffix from the second part on. The
result is the last part’s, with parts listing every part. A part that fails rejects
the send and the remaining parts are not sent, except when the durable outbox defers
it (SendDeferredError): the remaining parts are then journaled behind it and the
sweeper delivers them too. bot.enqueue() journals one record per part (<key>,
<key>#2…). Edits and ctx.stream() (which splits on its own) are not affected, and
the outbox sweeper sends a record as it was journaled. Default true; false sends
the text as given (the provider may then reject it with PayloadTooLargeError).
dedupe?
chatId + ref.id
(interactions: interactionId), bounded LRU with optional TTL. Enabled by
default ({ size: 1000 }); false disables it. Relies on the providers’
INBOUND ID CONTRACT (see IProvider). Runs after the access lists: a
blocked delivery is never recorded, so a redelivery after un-blocking is
processed. See InboundDeduper.
echoFilter?
fromMe (a mailbox, a gateway, a
selfId learned late). true = { size: 1000 }. Counted in metrics().dropped.echo.
Complements the provider’s fromMe (the primary guard); omitted = off, as before.
durability?
{} = on with the in-memory backend. See DurabilityConfig and the operations guide.
store?
new MemoryStore({ file }), new SQLiteStore({ file }), new RedisStore({ url }),
…). Default: an in-memory MemoryStore. A StoreKind string is accepted for
compatibility and means the built-in MemoryStore.
storeConfig?
Deprecated
Passstore: new MemoryStore({ file, maxMessagesPerChat, autoSaveInterval })
instead. Options of the built-in MemoryStore, used only when BotConfig.store is not
an IStore instance (the bot logs a warning either way).
provider
commandPrefix?
conversationScope?
conversation?
timeout?
timeoutMessage?
retriesMessage?
errorMessage?
cancelledMessage?
groupMode?
lang?
ctx.lang. Default 'en'; 'es' (also
bundled) restores the Spanish texts of the 2.0 alphas. Unlike i18n.defaultLocale
it does NOT turn on per-user language resolution (no ctx.user read, no provider
language): a single-language bot sets this and nothing else.
i18n?
bot.locale().
handoff?
bot.handoff().
typing?
ctx
(reply/say/answer/text/quote, and flow .say). true enables the
defaults ({ minMs: 800, maxMs: 3000, charsPerSecond: 20 }). Disabled by default.
Ignored (no indicator, no wait) on providers without capabilities.typing.
rateLimit?
Deprecated
Configure pacing on the provider (e.g.new BaileysProvider({ rateLimit }))
and the retry of rate-limited ctx replies with BotConfig.rateLimitRetry.
It will be removed in the next major version.
rateLimitRetry?
ctx send (reply/say/media in handlers, flows and conversations)
that the transport rejects with a RateLimitedError asking for a short wait: the send
waits retryAfterMs and is tried again (same payload, hooks not re-run), so a
conversation step does not end on a transient 429. Default { retries: 1, maxWaitMs: 5000 }:
one retry, only when the wait is at most 5 s. A longer wait, other errors and bot.send()
fail as before (broadcasts and the durable outbox have their own back-off). false
disables it. retries counts attempts AFTER the first, like every retries option.
debug?
debug level. Without it (and without logger) the default level is warn.
logIds?
'hash' (default, HMAC-SHA256 truncated to 16 chars, stable within
the process — the same hashes as the trace spans when telemetry is on), 'raw' (as is,
for local debugging) or 'omit'. Uses telemetry.idKey as the HMAC key when set.
logger?
coordination?
scheduler?
bot.schedule/every/delay(spec, { id }, fn)) keep their state,
and how replicas share them. Without it, durable tasks use an in-memory store (they
do not survive a restart) and plain tasks behave exactly as before. See
SchedulerOptions.
telemetry?
@botmesh/ai adds model and tool spans) through a BotTracer —
OpenTelemetry with @botmesh/otel. No message bodies or personal data are recorded;
ids are hashed by default. Omitted: no tracing, the code path is unchanged. See the
“Tracing” guide.