# API reference

Source: https://docs.gryt.chat/docs/bot/api-reference

Everything @gryt/bot exports, generated from the source

{/* Generated by .github/scripts/generate-api-reference.mjs in the monorepo.
    Do not edit this file. Change the source it reads, then run the script. */}

This is the reference. [Writing a bot](https://docs.gryt.chat/docs/bot) is the page that teaches the
shape: the handshake, waiting to be approved, and what a bot does when an admin
says no.

Everything below is exported from `@gryt/bot`. Nothing else in the package is
public.

```ts

```

### `GrytBot`

A bot on one Gryt server.

It joins like any other client and is a member like any other: no bot account
type, no bot token, no bypass. What it may do is what its role says.

So the interesting failure is a permission failure. `can()` answers from what
the server said, and sending without the permission throws here with the
permission's name rather than surfacing as a `server:error` later.

```ts
const bot = new GrytBot({ host: "localhost:5001", nickname: "Helper" });

bot.command("ping", async (ctx) => ctx.reply("pong"), {
  description: "Check I am alive",
  requires: ["send_messages"],
});

await bot.start();
```

#### `can()`

```ts
can(permission: Permission): boolean
```

False before `ready`: a bot acting on what it assumes it may do finds out
over the wire. True for a permission the server's catalogue does not have —
that is a server older than the permission, not a refusal.
#### `command()`

```ts
command(name: string, handler: (ctx: CommandContext) => void | Promise<void>, options: CommandOptions = {}): this
```

Register a command. Later registrations of the same name replace earlier.
#### `start()`

```ts
start(): Promise<ServerInfo>
```

Connect, join, and resolve once the server has said who this bot is.

On a first run against a server that has not approved it, this does not
resolve — the bot is waiting at the door, which is a state and not a
failure. Listen for `waiting`, and for `ready` when somebody answers.
#### `stop()`

```ts
stop(): Promise<void>
```

Leave, and stop reconnecting.
#### `send()`

```ts
send(conversationId: string, text: string): Promise<void>
```

Post in a channel.

Throws before sending anything if the bot lacks `send_messages`, naming
the permission. The server would refuse it anyway; failing here means the
stack trace points at the call rather than at a socket handler.
#### `react()`

```ts
react(conversationId: string, messageId: string, reactionSrc: string): Promise<void>
```

#### `delete()`

```ts
delete(conversationId: string, messageId: string, opts: { own?: boolean } = {}): Promise<void>
```

Delete a message.

Its own is `delete_own_messages`; anybody else's is `manage_messages`. The
caller says which it is, because the bot does not necessarily know who sent
a message it was handed.
#### `fetch()`

```ts
fetch(conversationId: string, limit = 50): Promise<void>
```

Ask for the last N messages in a channel. Answered on the `message` event.
### `GrytBotEvents`

| Field | Type | What it is |
| --- | --- | --- |
| `ready` | `[ServerInfo]` |  |
| `message` | `[Message]` |  |
| `members` | `[Member[]]` |  |
| `channels` | `[Channel[]]` |  |
| `error` | `[Error]` | Something the server refused. Always worth logging; often a permission. |
| `waiting` | `[string]` | Turned away pending approval. Not an error — see the note in `wire`. |
| `disconnected` | `[string]` |  |

### `GrytBotOptions`

| Field | Type | What it is |
| --- | --- | --- |
| `host` | `string` | `chat.example.com`, or `localhost:5001`. Scheme optional. |
| `nickname?` | `string` | What the member list will call it. |
| `identityPath?` | `string` | Where the key lives. The file *is* the bot — see identity.ts. |
| `identity?` | `BotIdentity` | An already-loaded identity, if you keep the key somewhere of your own. |
| `wants?` | `string[]` | Sent once, the first time it turns up, and shown to whoever approves it. Ask for the least that works. **Fixed from then on.** A later run declaring more gets the answer to the question the first one asked — the run asking for more may not be yours. |
| `description?` | `string` | One line, shown beside the ask. Say what the bot is for. |
| `botToken?` | `string` | A token from a registration an operator set up in advance. The unattended path: no approval to wait for, because the approving already happened. Single-use — the first bot to present it becomes that registration. |
| `prefix?` | `string` | The command prefix. Set to "" to turn the router off entirely. |
| `helpCommand?` | `boolean` | Whether to answer `help` with a listing. On by default. |
| `secure?` | `boolean` | Force http/https rather than guessing from the host. |

### `parseCommand`

Which command a message invokes, if any.

Case-insensitive on the command word, because somebody will type `!Help` and
being right about it helps nobody.

```ts
parseCommand(text: string, prefix: string): { name: string; rest: string } | null
```
### `splitArgs`

```ts
splitArgs(rest: string): string[]
```
### `CommandContext`

| Field | Type | What it is |
| --- | --- | --- |
| `message` | `Message` | The message that invoked it. |
| `rest` | `string` | Everything after the command word, trimmed. Empty string, never null. |
| `args` | `string[]` | `rest` split on whitespace, with empties dropped. |
| `reply` | `(text: string): Promise<void>` | Reply in the channel the command came from. |
| `react` | `(emoji: string): Promise<void>` | React to the message that invoked it. |

### `CommandOptions`

| Field | Type | What it is |
| --- | --- | --- |
| `description?` | `string` | One line, for the help listing. |
| `requires?` | `Permission[]` | Permissions the *bot* needs before this command is worth offering. Checked before the handler runs, so a command that replies is skipped outright on a server where the bot may not post — rather than running, failing at the socket, and leaving whoever typed it watching nothing happen. This is about the bot, not about the person who typed it: what *they* may do is the server's business and it is already enforcing it. |

### `RegisteredCommand`

| Field | Type | What it is |
| --- | --- | --- |
| `name` | `string` |  |
| `handler` | `(ctx: CommandContext) => void \| Promise<void>` |  |

### `createIdentity`

Mint a new identity. The bot this belongs to has never been seen anywhere.

```ts
createIdentity(): Promise<{ identity: BotIdentity; privateJwk: JWK; }>
```
### `loadIdentity`

The second run must be the same bot: same id, same role, same history. A key
generated per start arrives as a new member every time.

Written `0o600` — anyone who can read this file can be this bot.

```ts
loadIdentity(path: string): Promise<BotIdentity>
```
### `PERMISSIONS_BEFORE_CATALOGUE`

Stands in for the catalogue on a server too old to publish one, so an absent
permission is not read as a refusal.

**Frozen.** It describes a release that has already happened, and never grows.

```ts
PERMISSIONS_BEFORE_CATALOGUE: readonly Permission[] = [ "send_messages", "attach_files", "add_reactions", "join_voice", "speak", "share_video", "share_screen", "change_nickname", "change_avatar", "create_invite", "manage_invites", "manage_messages", "kick_members", "ban_members", "mute_members", "manage_reports", "manage_join_requests", "manage_channels", "manage_emojis", "manage_webhooks", "manage_roles", "manage_server", "view_audit_log", ]
```
### `BotIdentity`

| Field | Type | What it is |
| --- | --- | --- |
| `subject` | `string` | The id this bot will be known by on every server. Derived from the key. |
| `certificate` | `(): Promise<string>` | A certificate that vouches for itself, valid for an hour. |
| `assertion` | `(audience: string, nonce: string): Promise<string>` | Proof, bound to one server's challenge, that this bot holds the key. |

### `Attachment`

| Field | Type | What it is |
| --- | --- | --- |
| `file_id` | `string` |  |
| `mime` | `string \| null` |  |
| `size` | `number \| null` |  |
| `original_name` | `string \| null` |  |
| `width` | `number \| null` |  |
| `height` | `number \| null` |  |
| `has_thumbnail` | `boolean` |  |

### `Channel`

| Field | Type | What it is |
| --- | --- | --- |
| `id` | `string` |  |
| `name` | `string` |  |
| `type` | `"text" \| "voice"` |  |

### `ServerRefusal`

Why the server refused something.

The machine-readable half is `error`, which is what the server actually
sends; `code` is accepted too because it is the name half of this SDK reached
for first and getting it wrong turned "waiting to be approved" into a crash.

| Field | Type | What it is |
| --- | --- | --- |
| `error?` | `string` |  |
| `code?` | `string` |  |
| `message?` | `string` |  |
| `permission?` | `string` | Named when the refusal was a permission. |

### `Member`

| Field | Type | What it is |
| --- | --- | --- |
| `serverUserId` | `string` |  |
| `nickname` | `string` |  |
| `role` | `string` |  |
| `status` | `"online" \| "in_voice" \| "afk" \| "offline"` |  |
| `avatarFileId` | `string \| null` |  |

### `Message`

| Field | Type | What it is |
| --- | --- | --- |
| `conversationId` | `string` |  |
| `messageId` | `string` |  |
| `senderServerUserId` | `string` |  |
| `senderNickname` | `string \| null` |  |
| `text` | `string \| null` |  |
| `attachments` | `Attachment[]` |  |
| `createdAt` | `Date` |  |
| `editedAt` | `Date \| null` |  |
| `replyToMessageId` | `string \| null` |  |
| `isSystem` | `boolean` | True for the "X joined the server" kind of message, which has no sender. |
| `isOwn` | `boolean` | True when this bot sent it. Handlers are not called for these. |

### `Permission`

A permission id. The server owns the list; see `GrytBot.permissions`.

```ts
export type Permission = string;
```
### `ServerInfo`

| Field | Type | What it is |
| --- | --- | --- |
| `serverId` | `string` |  |
| `name` | `string` |  |
| `description` | `string` |  |
| `permissions` | `Permission[]` | What this bot may do here. Empty until the server has said. |
| `role` | `string` | The role this bot holds. |
