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

# Exports & events

> Send messages, register suggestions, and hook into chat from your own scripts.

Awoken Chat exposes a small Lua API on both server and client, plus full compatibility with the legacy `chat:addMessage` / `chat:addSuggestion` shape so existing resources keep working unchanged.

<Tip>
  Anything using `exports.chat:addMessage(...)` or `TriggerEvent('chatMessage', ...)` keeps working out of the box - Awoken Chat declares `provide 'chat'` in its manifest and listens for those events natively.
</Tip>

## Server-side exports

### Send a message

Server-authoritative send. Goes through the full pipeline (antispam, blocked-word filter, escalation, mentions, webhooks, proximity filtering).

```lua theme={"dark"}
exports['awoken_chat']:send(source, channelId, body, opts)
```

| Argument              | Type       | Notes                                                                                                                                      |
| --------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `source`              | `number`   | Player server id. Pass `0` for system messages (skips antispam).                                                                           |
| `channelId`           | `string`   | One of the category ids - `'local'`, `'ooc'`, `'me'`, `'staff'`, etc. Custom categories work too.                                          |
| `body`                | `string`   | Message text. Supports Markdown (`**bold**`, `*italic*`, `~~strike~~`, `__underline__`, `` `code` ``, ` ```block``` `, `\|\|spoiler\|\|`). |
| `opts.senderName`     | `string?`  | Override the resolved sender name.                                                                                                         |
| `opts.overrideSender` | `boolean?` | If true, the body is already pre-rendered with the sender baked in (e.g. `/try` previews).                                                 |
| `opts.kind`           | `string?`  | `'message'` (default), `'emote'`, `'compat'`, `'system'`, `'job'`, `'pm'`, `'discord'`.                                                    |
| `opts.replyTo`        | `table?`   | `{ id, senderName, body }` - renders a quote pill above the message.                                                                       |

```lua theme={"dark"}
-- Plain message from a player
exports['awoken_chat']:send(source, 'ooc', 'Hello world')

-- System broadcast (channel id, no sender)
exports['awoken_chat']:send(0, 'global', 'Server restarting in 5 minutes.', {
    kind = 'system',
})
```

### System notification

Sends a coloured info/success/warning/error toast to one or all players. Bypasses the full message pipeline - shows as a single non-archived line.

```lua theme={"dark"}
exports['awoken_chat']:system(target, body, type)
```

| Argument | Type      | Notes                                                      |
| -------- | --------- | ---------------------------------------------------------- |
| `target` | `number`  | Player server id, or `-1` to broadcast to everyone.        |
| `body`   | `string`  | Toast text. Markdown supported.                            |
| `type`   | `string?` | `'inform'` (default), `'success'`, `'warning'`, `'error'`. |

```lua theme={"dark"}
exports['awoken_chat']:system(source,  'Welcome back!',           'success')
exports['awoken_chat']:system(source,  'You are at the limit.',   'warning')
exports['awoken_chat']:system(-1,      'Server going to restart', 'inform')
```

### List configured channels

Returns the live category list (DB rows merged with the in-code defaults). Useful for admin panels or external integrations that need to know what channels exist.

```lua theme={"dark"}
local channels = exports['awoken_chat']:getChannels()
-- channels[i] = { id, label, color, icon, command, proximity, permission, job, gang, ... }
```

### Look up a single category

```lua theme={"dark"}
local cat = exports['awoken_chat']:getCategoryById('me')
-- cat = { id='me', command='me', proximity=20, threeD=true, ... }  or nil
```

***

## Server-side events

### Inbound from clients

| Event                      | Payload                       | Notes                                                                                                                   |
| -------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `awoken_chat:send`         | `(channelId, body, replyTo?)` | Fired by the NUI when a player sends. You usually don't trigger this yourself - prefer the `send` export.               |
| `awoken_chat:requestInit`  | *none*                        | Triggered by the client when the NUI boots. Server responds with `awoken_chat:init`.                                    |
| `awoken_chat:saveSettings` | `partial`                     | Player-tier settings save (per-license). Validated server-side; admin-tier keys silently dropped for non-admin senders. |

