> For the complete documentation index, see [llms.txt](https://docs.crystxlz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.crystxlz.com/resources/chat.md).

# Chat

## Step 1: **Download and Extract**

**Download the resource and extract the `.zip` file into your `resources` folder.**

**Ensure the resource by adding it to your `server.cfg`:**

```
ensure crystal-chat
```

**Alternatively, you can ensure the folder containing this resource if it’s inside a resource container.**

## **Step 2: Configuration**

**Config File Overview**

**Below is a detailed explanation of the configuration options for Crystal Chat.**

```lua
-- Configuration Settings for Crystal Chat

-- The script automatically detects which framework you're using.
-- It checks if either 'es_extended' (ESX) or 'qb-core' (QB) is available.
-- If neither is found, it defaults to 'custom'.
local hasEsx = GetResourceState('es_extended') ~= 'missing'
local hasQb = GetResourceState('qb-core') ~= 'missing'

Config = {}

-- [Framework]
-- This setting defines which framework you're using.
-- It will automatically set to:
-- - 'esx' if using ESX
-- - 'qb' if using QB
-- - 'custom' if neither are detected.
-- You shouldn't need to change this unless you're using a custom framework.
Config.Framework = hasEsx and 'esx' or hasQb and 'qb' or 'custom'

-- [Server Print]
-- Enables or disables server print messages.
Config.ServerPrint = true

-- [Interaction Key Configuration]
-- These keys define the player controls for interacting with the chat system:
-- 'open': Key to open the chat interface (default: 'T').
-- 'hide': Key to permanently close the chat interface. To reopen it, the 'hide' key must be pressed again (default: 'L').
Config.Keys = {
    open = 'T',
    hide = 'L'
}

-- [Default Message Settings]
-- Configuration for the default message sent in chat without using a command (e.g., just typing in chat).
Config.DefaultMessage = {
    enable = true, -- Whether the default message is enabled.
    tag = 'General' -- Tag associated with default messages.
}

-- [Player Message Settings]
-- Configuration for messages sent in chat when a player joins or quits the server.
-- When enabled, a message with the 'server' tag will inform players of these events.
Config.PlayerMessage = {
    onEnter = true, -- Enable message when a player joins the server.
    onExit = true, -- Enable message when a player leaves the server.
    tag = 'Server' -- Tag for messages related to player join/quit notifications.
}

-- [Advert Configuration]
-- This section defines which job roles have permission to use the advert command in chat.
-- Each job can be set to true to allow them to send advertisements.
Config.Advert = {
    ['cardealer'] = true -- 'cardealer' job can use the advert command in chat.
}

-- [Job Settings]
-- Configuration for job-related functionalities. This allows you to specify which job roles can use specific commands.
-- The key (e.g., ['police']) represents the name of the command, and each job can be set to true to enable its respective functionalities.
Config.Jobs = {
    ['police'] = {
        police = true, -- Enable command functionalities for the 'police' job.
        sheriff = true -- Enable command functionalities for the 'sheriff' job.
    },
    ['ambulance'] = {
        ambulance = true -- Enable command functionalities for the 'ambulance' job.
    }
}

-- [License Settings]
-- Configuration for licenses that are required to use specific commands.
-- The key (e.g., ['youtube']) represents the command name. 
-- Inside each license, you can insert any accepted license type.
-- This configuration is used to check if a player has the necessary license to use a command.
Config.Licenses = {
    ['youtube'] = {
        -- License requirement for the YouTube command.
        ['discord:discordId'] = true
    },
    ['twitch'] = {
        -- License requirement for the Twitch command.
        ['discord:discordId'] = true 
    }
}

-- [Chat Cleaning Settings]
-- Configuration that allows players to clear their own chat messages.
Config.allowPlayerToCleanChat = true

-- [Staff Group Settings]
-- This configuration defines the groups that have access to specific restricted commands (e.g., staff, staffo, clearall).
-- Only members of these groups will be allowed to use these commands.
Config.Staff = {
    'owner',
    'admin',
    'mod'
}

-- [Owner Group Settings]
-- This configuration defines the groups recognized as owners in chat.
-- Only players belonging to one of these groups will be identified as owners.
Config.OwnerGroups = {
    'owner'
}

-- [Message History Length]
-- Defines the maximum length for message history.
-- It is advisable not to set this value too high to avoid significant performance slowdowns.
Config.MaxHistoryLength = 100

-- [UI Color]
-- This is where you define the primary color for the user interface.
-- The color should be in HEX format, like "#8C80F0".
-- You can use any valid HEX color code, and there are online tools to help you find one.
Config.Color = '#8C80F0'

-- [Message Styles]
-- Configuration for the appearance of different messages.
-- Each message types (e.g., ['anon'], ['twitter'], ['staff']) can have its own visual properties.
-- You can define various keys to represent different styles. 
-- It is recommended to change only the background property to avoid disrupting the overall message style.
Config.MessageStyles = {
    ['ooc'] = {
        background = 'linear-gradient(90deg, rgba(107, 107, 107, 0.35) 7%, transparent 110%)'
    },
    ['globalme'] = {
        background = 'linear-gradient(90deg, rgba(255, 181, 95, 0.35) 7%, transparent 110%)'
    },
    ['anon'] = {
        background = 'linear-gradient(90deg, rgba(0, 0, 0, 0.65) 7%, transparent 110%)'
    },
    ['twitter'] = {
        background = 'linear-gradient(90deg, rgba(95, 178, 255, 0.35) 7%, transparent 110%)'
    },
    ['youtube'] = {
        background = 'linear-gradient(90deg, rgba(254, 1, 0, 0.35) 7%, transparent 110%)'
    },
    ['twitch'] = {
        background = 'linear-gradient(90deg, rgba(100, 65, 165, 0.35) 7%, transparent 110%)'
    },
    ['advert'] = {
        background = 'linear-gradient(90deg, rgba(255, 229, 95, 0.35) 7%, transparent 110%)'
    },
    ['police'] = {
        background = 'linear-gradient(90deg, rgba(0, 0, 139, 0.35) 7%, transparent 110%)'
    },
    ['ambulance'] = {
        background = 'linear-gradient(90deg, rgba(139, 0, 0, 0.35) 7%, transparent 110%)'
    },
    ['staff'] = {
        background = 'linear-gradient(90deg, rgba(144, 238, 144, 0.35) 7%, transparent 110%)'
    },
    ['staffo'] = {
        background = 'linear-gradient(90deg, rgba(255, 140, 0, 0.35) 7%, transparent 110%)'
    }
}

-- [Tag Styles]
-- Configuration for the appearance of different tags used in messages.
-- Each tag (e.g., ['ooc'], ['twitter'], ['staff']) can have its own visual properties.
-- You can define various keys to represent different styles.
-- It is recommended to edit only the properties already present to maintain consistent design.
Config.TagStyles = {
    ['ooc'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(107, 107, 107, 0.43)',
        background = 'linear-gradient(18deg, rgba(107, 107, 107, 1) 0%, transparent 100%)',
        borderColor = '#6B6B6B'
    },
    ['globalme'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(255, 181, 95, 0.43)',
        background = 'linear-gradient(18deg, rgba(255, 181, 95, 1) 0%, transparent 100%)',
        borderColor = '#FFB55F'
    },
    ['anon'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(0, 0, 0, 0.43)',
        background = 'linear-gradient(18deg, rgba(0, 0, 0, 1) 0%, transparent 100%)',
        borderColor = '#333'
    },
    ['twitter'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(95, 178, 255, 0.43)',
        background = 'linear-gradient(18deg, rgba(95, 178, 255, 1) 0%, transparent 100%)',
        borderColor = '#5FB2FF'
    },
    ['youtube'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(255, 0, 0, 0.43)',
        background = 'linear-gradient(18deg, rgba(254, 1, 0, 1) 0%, transparent 100%)',
        borderColor = '#FF0000'
    },
    ['twitch'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(100, 65, 165, 0.43)',
        background = 'linear-gradient(18deg, rgba(100, 65, 165, 1) 0%, transparent 100%)',
        borderColor = '#6441A5'
    },
    ['advert'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(255, 229, 95, 0.43)',
        background = 'linear-gradient(18deg, rgba(255, 229, 95, 1) 0%, transparent 100%)',
        borderColor = '#FFE55F'
    },
    ['police'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(0, 0, 139, 0.43)',
        background = 'linear-gradient(18deg, rgba(0, 0, 139, 1) 0%, transparent 100%)',
        borderColor = '#00008B'
    },
    ['ambulance'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(139, 0, 0, 0.43)',
        background = 'linear-gradient(18deg, rgba(139, 0, 0, 1) 0%, transparent 100%)',
        borderColor = '#8B0000'
    },
    ['staff'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(144, 238, 144, 0.43)',
        background = 'linear-gradient(18deg, rgba(144, 238, 144, 1) 0%, transparent 100%)',
        borderColor = '#90EE90'
    },
    ['staffo'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(255, 140, 0, 0.43)',
        background = 'linear-gradient(18deg, rgba(255, 140, 0, 1) 0%, transparent 100%)',
        borderColor = '#FF8C00'
    },
    ['owner'] = {
        boxShadow = '0px 0px 0.729vw 0px rgba(140, 128, 240, 0.43)',
        background = 'linear-gradient(18deg, rgba(140, 128, 240, 1) 0%, transparent 100%)',
        borderColor = '#8C80F0'
    }
}

-- [Logs Settings]
-- This setting enables or disables logging of chat events to a Discord webhook.
-- When enabled, messages will be sent to the specified webhook URL.
-- You can set up a Discord webhook to log all chat messages events.
-- Ensure that the provided webhook URL is valid and properly set up in your Discord server.
Config.LogsSettings = {
    enable = false, -- Whether logging is enabled.
    webhook = '' -- The webhook URL for Discord logs.
}
```

## Step 3: Disable Default Chat

**Remember to add this convar in you `server.cfg`and to delete the default `chat` resource**

```bash
setr resources_useSystemChat false
```

{% hint style="danger" %}
**If you forget to set this convar, you will see two chat windows in-game: the default FiveM chat and our chat. Make sure to include this convar to avoid any conflicts.**
{% endhint %}

## Optional: Setting Up Exports

```
exports['crystal-chat']:addMessage(source, sender, content, tags, shouldSave, targets)
```

**Params:**

* source: `number`
  * Player source
* sender: `string`
  * The name of the message sender
* content: `string`
  * The content of the message
* tags: `table (array)`
  * tag `string | number`
* shouldSave: `boolean`
  * Determines if the message is saved in history and logged
* targets: `number | table (array)`&#x20;
  * Specifies the recipient(s). Leave empty for no specific targets

## Optional: Setting Up Framework

**This resource supports various native frameworks, ensuring seamless integration. If you are using a custom framework or one that is not directly supported, you can adapt the script by modifying the files located in:**

```bash
bridge/framework/custom/
  ├── client.lua
  └── server.lua
```

**By editing these files, you can ensure compatibility with any framework, allowing for a customized and smooth experience.**

## Usage Example

```lua
-- Server Side Only
-- exports['crystal-chat']:addMessage(source, sender, content, tags, shouldSave, targets)

exports['crystal-chat']:addMessage(
    0, -- Server source
    'SERVER', -- Sender name
    'SERVER WILL RESTART SOON!', -- Message content
    {
        'SERVER', -- First tag defines style
        os.date('%H:%M')
    },
    false
)

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.crystxlz.com/resources/chat.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
