> ## Documentation Index
> Fetch the complete documentation index at: https://botmesh.afaya.com.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Bot

> Class exported by @botmesh/core.

Defined in: [core/Bot.ts:243](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L243)

The bot engine. Register handlers, flows, conversations, hooks and plugins, then
call [start()](#start). A bot drives exactly one transport ([BotConfig.provider](https://botmesh.afaya.com.co/api/core/interfaces/BotConfig.md#provider));
everything it receives and sends goes through the neutral [IProvider](https://botmesh.afaya.com.co/api/core/interfaces/IProvider.md) contract, so the same
code runs on WhatsApp, Telegram or any other channel.

## Example

```ts theme={null}
import { Bot, flow } from '@botmesh/core'
import { BaileysProvider } from '@botmesh/baileys'

const bot = new Bot({ provider: new BaileysProvider({ session: 'my-bot' }) })

bot.when('hi', (ctx) => ctx.reply('Hello! 👋'))
bot.use(
  flow('register')
    .ask('What is your name?', 'name')
    .say((_ctx, c) => `Nice to meet you, ${c.state.name}!`),
)

await bot.start()
```

## Extends

* `EventEmitter`

## Constructors

### Constructor

```ts theme={null}
new Bot(config): Bot;
```

Defined in: [core/Bot.ts:321](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L321)

#### Parameters

| Parameter | Type |
| - | - |
| `config` | [`BotConfig`](https://botmesh.afaya.com.co/api/core/interfaces/BotConfig) |

#### Returns

`Bot`

#### Overrides

`EventEmitter.constructor`

## Properties

### logger

```ts theme={null}
readonly logger: Logger;
```

Defined in: [core/Bot.ts:244](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L244)

***

### ready

```ts theme={null}
readonly ready: Promise<void>;
```

Defined in: [core/Bot.ts:269](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L269)

Resolves when the bot reaches the `'ready'` connection state.

***

### blacklist

```ts theme={null}
readonly blacklist: AccessList;
```

Defined in: [core/Bot.ts:276](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L276)

Senders/chats whose inbound messages are dropped before anything else (not
persisted, no hooks, no routing, no `'message'` event). Ids are matched exactly
against `ctx.sender` and `ctx.from`. See [AccessList](https://botmesh.afaya.com.co/api/core/classes/AccessList.md).

***

### whitelist

```ts theme={null}
readonly whitelist: Whitelist;
```

Defined in: [core/Bot.ts:281](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L281)

When enabled, only senders/chats on this list are processed (the blacklist
still wins). Disabled by default. See [Whitelist](https://botmesh.afaya.com.co/api/core/classes/Whitelist.md).

## Methods

### on()

#### Call Signature

```ts theme={null}
on<K>(event, listener): this;
```

Defined in: [core/Bot.ts:358](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L358)

Adds the `listener` function to the end of the listeners array for the
event named `eventName`. No checks are made to see if the `listener` has
already been added. Multiple calls passing the same combination of `eventName`
and `listener` will result in the `listener` being added, and called, multiple
times.

```js theme={null}
server.on('connection', (stream) => {
  console.log('someone connected!');
});
```

Returns a reference to the `EventEmitter`, so that calls can be chained.

By default, event listeners are invoked in the order they are added. The
`emitter.prependListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.

```js theme={null}
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
//   b
//   a
```

##### Type Parameters

| Type Parameter |
| - |
|  `K` *extends* keyof [`BotEvents`](https://botmesh.afaya.com.co/api/core/interfaces/BotEvents) |

##### Parameters

| Parameter | Type | Description |
| - | - | - |
| `event` | `K` | - |
| `listener` | (...`args`) => `void` | The callback function |

##### Returns

`this`

##### Since

v0.1.101

##### Overrides

`EventEmitter.on`

#### Call Signature

```ts theme={null}
on(event, listener): this;
```

Defined in: [core/Bot.ts:359](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L359)

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `string` |
| `listener` | (...`args`) => `void` |

##### Returns

`this`

##### Overrides

`EventEmitter.on`

***

### once()

#### Call Signature

```ts theme={null}
once<K>(event, listener): this;
```

Defined in: [core/Bot.ts:362](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L362)

Adds a **one-time** `listener` function for the event named `eventName`. The
next time `eventName` is triggered, this listener is removed and then invoked.

```js theme={null}
server.once('connection', (stream) => {
  console.log('Ah, we have our first user!');
});
```

Returns a reference to the `EventEmitter`, so that calls can be chained.

By default, event listeners are invoked in the order they are added. The
`emitter.prependOnceListener()` method can be used as an alternative to add the
event listener to the beginning of the listeners array.

```js theme={null}
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.once('foo', () => console.log('a'));
myEE.prependOnceListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
//   b
//   a
```

##### Type Parameters

| Type Parameter |
| - |
|  `K` *extends* keyof [`BotEvents`](https://botmesh.afaya.com.co/api/core/interfaces/BotEvents) |

##### Parameters

| Parameter | Type | Description |
| - | - | - |
| `event` | `K` | - |
| `listener` | (...`args`) => `void` | The callback function |

##### Returns

`this`

##### Since

v0.3.0

##### Overrides

`EventEmitter.once`

#### Call Signature

```ts theme={null}
once(event, listener): this;
```

Defined in: [core/Bot.ts:363](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L363)

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `string` |
| `listener` | (...`args`) => `void` |

##### Returns

`this`

##### Overrides

`EventEmitter.once`

***

### off()

#### Call Signature

```ts theme={null}
off<K>(event, listener): this;
```

Defined in: [core/Bot.ts:366](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L366)

Alias for `emitter.removeListener()`.

##### Type Parameters

| Type Parameter |
| - |
|  `K` *extends* keyof [`BotEvents`](https://botmesh.afaya.com.co/api/core/interfaces/BotEvents) |

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `K` |
| `listener` | (...`args`) => `void` |

##### Returns

`this`

##### Since

v10.0.0

##### Overrides

`EventEmitter.off`

#### Call Signature

```ts theme={null}
off(event, listener): this;
```

Defined in: [core/Bot.ts:367](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L367)

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `string` |
| `listener` | (...`args`) => `void` |

##### Returns

`this`

##### Overrides

`EventEmitter.off`

***

### emit()

#### Call Signature

```ts theme={null}
emit<K>(event, ...args): boolean;
```

Defined in: [core/Bot.ts:370](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L370)

Synchronously calls each of the listeners registered for the event named
`eventName`, in the order they were registered, passing the supplied arguments
to each.

Returns `true` if the event had listeners, `false` otherwise.

```js theme={null}
import { EventEmitter } from 'node:events';
const myEmitter = new EventEmitter();

// First listener
myEmitter.on('event', function firstListener() {
  console.log('Helloooo! first listener');
});
// Second listener
myEmitter.on('event', function secondListener(arg1, arg2) {
  console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
});
// Third listener
myEmitter.on('event', function thirdListener(...args) {
  const parameters = args.join(', ');
  console.log(`event with parameters ${parameters} in third listener`);
});

console.log(myEmitter.listeners('event'));

myEmitter.emit('event', 1, 2, 3, 4, 5);

// Prints:
// [
//   [Function: firstListener],
//   [Function: secondListener],
//   [Function: thirdListener]
// ]
// Helloooo! first listener
// event with parameters 1, 2 in second listener
// event with parameters 1, 2, 3, 4, 5 in third listener
```

##### Type Parameters

| Type Parameter |
| - |
|  `K` *extends* keyof [`BotEvents`](https://botmesh.afaya.com.co/api/core/interfaces/BotEvents) |

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `K` |
| ...`args` | [`BotEventArgs`](https://botmesh.afaya.com.co/api/core/type-aliases/BotEventArgs)\<`K`> |

##### Returns

`boolean`

##### Since

v0.1.26

##### Overrides

`EventEmitter.emit`

#### Call Signature

```ts theme={null}
emit(event, ...args): boolean;
```

Defined in: [core/Bot.ts:371](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L371)

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `string` |
| ...`args` | `any`\[] |

##### Returns

`boolean`

##### Overrides

`EventEmitter.emit`

***

### start()

```ts theme={null}
start(): Promise<void>;
```

Defined in: [core/Bot.ts:378](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L378)

#### Returns

`Promise`\<`void`>

***

### stop()

```ts theme={null}
stop(opts?): Promise<void>;
```

Defined in: [core/Bot.ts:388](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L388)

Stop the bot. By default aborts conversations and tears down immediately.

#### Parameters

| Parameter | Type |
| - | - |
| `opts?` | [`StopOptions`](https://botmesh.afaya.com.co/api/core/interfaces/StopOptions) |

#### Returns

`Promise`\<`void`>

***

### send()

```ts theme={null}
send(
   chatId, 
   content, 
   options?
): Promise<SentMessage<unknown>>;
```

Defined in: [core/Bot.ts:397](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L397)

Send normalized content to any chat (a plain string is sent as text, like
[broadcast](#broadcast) and [sendTo](#sendto)). Runs the `before('send')`/`after('send')` hook
pipeline; a `before('send')` hook may mutate `payload.content` or `abort()` to skip.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `content` | `string` \| [`OutboundContent`](https://botmesh.afaya.com.co/api/core/type-aliases/OutboundContent) |
| `options?` | [`SendOptions`](https://botmesh.afaya.com.co/api/core/interfaces/SendOptions) |

#### Returns

`Promise`\<[`SentMessage`](https://botmesh.afaya.com.co/api/core/interfaces/SentMessage)\<`unknown`>>

***

### enqueue()

```ts theme={null}
enqueue(
   chatId, 
   content, 
   options?
): Promise<{
  key: string;
  status: "exists" | "queued" | "skipped";
}>;
```

Defined in: [core/Bot.ts:426](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L426)

Durable fire-and-forget send (needs `BotConfig.durability`): runs the `before('send')`
hooks, journals the send and returns its outbox key at once; the background sweeper
delivers it (retries, backoff, dead-letter queue). Enqueueing an `idempotencyKey` that
already exists is a no-op (`status: 'exists'`) — use it for campaigns and scheduled
jobs that may run twice. A text over the channel's limit is split after the hooks
(`BotConfig.splitLongText`) into one record per part: `key`, `key#2`, ….

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `content` | `string` \| [`OutboundContent`](https://botmesh.afaya.com.co/api/core/type-aliases/OutboundContent) |
| `options?` | [`SendOptions`](https://botmesh.afaya.com.co/api/core/interfaces/SendOptions) |

#### Returns

`Promise`\<\{
`key`: `string`;
`status`: `"exists"` | `"queued"` | `"skipped"`;
}>

#### Example

```ts theme={null}
await bot.enqueue(chatId, 'Tu cita es mañana', { idempotencyKey: `reminder:${citaId}` })
```

***

### ~~sendText()~~

```ts theme={null}
sendText(chatId, text): Promise<SentMessage<unknown>>;
```

Defined in: [core/Bot.ts:435](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L435)

Send plain text to a chat. Same as `send(chatId, text)`.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `text` | `string` |

#### Returns

`Promise`\<[`SentMessage`](https://botmesh.afaya.com.co/api/core/interfaces/SentMessage)\<`unknown`>>

#### Deprecated

Use [send](#send): `bot.send(chatId, text)` (a string is sent as text).

***

### broadcast()

```ts theme={null}
broadcast(
   chatIds, 
   content, 
   opts?
): Promise<BroadcastResult>;
```

Defined in: [core/Bot.ts:463](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L463)

Send `content` (a string is sent as text) to many chats: in batches of `batchSize`
(default 10) with `concurrency` parallel sends (default 1), pausing `delayBetween`
between batches. A `RateLimitedError` pauses the whole broadcast for its
`retryAfterMs` and retries that chat (up to `retries` times after the first send, default 3); other errors
are recorded and the broadcast goes on. Abort `signal` to stop early — never-attempted
chats come back in `pending`. `bot.stop()` cancels it the same way (with `drain`,
stop waits for its in-flight sends), and a broadcast started on a bot that is not
started (never started, or stopped) sends nothing. Duplicate ids are sent once. Each send takes the normal
outbound path (send hooks, ledger, the provider's rate limiter) but not the
dispatcher's per-chat queues, so inbound handling is never blocked; still, launch it
with `void` (not `await`) from inside a handler so that chat's queue is not held.

#### Parameters

| Parameter | Type |
| - | - |
| `chatIds` | readonly `string`\[] |
| `content` | `string` \| [`OutboundContent`](https://botmesh.afaya.com.co/api/core/type-aliases/OutboundContent) |
| `opts?` | [`BroadcastOptions`](https://botmesh.afaya.com.co/api/core/interfaces/BroadcastOptions) |

#### Returns

`Promise`\<[`BroadcastResult`](https://botmesh.afaya.com.co/api/core/interfaces/BroadcastResult)>

#### Example

```ts theme={null}
const ac = new AbortController()
const res = await bot.broadcast(chatIds, '🎉 Nueva promo!', {
  batchSize: 10, delayBetween: '2s', signal: ac.signal,
  onProgress: (done, total) => bot.logger.info(`${done}/${total}`),
  onFail: (chatId, error) => bot.logger.warn({ chatId, err: error }, 'broadcast failed'),
})
// → { total: 500, sent: 480, failed: 20, skipped: 0, errors: [{ chatId, error }], messages, cancelled: false, pending: [] }
```

***

### trigger()

```ts theme={null}
trigger(name, opts): Promise<TriggerResult>;
```

Defined in: [core/Bot.ts:491](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L491)

Start a registered flow/conversation for a subject without waiting for them to
write — reminders from `bot.schedule()`, webhooks, admin panels. `data` seeds
`c.state`. The start goes through the same gates as a message (blacklist /
whitelist, human handoff) and the chat's FIFO queue; by default a subject that
already has a live or dormant conversation is left alone (`ifActive: 'replace'`
cancels it). Resolves once the conversation is entered — not when it ends
(listen to `'conversation:ended'` for that). Rejects when `name` is not registered.
Safe to `await` from a handler or command of the same chat: the trigger then runs
inline in that message's queue slot instead of queuing behind it (which would
deadlock the chat). Awaiting a trigger for a DIFFERENT chat whose handlers in turn
await a trigger back into this one can still deadlock — launch those with `void`.
Before-message hooks, matchers and the `'message'` event do not run, and nothing
is persisted for the synthetic inbound (`ctx.raw` is `{ synthetic: 'trigger', name }`).

#### Parameters

| Parameter | Type |
| - | - |
| `name` | `string` |
| `opts` | [`TriggerOptions`](https://botmesh.afaya.com.co/api/core/interfaces/TriggerOptions) |

#### Returns

`Promise`\<[`TriggerResult`](https://botmesh.afaya.com.co/api/core/interfaces/TriggerResult)>

#### Example

```ts theme={null}
bot.schedule('0 9 * * *', async () => {
  for (const cita of await db.citasDeHoy()) {
    await bot.trigger('recordatorio', { chatId: cita.chatId, data: { hora: cita.hora } })
  }
})
```

***

### metrics()

```ts theme={null}
metrics(): BotMetricsSnapshot;
```

Defined in: [core/Bot.ts:501](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L501)

Snapshot of the runtime counters: conversations (started/completed/cancelled/
timedOut/retriesExceeded/errored, active, mean duration) overall and per flow,
messages in/out, inbound drops (duplicate/blocked/handoff), triggers, errors and
uptime. In-process only. Render it for Prometheus with `toPrometheus()`.

#### Returns

[`BotMetricsSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/BotMetricsSnapshot)

***

### resetMetrics()

```ts theme={null}
resetMetrics(): void;
```

Defined in: [core/Bot.ts:506](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L506)

Zero every [metrics](#metrics) counter (uptime is kept).

#### Returns

`void`

***

### handoff()

```ts theme={null}
handoff(chatId, opts?): Promise<boolean>;
```

Defined in: [core/Bot.ts:539](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L539)

Hand `chatId` over to a human agent. Until [resume](#resume), the Dispatcher skips
every routing stage for that chat (commands, conversations, dormant resume,
matchers, catch-all) except `BotConfig.handoff.allowCommands`; inbound messages
are still persisted, hooks still run and the `'message'` event still fires.
Active conversations in the chat are cancelled silently and its dormant
checkpoints dropped. Emits `'handoff'` and persists the state on
`StoredChat.handoff` (survives restarts with a persistent store).

The state flips synchronously, so not awaiting is safe. Resolves `true` if the
chat was not already handed off; never rejects for store failures (they go to
the `'error'` event). Throws `TypeError` synchronously on an empty chat id.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `opts?` | [`HandoffOptions`](https://botmesh.afaya.com.co/api/core/interfaces/HandoffOptions) |

#### Returns

`Promise`\<`boolean`>

***

### resume()

```ts theme={null}
resume(chatId, opts?): Promise<boolean>;
```

Defined in: [core/Bot.ts:547](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L547)

Give a handed-off chat back to the bot: routing resumes immediately, `'resume'`
fires and the persisted state is cleared. Resolves `true` if the chat was handed off.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `opts?` | [`ResumeOptions`](https://botmesh.afaya.com.co/api/core/interfaces/ResumeOptions) |

#### Returns

`Promise`\<`boolean`>

***

### isHandedOff()

```ts theme={null}
isHandedOff(chatId): boolean;
```

Defined in: [core/Bot.ts:552](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L552)

Is `chatId` currently handed off to a human?

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |

#### Returns

`boolean`

***

### getHandoff()

```ts theme={null}
getHandoff(chatId): HandoffState | undefined;
```

Defined in: [core/Bot.ts:557](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L557)

Snapshot of the chat's handoff state (`since`, `reason`, `meta`), or `undefined`.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |

#### Returns

[`HandoffState`](https://botmesh.afaya.com.co/api/core/interfaces/HandoffState) | `undefined`

***

### listHandoffs()

```ts theme={null}
listHandoffs(): HandoffState[];
```

Defined in: [core/Bot.ts:562](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L562)

Snapshots of every chat currently handed off.

#### Returns

[`HandoffState`](https://botmesh.afaya.com.co/api/core/interfaces/HandoffState)\[]

***

### ~~sendTo()~~

```ts theme={null}
sendTo(
   chatId, 
   content, 
   options?
): Promise<SentMessage<unknown>>;
```

Defined in: [core/Bot.ts:574](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L574)

Send to a chat from outside the inbound pipeline — typically a human agent's
message during a handoff. Same path as [send](#send) (`before`/`after('send')`
hooks, outbound ledger); it is the same call as [send](#send), named for handoff
code. Works whether or not the chat is handed off and never resumes the bot by itself.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `content` | `string` \| [`OutboundContent`](https://botmesh.afaya.com.co/api/core/type-aliases/OutboundContent) |
| `options?` | [`SendOptions`](https://botmesh.afaya.com.co/api/core/interfaces/SendOptions) |

#### Returns

`Promise`\<[`SentMessage`](https://botmesh.afaya.com.co/api/core/interfaces/SentMessage)\<`unknown`>>

#### Deprecated

Use [send](#send): `bot.send(chatId, content, options)` (the very same call).

***

### exportAccessLists()

```ts theme={null}
exportAccessLists(): AccessListsSnapshot;
```

Defined in: [core/Bot.ts:579](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L579)

JSON-serializable snapshot of [blacklist](#blacklist) + [whitelist](#whitelist) for host persistence.

#### Returns

[`AccessListsSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/AccessListsSnapshot)

***

### loadAccessLists()

```ts theme={null}
loadAccessLists(snapshot): this;
```

Defined in: [core/Bot.ts:584](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L584)

Restore [exportAccessLists](#exportaccesslists) output. Lists missing from `snapshot` are left untouched.

#### Parameters

| Parameter | Type |
| - | - |
| `snapshot` | \{ `blacklist?`: \| readonly `string`\[] \| [`AccessListSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/AccessListSnapshot); `whitelist?`: \| readonly `string`\[] \| `Partial`\<[`WhitelistSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/WhitelistSnapshot)>; } |
| `snapshot.blacklist?` | \| readonly `string`\[] \| [`AccessListSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/AccessListSnapshot) |
| `snapshot.whitelist?` | \| readonly `string`\[] \| `Partial`\<[`WhitelistSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/WhitelistSnapshot)> |

#### Returns

`this`

***

### when()

```ts theme={null}
when(trigger, handler): () => void;
```

Defined in: [core/Bot.ts:601](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L601)

Route messages matching `trigger` (text, `RegExp`, function, type trigger such as
`IMAGE`, `WELCOME`, or an array) to a handler or a flow. Returns an unsubscriber.

#### Parameters

| Parameter | Type |
| - | - |
| `trigger` | [`Trigger`](https://botmesh.afaya.com.co/api/core/type-aliases/Trigger) |
| `handler` | \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)> \| [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

***

### conversation()

```ts theme={null}
conversation(
   name, 
   fn, 
   opts?
): () => void;
```

Defined in: [core/Bot.ts:621](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L621)

Register an async conversation, entered when `opts.trigger` (default: `name`) matches.
`ctx` is the full [MessageContext](https://botmesh.afaya.com.co/api/core/interfaces/MessageContext.md) of the triggering message (`ctx.tools`, media
helpers, `react`…); `c` offers `ask`/`waitText`/`waitMedia`/`choose`, `retry()`,
`idle()`/`idleClear()`, `end(farewell?)` and `goto(name)`.

#### Parameters

| Parameter | Type |
| - | - |
| `name` | `string` |
| `fn` | [`ConversationHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/ConversationHandler) |
| `opts?` | \{ `trigger?`: [`Trigger`](https://botmesh.afaya.com.co/api/core/type-aliases/Trigger); } |
| `opts.trigger?` | [`Trigger`](https://botmesh.afaya.com.co/api/core/type-aliases/Trigger) |

#### Returns

() => `void`

#### Example

```ts theme={null}
bot.conversation('ahorcado', async (c, ctx) => {
  c.idle('2m', () => c.end('⏰ Te desconecté por inactividad'))
  let letra = await c.ask('Escribe una letra')
  while (letra.length !== 1) letra = await c.retry('❌ Solo una letra')
  await ctx.react('✅')
})
```

***

### enterConversation()

#### Call Signature

```ts theme={null}
enterConversation(handler, ctx): Promise<void>;
```

Defined in: [core/Bot.ts:650](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L650)

Enter an inline [ConversationHandler](https://botmesh.afaya.com.co/api/core/type-aliases/ConversationHandler.md) for the chat (or group participant) of `ctx`.
To start a REGISTERED conversation or flow, use [trigger](#trigger) (the by-name form here is
deprecated).

Fire-and-forget by design: it returns immediately, so a handler can start a
conversation and return, releasing the chat's FIFO queue for the user's next
message (which the conversation then receives). Any conversation already active
on that key is replaced. Failures (e.g. an unknown name) are reported through
the `'error'` event, never as an unhandled rejection.

The returned promise settles (it never rejects) once the conversation has ended
and released its key. Never `await` it inside a handler: that blocks the chat's
queue, so the user's answer could never reach the conversation.

##### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`ConversationHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/ConversationHandler) |
| `ctx` | [`MessageContext`](https://botmesh.afaya.com.co/api/core/interfaces/MessageContext) |

##### Returns

`Promise`\<`void`>

##### Example

```ts theme={null}
bot.when('pedido', async (ctx) => {
  bot.enterConversation(async (c) => {
    const ok = await c.ask('¿Confirmas? (sí/no)')
    await c.say(ok === 'sí' ? 'Hecho' : 'Cancelado')
  }, ctx)
})
```

#### Call Signature

```ts theme={null}
enterConversation(name, ctx): Promise<void>;
```

Defined in: [core/Bot.ts:656](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L656)

##### Parameters

| Parameter | Type |
| - | - |
| `name` | `string` |
| `ctx` | [`MessageContext`](https://botmesh.afaya.com.co/api/core/interfaces/MessageContext) |

##### Returns

`Promise`\<`void`>

##### Deprecated

Start a registered conversation with [trigger](#trigger):
`bot.trigger(name, { chatId: ctx.from, userId: ctx.sender, isGroup: ctx.isGroup, ifActive: 'replace' })`
(safe to `await` from a handler of the same chat).

***

### use()

#### Call Signature

```ts theme={null}
use(flow): this;
```

Defined in: [core/Bot.ts:667](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L667)

Register flows (an array is accepted). Chainable; remove one later with
[unregisterFlow](#unregisterflow). Plugins go through [plug](#plug).

##### Parameters

| Parameter | Type |
| - | - |
| `flow` | \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)> \| ( \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)>)\[] |

##### Returns

`this`

#### Call Signature

```ts theme={null}
use(item): this;
```

Defined in: [core/Bot.ts:672](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L672)

##### Parameters

| Parameter | Type |
| - | - |
| `item` | \| [`Plugin`](https://botmesh.afaya.com.co/api/core/type-aliases/Plugin) \| CompiledFlow \| FlowBuilder\<EmptyFlowState> \| Plugin\[] |

##### Returns

`this`

##### Deprecated

Plug plugins with [plug](#plug) (`bot.plug(plugin)`), which also returns the
unsubscriber; `use()` is for flows.

***

### ~~useFlow()~~

```ts theme={null}
useFlow(flow): this;
```

Defined in: [core/Bot.ts:685](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L685)

Same as `use(flow)`, typed for a single flow.

#### Parameters

| Parameter | Type |
| - | - |
| `flow` | \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)> |

#### Returns

`this`

#### Deprecated

Use [use](#use) (`bot.use(flow)`), or [registerFlow](#registerflow) to get the flow id
back and refuse a duplicate id.

***

### command()

```ts theme={null}
command(name, handler): () => void;
```

Defined in: [core/Bot.ts:688](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L688)

Register a `/name` command (wins over an active conversation). Returns an unsubscriber.

#### Parameters

| Parameter | Type |
| - | - |
| `name` | `string` |
| `handler` | [`CommandHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/CommandHandler) |

#### Returns

() => `void`

***

### onMessage()

```ts theme={null}
onMessage(handler): () => void;
```

Defined in: [core/Bot.ts:697](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L697)

Catch-all handler: receives the messages no command, conversation or matcher took.
Not to be confused with `bot.on('message', …)`, the event that observes every
inbound message. Returns an unsubscriber.

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

***

### onType()

```ts theme={null}
onType(type, handler): () => void;
```

Defined in: [core/Bot.ts:705](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L705)

Handle every message of one [MessageType](https://botmesh.afaya.com.co/api/core/type-aliases/MessageType.md) (same as `when(IMAGE, handler)` and the
other type triggers). Returns an unsubscriber.

#### Parameters

| Parameter | Type |
| - | - |
| `type` | [`MessageType`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageType) |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

***

### ~~onImage()~~

```ts theme={null}
onImage(handler): () => void;
```

Defined in: [core/Bot.ts:709](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L709)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('image', handler)` or `bot.when(IMAGE, handler)`.

***

### ~~onAudio()~~

```ts theme={null}
onAudio(handler): () => void;
```

Defined in: [core/Bot.ts:711](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L711)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('audio', handler)` or `bot.when(AUDIO, handler)`.

***

### ~~onVideo()~~

```ts theme={null}
onVideo(handler): () => void;
```

Defined in: [core/Bot.ts:713](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L713)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('video', handler)` or `bot.when(VIDEO, handler)`.

***

### ~~onDocument()~~

```ts theme={null}
onDocument(handler): () => void;
```

Defined in: [core/Bot.ts:715](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L715)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('document', handler)` or `bot.when(DOCUMENT, handler)`.

***

### ~~onSticker()~~

```ts theme={null}
onSticker(handler): () => void;
```

Defined in: [core/Bot.ts:717](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L717)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('sticker', handler)` or `bot.when(STICKER, handler)`.

***

### ~~onLocation()~~

```ts theme={null}
onLocation(handler): () => void;
```

Defined in: [core/Bot.ts:719](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L719)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('location', handler)` or `bot.when(LOCATION, handler)`.

***

### ~~onContact()~~

```ts theme={null}
onContact(handler): () => void;
```

Defined in: [core/Bot.ts:721](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L721)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('contact', handler)` or `bot.when(CONTACT, handler)`.

***

### ~~onPoll()~~

```ts theme={null}
onPoll(handler): () => void;
```

Defined in: [core/Bot.ts:723](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L723)

#### Parameters

| Parameter | Type |
| - | - |
| `handler` | [`MessageHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/MessageHandler) |

#### Returns

() => `void`

#### Deprecated

Use `bot.onType('poll', handler)` or `bot.when(POLL, handler)`.

***

### registerFlow()

```ts theme={null}
registerFlow(flow): string;
```

Defined in: [core/Bot.ts:738](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L738)

Register a flow at runtime (same as `use(flow)`, but refuses a duplicate id).
Returns the flow id. See [replaceFlow](#replaceflow) to hot-swap an existing one.

#### Parameters

| Parameter | Type |
| - | - |
| `flow` | \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)> |

#### Returns

`string`

#### Example

```ts theme={null}
bot.registerFlow(flow('encuesta').ask('¿Tu nombre?', 'name').say((_ctx, c) => `Gracias ${c.state.name}`))
```

***

### unregisterFlow()

```ts theme={null}
unregisterFlow(id): boolean;
```

Defined in: [core/Bot.ts:744](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L744)

Remove a flow or conversation by id: its triggers stop matching. Conversations already
running finish on the version they entered with. Returns `false` when unknown.

#### Parameters

| Parameter | Type |
| - | - |
| `id` | `string` |

#### Returns

`boolean`

***

### replaceFlow()

```ts theme={null}
replaceFlow(id, flow): void;
```

Defined in: [core/Bot.ts:751](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L751)

Hot-swap the flow registered under `id` (registers it when absent). The new flow keeps
`id` whatever its own id is; its trigger replaces the old one. Running conversations
keep the old version; persisted checkpoints resume on the new steps (by step index).

#### Parameters

| Parameter | Type |
| - | - |
| `id` | `string` |
| `flow` | \| [`CompiledFlow`](https://botmesh.afaya.com.co/api/core/interfaces/CompiledFlow) \| [`FlowBuilder`](https://botmesh.afaya.com.co/api/core/classes/FlowBuilder)\<[`EmptyFlowState`](https://botmesh.afaya.com.co/api/core/type-aliases/EmptyFlowState)> |

#### Returns

`void`

***

### hasFlow()

```ts theme={null}
hasFlow(id): boolean;
```

Defined in: [core/Bot.ts:754](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L754)

Whether a flow or conversation is registered under `id`.

#### Parameters

| Parameter | Type |
| - | - |
| `id` | `string` |

#### Returns

`boolean`

***

### listFlows()

```ts theme={null}
listFlows(): RegisteredFlowInfo[];
```

Defined in: [core/Bot.ts:757](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L757)

Every live flow (`kind: 'flow'`) and async conversation (`kind: 'conversation'`).

#### Returns

[`RegisteredFlowInfo`](https://botmesh.afaya.com.co/api/core/type-aliases/RegisteredFlowInfo)\[]

***

### ~~triggerFlow()~~

```ts theme={null}
triggerFlow(
   id, 
   target, 
   opts?
): Promise<boolean>;
```

Defined in: [core/Bot.ts:771](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L771)

Start flow `id` proactively in a chat, without an inbound message (the user's replies
then flow into it as usual). A thin wrapper over [trigger](#trigger) with
`ifActive: 'replace'` — same access-list and handoff gates, per-chat FIFO slot,
language resolution, messaging seams and metrics — so it replaces a conversation
already running (or dormant) on the same key. Resolves `false` when the flow is
unknown, the subject is refused by the access lists (blacklist / whitelist) or the
chat is handed off; rejects when the bot is not started.

#### Parameters

| Parameter | Type |
| - | - |
| `id` | `string` |
| `target` | [`FlowTriggerTarget`](https://botmesh.afaya.com.co/api/core/interfaces/FlowTriggerTarget) |
| `opts?` | [`FlowTriggerOptions`](https://botmesh.afaya.com.co/api/core/interfaces/FlowTriggerOptions) |

#### Returns

`Promise`\<`boolean`>

#### Deprecated

Use [trigger](#trigger): `bot.trigger(id, { chatId, userId, isGroup, data, body, ifActive: 'replace' })`
(it resolves a [TriggerResult](https://botmesh.afaya.com.co/api/core/interfaces/TriggerResult.md); `result.started` is this method's boolean).

***

### listConversations()

```ts theme={null}
listConversations(): ConversationSnapshot[];
```

Defined in: [core/Bot.ts:776](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L776)

Snapshots of every live conversation (`key`, `state`, `waiting`, `queued`).

#### Returns

[`ConversationSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/ConversationSnapshot)\[]

***

### abortConversation()

```ts theme={null}
abortConversation(target): boolean;
```

Defined in: [core/Bot.ts:782](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L782)

Cancel the live conversation of `target` (a [ConversationTarget](https://botmesh.afaya.com.co/api/core/interfaces/ConversationTarget.md), e.g. a `ctx`,
or a raw runtime key from [listConversations](#listconversations)). Returns `false` when none is live.

#### Parameters

| Parameter | Type |
| - | - |
| `target` | `string` \| [`ConversationTarget`](https://botmesh.afaya.com.co/api/core/interfaces/ConversationTarget) |

#### Returns

`boolean`

***

### resetWelcome()

```ts theme={null}
resetWelcome(chatId, userId?): Promise<void>;
```

Defined in: [core/Bot.ts:807](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L807)

Re-arm the `WELCOME` trigger so the subject's next message is treated as a
first contact again (persisted in the store, so it survives restarts).

* `resetWelcome(dmChatId)` — the user of that DM.
* `resetWelcome(groupId, userId)` — one participant of a group.
* `resetWelcome(groupId)` — every participant of that group.

Called from a handler of the same chat it is ordered with that chat's
messages (the dispatcher's FIFO); called from elsewhere it races like any
last-writer-wins store write. Rejects if the store write fails (the
in-process state is re-armed regardless). `slashCommandsPlugin` calls it on `/reset`.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId` | `string` |
| `userId?` | `string` |

#### Returns

`Promise`\<`void`>

#### Example

```ts theme={null}
bot.command('bienvenida', async (ctx) => {
  await bot.resetWelcome(ctx.from, ctx.isGroup ? ctx.sender : undefined)
  await ctx.reply('Listo: tu próximo mensaje recibirá la bienvenida otra vez.')
})
```

***

### inspectConversation()

```ts theme={null}
inspectConversation(target): 
  | ConversationSnapshot
  | undefined;
```

Defined in: [core/Bot.ts:816](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L816)

Read-only snapshot of the live conversation for a chat (and participant, in
groups): captured `c.state`, whether it waits for a reply. `undefined` when
none is active. Diagnostics only — e.g. `botmesh dev`'s `:state` command.

#### Parameters

| Parameter | Type |
| - | - |
| `target` | [`ConversationTarget`](https://botmesh.afaya.com.co/api/core/interfaces/ConversationTarget) |

#### Returns

\| [`ConversationSnapshot`](https://botmesh.afaya.com.co/api/core/interfaces/ConversationSnapshot)
\| `undefined`

***

### isBusy()

```ts theme={null}
isBusy(): boolean;
```

Defined in: [core/Bot.ts:828](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L828)

True while the bot is still reacting to what it received: a provider event
is being stored or dispatched to its handlers (e.g. one awaiting an AI
call), or a conversation is running a step instead of waiting for the
user's reply. Work a handler starts without awaiting it is not tracked.
Diagnostics only — `botmesh dev` uses it to wait for slow replies when its
input is piped.

#### Returns

`boolean`

***

### before()

```ts theme={null}
before<E, TCtx>(
   event, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:842](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L842)

Register a `before` hook (higher `priority` runs first). Chainable. The context is typed
by the event ([HookContextMap](https://botmesh.afaya.com.co/api/core/interfaces/HookContextMap.md): `MessageContext` for `'message'`,
`SendHookContext` for `'send'`, …) plus `abort()`; a custom event's context is
`unknown` unless the handler annotates it (or `TCtx` is given).

#### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

#### Parameters

| Parameter | Type | Default value |
| - | - | - |
| `event` | `E` | `undefined` |
| `handler` | [`HookHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookHandler)\<[`HookBeforeContext`](https://botmesh.afaya.com.co/api/core/type-aliases/HookBeforeContext)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>>> | `undefined` |
| `priority?` | `number` | `0` |

#### Returns

`this`

***

### after()

```ts theme={null}
after<E, TCtx>(
   event, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:847](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L847)

Register an `after` hook (higher `priority` runs first). Chainable. Context typed like [before](#before).

#### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

#### Parameters

| Parameter | Type | Default value |
| - | - | - |
| `event` | `E` | `undefined` |
| `handler` | [`HookHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookHandler)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>> | `undefined` |
| `priority?` | `number` | `0` |

#### Returns

`this`

***

### onError()

```ts theme={null}
onError<E, TCtx>(
   event, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:855](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L855)

Register an `error`-phase hook: `(ctx, error)` with the failing context. `priority`
orders it like [before](#before)/[after](#after) (default 0).

#### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

#### Parameters

| Parameter | Type | Default value |
| - | - | - |
| `event` | `E` | `undefined` |
| `handler` | [`HookErrorHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookErrorHandler)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>> | `undefined` |
| `priority?` | `number` | `0` |

#### Returns

`this`

***

### hook()

#### Call Signature

```ts theme={null}
hook<E, TCtx>(
   event, 
   phase, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:860](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L860)

Register a hook for any phase: the generic form of [before](#before)/[after](#after)/[onError](#onerror).

##### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `E` |
| `phase` | `"before"` |
| `handler` | [`HookHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookHandler)\<[`HookBeforeContext`](https://botmesh.afaya.com.co/api/core/type-aliases/HookBeforeContext)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>>> |
| `priority?` | `number` |

##### Returns

`this`

#### Call Signature

```ts theme={null}
hook<E, TCtx>(
   event, 
   phase, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:861](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L861)

Register a hook for any phase: the generic form of [before](#before)/[after](#after)/[onError](#onerror).

##### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `E` |
| `phase` | `"after"` |
| `handler` | [`HookHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookHandler)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>> |
| `priority?` | `number` |

##### Returns

`this`

#### Call Signature

```ts theme={null}
hook<E, TCtx>(
   event, 
   phase, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:862](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L862)

Register a hook for any phase: the generic form of [before](#before)/[after](#after)/[onError](#onerror).

##### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `E` *extends* [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) | - |
|  `TCtx` | `unknown` |

##### Parameters

| Parameter | Type |
| - | - |
| `event` | `E` |
| `phase` | `"error"` |
| `handler` | [`HookErrorHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/HookErrorHandler)\<[`HookContextOf`](https://botmesh.afaya.com.co/api/core/type-aliases/HookContextOf)\<`E`, `TCtx`>> |
| `priority?` | `number` |

##### Returns

`this`

#### Call Signature

```ts theme={null}
hook(
   event, 
   phase, 
   handler, 
   priority?
): this;
```

Defined in: [core/Bot.ts:863](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L863)

Register a hook for any phase: the generic form of [before](#before)/[after](#after)/[onError](#onerror).

##### Parameters

| Parameter | Type |
| - | - |
| `event` | [`HookEvent`](https://botmesh.afaya.com.co/api/core/type-aliases/HookEvent) |
| `phase` | [`HookPhase`](https://botmesh.afaya.com.co/api/core/type-aliases/HookPhase) |
| `handler` | [`AnyHookHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/AnyHookHandler) |
| `priority?` | `number` |

##### Returns

`this`

***

### plug()

```ts theme={null}
plug<TConfig>(plugin, config?): () => void;
```

Defined in: [core/Bot.ts:902](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L902)

Install a plugin (optionally with `config`). Unlike [use](#use), returns an
unsubscriber (not the bot: do not chain) that first calls the plugin's `uninstall()`
and then removes, newest first, what it registered through `ctx.bot`: commands,
matchers, conversations/flow triggers, hooks, nested plugins, runtime flows and
`onDispose` callbacks. Calling it again is a no-op. It does NOT undo event listeners
(`on`/`once`), `provide()`d tools, `locale()` messages, `schedule`/`every`/`delay`
jobs, `onIdle` handlers or a flow `replaceFlow()` overwrote: undo those in
`ctx.onDispose()` (e.g. `ctx.bot.unprovide(name)`).

`install()` should be synchronous. If it throws, whatever it registered so far is
rolled back and the error is rethrown; if it returns a promise that rejects, the
rejection goes to the `'error'` event instead of crashing the process.

`spec.requires` lists plugin names that must already be plugged (a nested plugin may
require its parent); a missing one throws before `install()` runs. Flows registered
through `ctx.bot.registerFlow()` (or created by `ctx.bot.replaceFlow()`) are
unregistered on unplug.

One instance per plugin name: plugging a name that is already plugged throws (unplug
the first instance before plugging it again), unless every instance sets
`spec.multiple: true`.

`config` is typed by the plugin (`definePlugin<MyConfig>()`), so an unknown option or a
wrong type is a compile error.

#### Type Parameters

| Type Parameter | Default type |
| - | - |
|  `TConfig` | `Record`\<`string`, `unknown`> |

#### Parameters

| Parameter | Type |
| - | - |
| `plugin` | [`Plugin`](https://botmesh.afaya.com.co/api/core/type-aliases/Plugin)\<`TConfig`> |
| `config?` | `TConfig` |

#### Returns

() => `void`

#### Throws

when a plugin named in `spec.requires` is not plugged, or when a plugin
with the same `spec.name` is already plugged and `spec.multiple` is not set.

***

### locale()

#### Call Signature

```ts theme={null}
locale(code, messages): this;
```

Defined in: [core/Bot.ts:933](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L933)

Register (deep-merge) the messages of locale `code`, or — with an options
object — configure i18n (`defaultLocale`, `detect`, `providerLanguage`,
`userKey`, `locales`). Either form turns on per-message language resolution:
`ctx.user` preference → provider-reported language → `detect` → default,
limited to the `locales` allow-list when one is set.
Keys nest (`ctx.t('menu.title')`), `{param}` placeholders are interpolated
and `{ one, other, zero? }` leaves pick a plural form from `params.count`.
The built-in core messages live under `core.*` (`es` and `en` ship) and
can be overridden here. Throws `TypeError` on an invalid code or message tree.

##### Parameters

| Parameter | Type |
| - | - |
| `code` | `string` |
| `messages` | [`LocaleMessages`](https://botmesh.afaya.com.co/api/core/interfaces/LocaleMessages) |

##### Returns

`this`

##### Example

```ts theme={null}
bot.locale('es', { greeting: '¡Hola, {name}!', cart: { one: '{count} producto', other: '{count} productos' } })
bot.locale('en', { greeting: 'Hello, {name}!', cart: { one: '{count} item', other: '{count} items' } })
bot.locale({ defaultLocale: 'es' })
bot.when('hola', (ctx) => ctx.reply(ctx.t('greeting', { name: ctx.pushName ?? '' })))
bot.command('lang', async (ctx, [code]) => {
  if (!code || !bot.locales().includes(code.toLowerCase())) return ctx.reply(bot.locales().join(', '))
  await ctx.setLang(code)
})
```

#### Call Signature

```ts theme={null}
locale(options): this;
```

Defined in: [core/Bot.ts:934](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L934)

Register (deep-merge) the messages of locale `code`, or — with an options
object — configure i18n (`defaultLocale`, `detect`, `providerLanguage`,
`userKey`, `locales`). Either form turns on per-message language resolution:
`ctx.user` preference → provider-reported language → `detect` → default,
limited to the `locales` allow-list when one is set.
Keys nest (`ctx.t('menu.title')`), `{param}` placeholders are interpolated
and `{ one, other, zero? }` leaves pick a plural form from `params.count`.
The built-in core messages live under `core.*` (`es` and `en` ship) and
can be overridden here. Throws `TypeError` on an invalid code or message tree.

##### Parameters

| Parameter | Type |
| - | - |
| `options` | [`I18nConfig`](https://botmesh.afaya.com.co/api/core/interfaces/I18nConfig) |

##### Returns

`this`

##### Example

```ts theme={null}
bot.locale('es', { greeting: '¡Hola, {name}!', cart: { one: '{count} producto', other: '{count} productos' } })
bot.locale('en', { greeting: 'Hello, {name}!', cart: { one: '{count} item', other: '{count} items' } })
bot.locale({ defaultLocale: 'es' })
bot.when('hola', (ctx) => ctx.reply(ctx.t('greeting', { name: ctx.pushName ?? '' })))
bot.command('lang', async (ctx, [code]) => {
  if (!code || !bot.locales().includes(code.toLowerCase())) return ctx.reply(bot.locales().join(', '))
  await ctx.setLang(code)
})
```

***

### t()

```ts theme={null}
t(
   key, 
   params?, 
   lang?
): string;
```

Defined in: [core/Bot.ts:945](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L945)

Translate outside a handler (scheduled jobs, broadcasts): `lang` defaults to the
default locale. Pair it with [langOf](#langof) to use a user's stored preference.

#### Parameters

| Parameter | Type |
| - | - |
| `key` | `string` |
| `params?` | [`TranslateParams`](https://botmesh.afaya.com.co/api/core/type-aliases/TranslateParams) |
| `lang?` | `string` |

#### Returns

`string`

***

### langOf()

```ts theme={null}
langOf(userId): Promise<string>;
```

Defined in: [core/Bot.ts:955](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L955)

The stored language preference of `userId` (`ctx.setLang`) when a registered locale
serves it, else the default locale — the same language `ctx.lang` would resolve from
the stored value (always the default while i18n is off). A store read failure
resolves the default (logged at debug level).

#### Parameters

| Parameter | Type |
| - | - |
| `userId` | `string` |

#### Returns

`Promise`\<`string`>

***

### locales()

```ts theme={null}
locales(): string[];
```

Defined in: [core/Bot.ts:960](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L960)

Registered locale codes, built-in `es`/`en` included.

#### Returns

`string`\[]

***

### provide()

```ts theme={null}
provide<T>(name, value): this;
```

Defined in: [core/Bot.ts:970](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L970)

Inject `value` as `ctx.tools[name]` in every handler (replacing a previous value under
the same name). Returns the bot, so calls can be chained. Undo it with [unprovide](#unprovide).

#### Type Parameters

| Type Parameter |
| - |
|  `T` *extends* `string` |

#### Parameters

| Parameter | Type |
| - | - |
| `name` | `T` |
| `value` | `unknown` |

#### Returns

`this`

***

### unprovide()

```ts theme={null}
unprovide(name): boolean;
```

Defined in: [core/Bot.ts:981](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L981)

Remove the tool injected under `name` by [provide](#provide) (the inverse of `provide`, as
[unregisterFlow](#unregisterflow) is of `registerFlow`). Returns `true` when a tool was removed,
`false` when none was provided under that name. Unplugging a plugin does not undo its
`provide()` calls: call this from `ctx.onDispose()`.

#### Parameters

| Parameter | Type |
| - | - |
| `name` | `string` |

#### Returns

`boolean`

***

### schedule()

#### Call Signature

```ts theme={null}
schedule(cron, fn): ScheduledTask;
```

Defined in: [core/Bot.ts:996](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L996)

Run `fn` on a cron expression (e.g. `'0 9 * * *'`).

##### Parameters

| Parameter | Type |
| - | - |
| `cron` | `string` |
| `fn` | () => `void` \| `Promise`\<`void`> |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

#### Call Signature

```ts theme={null}
schedule(
   cron, 
   opts, 
   fn
): ScheduledTask;
```

Defined in: [core/Bot.ts:1001](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1001)

Durable cron task: its schedule is stored under `opts.id` (see `BotConfig.scheduler`),
survives restarts with the `opts.missed` policy, and each occurrence runs on one replica.

##### Parameters

| Parameter | Type |
| - | - |
| `cron` | `string` |
| `opts` | [`DurableTaskOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DurableTaskOptions) |
| `fn` | [`DurableTaskHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/DurableTaskHandler) |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

#### Call Signature

```ts theme={null}
schedule(
   cron, 
   opts, 
   fn
): ScheduledTask;
```

Defined in: [core/Bot.ts:1006](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1006)

Cron task read in a time zone: `bot.schedule('0 9 * * 1-5', { timeZone: 'America/Bogota' }, fn)`
(see [CronTaskOptions](https://botmesh.afaya.com.co/api/core/interfaces/CronTaskOptions.md) for the daylight-saving rules). Add an `id` to make it durable.

##### Parameters

| Parameter | Type |
| - | - |
| `cron` | `string` |
| `opts` | [`CronTaskOptions`](https://botmesh.afaya.com.co/api/core/interfaces/CronTaskOptions) |
| `fn` | () => `void` \| `Promise`\<`void`> |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

***

### every()

#### Call Signature

```ts theme={null}
every(interval, fn): ScheduledTask;
```

Defined in: [core/Bot.ts:1015](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1015)

Run `fn` every `interval` (a duration such as `'10m'`, or ms).

##### Parameters

| Parameter | Type |
| - | - |
| `interval` | `string` \| `number` |
| `fn` | () => `void` \| `Promise`\<`void`> |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

#### Call Signature

```ts theme={null}
every(
   interval, 
   opts, 
   fn
): ScheduledTask;
```

Defined in: [core/Bot.ts:1017](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1017)

Durable interval task (see the durable [schedule](#schedule) overload); slots do not drift.

##### Parameters

| Parameter | Type |
| - | - |
| `interval` | `string` \| `number` |
| `opts` | [`DurableTaskOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DurableTaskOptions) |
| `fn` | [`DurableTaskHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/DurableTaskHandler) |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

***

### delay()

#### Call Signature

```ts theme={null}
delay(duration, fn): ScheduledTask;
```

Defined in: [core/Bot.ts:1022](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1022)

Run `fn` once after `duration` (a duration such as `'30s'`, or ms).

##### Parameters

| Parameter | Type |
| - | - |
| `duration` | `string` \| `number` |
| `fn` | () => `void` \| `Promise`\<`void`> |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

#### Call Signature

```ts theme={null}
delay(
   duration, 
   opts, 
   fn
): ScheduledTask;
```

Defined in: [core/Bot.ts:1028](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1028)

Durable one-shot task: its run time is fixed when `opts.id` is first stored, so a
restart does not push it back, provided the code registers the id again at boot (only
the schedule is stored, not the handler). See the durable [schedule](#schedule) overload.

##### Parameters

| Parameter | Type |
| - | - |
| `duration` | `string` \| `number` |
| `opts` | [`DurableTaskOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DurableTaskOptions) |
| `fn` | [`DurableTaskHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/DurableTaskHandler) |

##### Returns

[`ScheduledTask`](https://botmesh.afaya.com.co/api/core/interfaces/ScheduledTask)

***

### forgetTask()

```ts theme={null}
forgetTask(id): Promise<void>;
```

Defined in: [core/Bot.ts:1037](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1037)

Delete the stored schedule of a durable task `id` (the bot's store namespace is
applied, as on registration): an orphan logged at start (stored, no longer registered
in code), a one-shot tombstone, or a registered task, which is cancelled as well.

#### Parameters

| Parameter | Type |
| - | - |
| `id` | `string` |

#### Returns

`Promise`\<`void`>

***

### onIdle()

```ts theme={null}
onIdle(duration, handler): () => void;
```

Defined in: [core/Bot.ts:1062](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1062)

Run `handler` once when a chat stays quiet for `duration` (`'10m'`, `'1h'`, `'1d'`, ms…) after
its last processed inbound message. Every new inbound message from that chat reschedules it,
and re-arms it after it fired. `ctx` is that last message's context, so
`ctx.reply('¿Sigues ahí?')` answers in the right chat. Handler errors go to the bot
`'error'` event. Pending timers are cancelled by [clearIdle](#clearidle), by the returned
unsubscribe and by `stop()`. The handler never runs for a chat in human handoff: a
`'handoff'` event carrying `{ chatId }` cancels that chat's timers, and its messages do not
re-arm them until a `'resume'` event for that chat (the bot's own `isHandedOff()` state is
honoured too, when present). `duration` must be positive and at most 2^31 − 1 ms (about
24.8 days, the longest a Node timer can wait); otherwise it throws `RangeError`.

#### Parameters

| Parameter | Type |
| - | - |
| `duration` | `string` \| `number` |
| `handler` | [`IdleHandler`](https://botmesh.afaya.com.co/api/core/type-aliases/IdleHandler) |

#### Returns

() => `void`

#### Example

```ts theme={null}
bot.onIdle('10m', async (ctx, { idleMs }) => {
  await ctx.reply(`¿Sigues ahí? (${idleMs / 60_000} min sin respuesta)`)
})
```

***

### clearIdle()

```ts theme={null}
clearIdle(chatId?): void;
```

Defined in: [core/Bot.ts:1070](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1070)

Cancel pending [onIdle](#onidle) timers for `chatId` (every chat when omitted) — e.g. when a
human agent takes the chat over. They re-arm on that chat's next processed inbound message.

#### Parameters

| Parameter | Type |
| - | - |
| `chatId?` | `string` |

#### Returns

`void`

***

### getStore()

```ts theme={null}
getStore(): IStore;
```

Defined in: [core/Bot.ts:1078](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1078)

#### Returns

[`IStore`](https://botmesh.afaya.com.co/api/core/interfaces/IStore)

***

### getProvider()

```ts theme={null}
getProvider(): IProvider;
```

Defined in: [core/Bot.ts:1079](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1079)

#### Returns

[`IProvider`](https://botmesh.afaya.com.co/api/core/interfaces/IProvider)

***

### getConnectionState()

```ts theme={null}
getConnectionState(): ConnectionState;
```

Defined in: [core/Bot.ts:1080](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1080)

#### Returns

[`ConnectionState`](https://botmesh.afaya.com.co/api/core/type-aliases/ConnectionState)

***

### getNamespace()

```ts theme={null}
getNamespace(): Readonly<StoreNamespace>;
```

Defined in: [core/Bot.ts:1081](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1081)

#### Returns

`Readonly`\<[`StoreNamespace`](https://botmesh.afaya.com.co/api/core/interfaces/StoreNamespace)>

***

### getSessionName()

```ts theme={null}
getSessionName(): string;
```

Defined in: [core/Bot.ts:1082](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1082)

#### Returns

`string`

***

### user()

```ts theme={null}
user(userId): UserData;
```

Defined in: [core/Bot.ts:1094](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1094)

Persistent profile of any subject — the same data a handler sees as
`ctx.user` when that subject writes (scheduled jobs, webhooks, admin code).
Requires a store implementing the user-data contract (every built-in one).

#### Parameters

| Parameter | Type |
| - | - |
| `userId` | `string` |

#### Returns

[`UserData`](https://botmesh.afaya.com.co/api/core/interfaces/UserData)

#### Example

```ts theme={null}
await bot.user('5491122334455').ns('billing').set('plan', 'pro')
```

***

### purgeExpiredUserData()

```ts theme={null}
purgeExpiredUserData(): Promise<number>;
```

Defined in: [core/Bot.ts:1102](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1102)

Physically remove expired `ctx.user` entries store-wide and resolve with
how many were removed (`0` with native-TTL stores such as Redis). Writes
already trigger this at most once a minute; schedule it for idle bots:
`bot.every('1h', () => bot.purgeExpiredUserData())`.

#### Returns

`Promise`\<`number`>

***

### exportSubject()

```ts theme={null}
exportSubject(userId): Promise<SubjectDataExport>;
```

Defined in: [core/Bot.ts:1105](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1105)

Export normalized data associated with one subject in this bot namespace.

#### Parameters

| Parameter | Type |
| - | - |
| `userId` | `string` |

#### Returns

`Promise`\<[`SubjectDataExport`](https://botmesh.afaya.com.co/api/core/interfaces/SubjectDataExport)>

***

### deleteSubject()

```ts theme={null}
deleteSubject(userId): Promise<SubjectDeletionResult>;
```

Defined in: [core/Bot.ts:1113](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1113)

Delete normalized subject data in this bot namespace, including the handoff of chat
`userId` and the subject's live or dormant conversations.

#### Parameters

| Parameter | Type |
| - | - |
| `userId` | `string` |

#### Returns

`Promise`\<[`SubjectDeletionResult`](https://botmesh.afaya.com.co/api/core/interfaces/SubjectDeletionResult)>

***

### flowInventory()

```ts theme={null}
flowInventory(): FlowInventory;
```

Defined in: [core/Bot.ts:1125](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1125)

Read-only snapshot of the registered flows, conversations and trigger routes,
plus the bits of config the linter needs. Input of `describeFlows()`/`lintFlows()`.

#### Returns

[`FlowInventory`](https://botmesh.afaya.com.co/api/core/interfaces/FlowInventory)

***

### describe()

#### Call Signature

```ts theme={null}
describe(options): FlowGraph;
```

Defined in: [core/Bot.ts:1139](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1139)

Describe every registered flow/conversation as a Mermaid flowchart (default)
or, with `{ format: 'json' }`, as a JSON graph. See [describeFlows](https://botmesh.afaya.com.co/api/core/functions/describeFlows.md).

##### Parameters

| Parameter | Type |
| - | - |
| `options` | [`DescribeOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DescribeOptions) & `object` |

##### Returns

[`FlowGraph`](https://botmesh.afaya.com.co/api/core/interfaces/FlowGraph)

##### Example

```ts theme={null}
writeFileSync('flows.mmd', bot.describe())        // open in mermaid.live or any Mermaid viewer
const graph = bot.describe({ format: 'json' })    // { version, flows, groups, nodes, edges }
```

#### Call Signature

```ts theme={null}
describe(options?): string;
```

Defined in: [core/Bot.ts:1140](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1140)

Describe every registered flow/conversation as a Mermaid flowchart (default)
or, with `{ format: 'json' }`, as a JSON graph. See [describeFlows](https://botmesh.afaya.com.co/api/core/functions/describeFlows.md).

##### Parameters

| Parameter | Type |
| - | - |
| `options?` | [`DescribeOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DescribeOptions) & `object` |

##### Returns

`string`

##### Example

```ts theme={null}
writeFileSync('flows.mmd', bot.describe())        // open in mermaid.live or any Mermaid viewer
const graph = bot.describe({ format: 'json' })    // { version, flows, groups, nodes, edges }
```

#### Call Signature

```ts theme={null}
describe(options?): string | FlowGraph;
```

Defined in: [core/Bot.ts:1141](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1141)

Describe every registered flow/conversation as a Mermaid flowchart (default)
or, with `{ format: 'json' }`, as a JSON graph. See [describeFlows](https://botmesh.afaya.com.co/api/core/functions/describeFlows.md).

##### Parameters

| Parameter | Type |
| - | - |
| `options?` | [`DescribeOptions`](https://botmesh.afaya.com.co/api/core/interfaces/DescribeOptions) |

##### Returns

`string` | [`FlowGraph`](https://botmesh.afaya.com.co/api/core/interfaces/FlowGraph)

##### Example

```ts theme={null}
writeFileSync('flows.mmd', bot.describe())        // open in mermaid.live or any Mermaid viewer
const graph = bot.describe({ format: 'json' })    // { version, flows, groups, nodes, edges }
```

***

### lint()

```ts theme={null}
lint(options?): LintDiagnostic[];
```

Defined in: [core/Bot.ts:1153](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L1153)

Statically lint the registered flows: unreachable steps/flows, missing goto
targets, empty/duplicate triggers, risky timeouts, ambiguous menus, … See [lintFlows](https://botmesh.afaya.com.co/api/core/functions/lintFlows.md).

#### Parameters

| Parameter | Type |
| - | - |
| `options?` | [`LintOptions`](https://botmesh.afaya.com.co/api/core/interfaces/LintOptions) |

#### Returns

[`LintDiagnostic`](https://botmesh.afaya.com.co/api/core/interfaces/LintDiagnostic)\[]

#### Example

```ts theme={null}
for (const d of bot.lint({ minSeverity: 'warning' })) bot.logger.warn(d, d.message)
```

## Accessors

### durability

#### Get Signature

```ts theme={null}
get durability(): DurabilityControl | undefined;
```

Defined in: [core/Bot.ts:411](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L411)

Durable message processing controls — the inbox/outbox journals, operator replay/retry
of dead-lettered records and counters. `undefined` unless `BotConfig.durability` is set.

##### Example

```ts theme={null}
for (const r of await bot.durability!.outbox.list({ state: 'dead' })) await bot.durability!.retrySend(r.key)
```

##### Returns

[`DurabilityControl`](https://botmesh.afaya.com.co/api/core/interfaces/DurabilityControl) | `undefined`

***

### tracing

#### Get Signature

```ts theme={null}
get tracing(): BotTracing;
```

Defined in: [core/Bot.ts:520](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L520)

The bot's tracing (`BotConfig.telemetry`): start your own spans under the bot's, or
check `enabled`. Plugins (`@botmesh/ai`) use it to add their spans to the same trace.
Without `telemetry` it is a disabled no-op ([BotTracing.enabled](https://botmesh.afaya.com.co/api/core/interfaces/BotTracing.md#enabled) `false`).

##### Example

```ts theme={null}
bot.when('pedido', async (ctx) => {
  await bot.tracing.trace('erp.lookup', {}, () => erp.find(ctx.body))
})
```

##### Returns

[`BotTracing`](https://botmesh.afaya.com.co/api/core/interfaces/BotTracing)

***

### injectTools

#### Get Signature

```ts theme={null}
get injectTools(): DefaultTools & Record<string, unknown>;
```

Defined in: [core/Bot.ts:987](https://github.com/andresayac/botmesh/blob/main/packages/core/src/core/Bot.ts#L987)

##### Returns

[`DefaultTools`](https://botmesh.afaya.com.co/api/core/interfaces/DefaultTools) & `Record`\<`string`, `unknown`>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.