### Outbound to clients

| Event                       | Payload        | Purpose                                                                                                                               |
| --------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `awoken_chat:receive`       | `payload`      | A chat message intended for the recipient.                                                                                            |
| `awoken_chat:system`        | `(body, kind)` | A system toast.                                                                                                                       |
| `awoken_chat:clear`         | *none*         | Wipe the recipient's local chat history.                                                                                              |
| `awoken_chat:channels`      | `list`         | The recipient's currently-visible category list. Fired on admin save, framework job/gang change, or via the connect-time diff poller. |
| `awoken_chat:roster`        | `list`         | Active player list used by the `@`-mention picker.                                                                                    |
| `awoken_chat:identity`      | `payload`      | Recipient's own resolved identity (firstName/lastName/job/gang/tags).                                                                 |
| `awoken_chat:globalChanged` | `partial`      | Admin changed a server-wide setting (shell / layout / etc.).                                                                          |

***

## Legacy `chat` compatibility

Every resource that interacts with the stock chat keeps working unchanged.

### `chat:addMessage`

```lua theme={"dark"}
-- Existing code:
TriggerClientEvent('chat:addMessage', source, {
    color = { 0, 229, 255 },
    args  = { 'SYSTEM', 'Welcome to the server!' },
})

-- Awoken Chat picks this up and renders it as a system-styled message
-- in the default channel for that player.
```

### Exports namespace

`exports.chat:addMessage` / `addSuggestion` / `removeSuggestion` / `addSuggestions` are all wired to the matching Awoken handlers via FXServer's `__cfx_export_chat_*` internal events. **No code changes needed in your other resources.**

```lua theme={"dark"}
-- Both of these resolve to Awoken Chat:
exports.chat:addSuggestion('/garage', 'Open the garage UI', {
    { name = 'action', help = 'store | take' },
})
exports.awoken_chat:addSuggestion('/garage', 'Open the garage UI', {
    { name = 'action', help = 'store | take' },
})
```

### Suggestion events

The legacy net events still fire:

```lua theme={"dark"}
TriggerClientEvent('chat:addSuggestion',    target, name, help, params)
TriggerClientEvent('chat:removeSuggestion', target, name)
TriggerClientEvent('chat:addSuggestions',   target, items)
```

***

## Client-side exports

Lighter API - mostly affordances for opening the chat or executing a command programmatically.

```lua theme={"dark"}
-- Open the chat with an empty input row (player can type freely)
TriggerEvent('awoken_chat:open')

-- Open with `/` prefilled (command mode)
TriggerEvent('awoken_chat:openCommand')

-- Execute a slash command directly (bypasses the chat box)
ExecuteCommand('me waves')
```

<Tip>
  The NUI listens for `awoken_chat:*` events for chat state; raw `SendNUIMessage` calls from outside the resource are not supported. Use the events above or the server `:send` export.
</Tip>

***

## Net event signatures (advanced)

If you're writing a tightly-integrated resource that listens on the awoken event surface directly:

```lua theme={"dark"}
-- Server -> Client: a message arrived
RegisterNetEvent('awoken_chat:receive', function(payload)
    -- payload = {
    --   id, channel, body, senderName, senderId, senderFirstName,
    --   avatarUrl, color, icon, label, time, kind,
    --   tags, mentions, replyTo, reactions, myReactions,
    --   threeD, threeDOnly, threeDAnchorId, threeDDurationMs,
    --   anonymous,
    -- }
end)

-- Server -> Client: per-player visible-channels list refresh
RegisterNetEvent('awoken_chat:channels', function(list)
    -- list[i] = { id, label, color, icon, command, proximity, default,
    --             anonymous, visibility, threeD, allowReplies, allowReactions }
end)
```

<Warning>
  Treat these payloads as **read-only forward compatibility surfaces**. Awoken Chat may add fields in future versions; mutate at your own risk.
</Warning>
