ReadonlyinnerThe wrapped provider (drive it to simulate inbound traffic).
ReadonlyidSame id as the wrapped provider (store namespaces stay unchanged).
ReadonlycapabilitiesSame capabilities object as the wrapped provider.
ReadonlyseedSeed in use.
ReadonlylogEverything the kit injected, in order.
ReadonlydeliveredEvery inbound event actually delivered to listeners (copies and replays included), in delivery order.
OptionalingestPush ingress for webhook transports (Cloud API POST, Telegram/Discord webhook, Discord interaction endpoint). The host HTTP server calls this with the raw body (and, optionally, the request headers for signature checks); the provider normalizes and emits via onEvent. May return a value the host can use as the HTTP status (e.g. 200 accepted / 403 bad signature). Socket-first providers (Baileys, Discord gateway) omit it.
OptionaldownloadLazy media retrieval behind one signature for every download model.
OptionalserializeDurable journaling (BotConfig.durability): turn a live MediaRef into a JSON-safe,
versioned reference that rehydrateMediaRef can rebuild in another process, so a
replayed message (crash recovery, background retry) can still download its media.
Synchronous, cheap and side-effect free; a throw counts as "not durable". Return
undefined for a ref that must not be journaled (e.g. view-once media). Never include
credentials: the result is stored at rest with the inbound record.
OptionalrehydrateRebuild the MediaRef of a replayed message from what serializeMediaRef wrote.
ref is the journaled ref without its token. Pure decoding: it must not need the
transport to be connected. stored comes from storage and is UNTRUSTED: reject an
invalid, unknown-version or tampered value with a ProviderError.
OptionalgetRead-back seam for poll aggregation, quote-body resolution, retry decrypt.
Providers that don't need it no-op / omit it. Replaces the constructor-
injected getMessage callback baked into BaileysProvider today.
OptionalmarkOptionaltypingOptionaldeleteOptionaleditOptionalsendShow (or update) an ephemeral, not-yet-sent preview of a message being
generated. Same draftId → the same draft is updated in place. A draft is
NOT a message: the caller must still send() the final text. Only for
providers with capabilities.streaming === 'draft'; rejects (typed error)
where the transport refuses drafts (e.g. Telegram groups), and the caller
then falls back to edits or chunks.
OptionalacknowledgeOptionalcanWhether a form OutboundContent for form (and opts.nativeId) can be
rendered natively right now, e.g. whether a WhatsApp Flow is mapped to it.
Only consulted when capabilities.forms === 'native'; when it returns
false, an auto-mode flow().form() asks field by field without sending
(and failing) a form message first. Absent = every form is renderable.
OptionaltextRich-text dialect of one chat, for providers that serve several channels
with different markup through one instance (e.g. Twilio: whatsapp: chats
render WhatsApp markup, SMS chats render none). Return undefined when the
chat's format is unknown; the core then falls back to
capabilities.textFormat. Exposed as ctx.textFormat. Must be synchronous
and cheap (it runs once per inbound message). Absent = every chat uses
capabilities.textFormat.
Cancels every pending delivery, buffered or held event, then stops the wrapped provider.
Subscribe to the normalized event stream. Returns an unsubscriber.
Send through the wrapped provider unless chaos decides this attempt fails
(scripted attempts, probability, or the connection is down), in which
case it rejects with a typed ProviderError and nothing reaches the
wrapped provider's outbox.
Optionaloptions: SendOptionsSimulate a connection drop: emits { state: 'closed', reason }, then holds
inbound and fails sends (per options) until reconnect. A finite
downtimeMs schedules the reconnect automatically; the default for a
manual drop is to stay down until reconnect() is called.
End a simulated drop: emits connecting then ready, redelivers the last
replayOnReconnect events (offline-sync duplicates), then delivers what
was held while down, in arrival order.
Redeliver (fresh copies of) the last count delivered inbound events — an explicit webhook retry.
Deliver whatever sits in the reorder window right now (permuted as configured).
Wait (real timers) until no chaos delivery, reorder flush, scheduled reconnect or delayed send is pending, plus one macrotask so listeners can dispatch. Events held by an indefinite drop do not count as pending.
The wrapped provider's self id (null when it has none: never undefined, see IProvider.selfId).
The wrapped provider's debug connection handle.
false while a simulated drop is in effect.
Number of send() calls so far (failed ones included).
Scheduled deliveries, reorder/reconnect timers and delayed sends still outstanding.
An
IProviderthat wraps another one and delivers its traffic adversarially (see the module docs and ChaosOptions). Pass it tonew Bot({ provider })and keep driving the wrapped provider (chaos.inner.incoming(...)).Optional provider capabilities (
typing,markRead,downloadMedia, …) are exposed only when the wrapped provider has them, so feature detection in the Bot keeps working.