> For the complete documentation index, see [llms.txt](https://pepper-scripts.gitbook.io/pepper-scripts-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pepper-scripts.gitbook.io/pepper-scripts-docs/tools-ui/pepper-chat.md).

# Pepper Chat

Free chat with tabs for All, OOC and Staff – with tools your staff uses right in the chat window.

{% hint style="success" %}
✅ **Get Pepper Chat:** <https://shop.pepperscripts.de/package/7729477>
{% endhint %}

{% hint style="info" %}
🧪 **Tested on our dev server:** Of course we test all scripts continuously on our own dev server “Pepper Scripts”.
{% endhint %}

Free and open source: <https://github.com/PepperScripts/pepper\\_chat>

## Overview

Pepper Chat replaces the default chat. Your players switch between the tabs All, OOC and Staff, and your staff mutes with a right-click, deletes messages and sends announcements right in the chat window – without typing commands. Spam protection and the word filter check every message on the server, mutes are stored in the database and survive a restart, and everything ends up in the daily log.

### Features

* Tabs: **All**, **OOC** and **Staff** (the staff tab is visible to staff only)
* Staff tools right in the chat window, no commands needed:
  * Right-click a message: mute the player (10 min, 1 h, 24 h, permanent) or delete the message
  * Buttons: announcement to everyone, slow mode, list of muted players, clear chat
* Announcements appear in chat and as a banner at the top of the screen
* Staff badge in front of the name (Admin, Mod), colours and labels set in the config
* Spam protection: cooldown, duplicate check and flood mute; word filter that censors or blocks
* Mutes are stored in the database and survive a restart
* Log to a daily file and, if you want, to a Discord webhook
* Command suggestions while typing, input history (arrow keys), character counter
* Replaces the default chat (`provide 'chat'`): `chat:addMessage`, `chat:addSuggestion`, templates and `exports.chat` keep working
* English and German included

## Requirements

| Dependency                                      | Required/optional | What for                                                                                   | Link                                                             |
| ----------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| FiveM server (`fx_version 'cerulean'`, Lua 5.4) | required          | Runs the resource                                                                          | <https://docs.fivem.net/docs/server-manual/setting-up-a-server/> |
| oxmysql                                         | required          | Table `pepper_chat_mutes` for mutes                                                        | <https://github.com/overextended/oxmysql>                        |
| MySQL/MariaDB database                          | required          | Accessed through oxmysql; the script creates the table itself                              | –                                                                |
| ESX Legacy, QBCore or Qbox                      | optional          | Staff roles from the group (ESX) or permissions (QBCore/Qbox); without a framework via ACE | –                                                                |
| OneSync                                         | not needed        | –                                                                                          | –                                                                |

## Installation

1. Put the `pepper_chat` folder into your `resources` folder. **Do not rename the folder** – exports and NUI calls depend on the name `pepper_chat`.
2. In your `server.cfg`, **remove** `ensure chat` (the default chat) and start Pepper Chat after `oxmysql`:

   ```
   ensure oxmysql
   # ensure chat   ← remove
   ensure pepper_chat
   ```
3. Restart the server. The table `pepper_chat_mutes` is created automatically on first start. If you want to create it by hand, import `install/pepper_chat.sql` into your database.
4. Set `Config.Locale` and your staff groups (`Config.Staff`) in `config.lua`.

### First test

1. In game press **T** – the chat window with the tabs opens. Type a message and send it with **Enter**.
2. **Tab** switches the tab (when no suggestions are open), `/ooc Hello` writes to the OOC channel.
3. As staff: right-click a message – the menu to mute and delete appears, plus the **Staff** tab and the tool buttons.
4. Type `say Test` in the server console – the line appears in everyone's chat.
5. Check that a file `chat-YYYY-MM-DD.log` was created in the `logs/` folder.

## Configuration

| File                                 | Controls                                                                                                 |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| `config.lua`                         | Language, key, channels, display, look, banner, staff roles, command names, shown name (sent to players) |
| `config_server.lua`                  | Log and webhook, spam protection, word filter (server only, never sent to players)                       |
| `locales/de.json`, `locales/en.json` | All texts in the chat and the UI                                                                         |
| `html/style.css`                     | Look of the chat window                                                                                  |

### Basics and display

| Option                     | Default                                      | Description                                                          |
| -------------------------- | -------------------------------------------- | -------------------------------------------------------------------- |
| `Config.Locale`            | `'en'`                                       | Language `'de'` or `'en'`                                            |
| `Config.OpenKey`           | `'t'`                                        | Key to open; players change it under Settings → Key Bindings → FiveM |
| `Config.Channels`          | `{ global = true, ooc = true, team = true }` | Channels on/off                                                      |
| `Config.DefaultChannel`    | `'global'`                                   | Which channel the "All" tab writes to                                |
| `Config.ShowIds`           | `true`                                       | Server ID behind the name                                            |
| `Config.ShowTime`          | `true`                                       | Time in front of the message                                         |
| `Config.MaxLength`         | `200`                                        | Max message length                                                   |
| `Config.MaxMessages`       | `100`                                        | Messages kept in the history                                         |
| `Config.FadeAfter`         | `12`                                         | Seconds until the chat fades out, `0` = never                        |
| `Config.JoinLeaveMessages` | `false`                                      | "joined / left the server" in chat                                   |

### Look and banner

```lua
Config.UI = { left = 1.2, top = 4.0, width = 31, height = 17, scale = 1.0, accent = '#E5484D' }
Config.AnnouncementBanner = { enabled = true, duration = 8 }
```

| Option                       | Default                        | Description                                                   |
| ---------------------------- | ------------------------------ | ------------------------------------------------------------- |
| `Config.UI.left` / `top`     | `1.2` / `4.0`                  | Position in percent of the screen                             |
| `Config.UI.width` / `height` | `31` / `17`                    | Size in text-line units                                       |
| `Config.UI.scale`            | `1.0`                          | Overall size, `1.0` = normal                                  |
| `Config.UI.accent`           | `'#E5484D'`                    | Accent colour (active tab, buttons)                           |
| `Config.AnnouncementBanner`  | `enabled = true, duration = 8` | Announcement also as a banner at the top, duration in seconds |

### Staff roles

```lua
Config.Staff = {
    { key = 'admin', label = 'Admin', color = '#E5484D', groups = { 'superadmin', 'admin', 'god' } },
    { key = 'mod', label = 'Mod', color = '#4C9AFF', groups = { 'mod', 'moderator', 'support' } },
}
```

The first matching role wins (top = higher). Checked are the ACE permission `pepperchat.<key>`, the ESX group (`getGroup`), QBCore permissions (`HasPermission`) and ACE groups of the same name (Qbox). `label` and `color` form the badge in front of the name.

| Option                 | Default                        | Description                                                                  |
| ---------------------- | ------------------------------ | ---------------------------------------------------------------------------- |
| `Config.SlowModeSteps` | `{ 0, 5, 10, 30, 60 }`         | Choices in the staff menu for slow mode (seconds)                            |
| `Config.MuteSteps`     | `{ 10, 60, 1440, 0 }`          | Choices in the right-click menu (minutes, `0` = permanent)                   |
| `Config.Commands`      | see "Commands and permissions" | Command names without the slash                                              |
| `Config.GetName`       | `GetPlayerName(source)`        | Which name the chat shows – query your framework here for the character name |

### Log, spam protection and word filter (`config_server.lua`)

| Option                                         | Default    | Description                                                     |
| ---------------------------------------------- | ---------- | --------------------------------------------------------------- |
| `ServerConfig.Log.file`                        | `true`     | Daily file `logs/chat-YYYY-MM-DD.log` in the resource folder    |
| `ServerConfig.Log.webhook`                     | `''`       | Discord webhook URL, `''` = off (`@` mentions are defused)      |
| `ServerConfig.Spam.cooldown`                   | `1000`     | Milliseconds between two messages                               |
| `ServerConfig.Spam.duplicateWindow`            | `10`       | Same message again only after this many seconds                 |
| `ServerConfig.Spam.floodCount` / `floodWindow` | `6` / `10` | This many messages in this many seconds count as flood          |
| `ServerConfig.Spam.floodMute`                  | `60`       | Then muted for this many seconds                                |
| `ServerConfig.Filter.mode`                     | `'censor'` | `'censor'` (asterisks), `'block'` (drop the message) or `'off'` |
| `ServerConfig.Filter.words`                    | empty      | List of filtered words (case-insensitive)                       |

Spam protection and slow mode do not apply to staff, the word filter does not apply to the staff channel.

## For developers

```lua
-- client
exports.pepper_chat:setVisible(false)                       -- hide the chat, e.g. for a cutscene
TriggerEvent('chat:addMessage', { color = { 255, 196, 107 }, args = { 'Bank', 'You received $500.' } })
-- server
TriggerClientEvent('chat:addMessage', source, { args = { 'Server', 'Welcome!' } })
exports.pepper_chat:addMessage(-1, { args = { 'Server', 'Restart at 6 pm.' } })
```

Like with the default chat, other resources on the server can catch the `chatMessage` event (`CancelEvent()`) or change and cancel messages with `registerMessageHook`. Colour codes `^0`–`^9` work in messages from scripts; they are removed from player messages.

## Commands and permissions

| Command                             | Who                 | What it does                             |
| ----------------------------------- | ------------------- | ---------------------------------------- |
| `/ooc [text]`                       | everyone            | Message to the OOC channel               |
| `/team [text]`                      | staff               | Message to the staff chat                |
| `/announce [text]`                  | staff               | Announcement to everyone (chat + banner) |
| `/chatclear`                        | staff               | Clears the chat for everyone             |
| `/chatmute [id] [minutes] [reason]` | staff               | Mutes a player, `0` = permanent          |
| `/chatunmute [id]`                  | staff               | Unmutes a player (player must be online) |
| `/chatslow [seconds]`               | staff               | Slow mode, `0` = off (at most 600)       |
| `say [text]`                        | server console only | Line as "Console" in the chat            |

All names can be changed in `Config.Commands`. The staff commands also work from the server console.

**Who is staff?** The first matching role in `Config.Staff`:

* **ESX:** the player's group (`admin`, `superadmin`, `mod` …)
* **QBCore / Qbox:** the player's permission (`god`, `admin`, `mod`)
* **No framework:** add to your `server.cfg`

  ```
  add_ace group.admin pepperchat.admin allow
  add_ace group.moderator pepperchat.mod allow
  ```

**Keys in the chat window:** **T** open (changeable), **Enter** send, **Esc** close, **Tab** take a suggestion or switch tabs, **Arrow up/down** input history or suggestions, **Page up/down** scroll the history, right-click (staff only) menu for message and player.

## Exports and events

| Side   | Name                                                                                                                        | Effect                                                    |
| ------ | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| Client | `exports.pepper_chat:setVisible(bool)`                                                                                      | Show/hide the chat                                        |
| Client | `exports.pepper_chat:addMessage(msg)` / `addSuggestion(name, help, params)`                                                 | Like the default chat                                     |
| Client | Events `chat:addMessage`, `chatMessage`, `chat:addSuggestion(s)`, `chat:removeSuggestion`, `chat:addTemplate`, `chat:clear` | Compatible with the default chat                          |
| Server | `exports.pepper_chat:addMessage(target, msg)`                                                                               | Message to one player or `-1` = everyone                  |
| Server | `exports.pepper_chat:registerMessageHook(fn)`                                                                               | Change or cancel player messages before they are sent out |
| Server | Event `chatMessage(source, name, text)`                                                                                     | Read along, cancel with `CancelEvent()`                   |

## FAQ

### The chat opens twice or not at all – what now?

Usually the default chat or another chat is still running. Remove `ensure chat` (and other chat resources) from your `server.cfg`. Pepper Chat registers as the replacement via `provide 'chat'`; only one may run.

### Does my other script that depends on `chat` keep working?

Yes. Through `provide 'chat'` dependencies on `chat` are met, and the events `chat:addMessage`, `chat:addSuggestion`, `chatMessage` and templates (`chat:addTemplate`) are understood.

### Do I need a database?

Yes, for the mutes via oxmysql. The script creates the table `pepper_chat_mutes` on start; by hand you can use `install/pepper_chat.sql`.

### I am an admin but do not see the staff tab?

Check that your group (ESX) or permission (QBCore/Qbox) is listed in `groups` of a role in `Config.Staff`, or without a framework set `add_ace group.admin pepperchat.admin allow`. The role is cached for up to 30 seconds – reconnect after a change.

### How do I show the character name instead of the FiveM name?

Change `Config.GetName` in `config.lua`: the function runs on the server and receives the `source`. Query your framework there and return the name (at most 40 characters are shown).

### How do I change colours and position?

Accent colour, position, size and scale are in `Config.UI`, the staff badge colours in `Config.Staff` (`color`). For deeper changes edit `html/style.css`.

### How do I change the texts?

All texts are in `locales/de.json` and `locales/en.json`. `Config.Locale` picks the language.

### Do mutes survive a restart?

Yes. They are stored in the database, tied to the player's Rockstar license. Expired ones are deleted on start. If a player has no license identifier, the mute only lasts for the current session.

### How do I unmute a player who is offline?

Through the staff menu in the chat: the list of muted players shows all active entries, you lift them there. `/chatunmute [id]` only works for players who are online.

### How do I set up the Discord webhook?

Put the webhook URL into `config_server.lua` at `ServerConfig.Log.webhook`. Lines are collected and sent in batches about every 5 seconds. The file stays on the server and is never sent to players.

### Why do player messages arrive without colour?

Colour codes `^0`–`^9` and control characters are removed from player messages on the server. In messages from your scripts (`chat:addMessage`) they still work.

### A player types a command that does not exist – does it end up in the chat?

No. Unknown commands are not sent to everyone as a message; the player gets a hint.

### How do I update Pepper Chat?

Replace the folder and back up `config.lua`, `config_server.lua` and changed language files first. The database stays. Changes are listed in the `CHANGELOG.md` in the resource folder.

## Support

Open a ticket in our [Discord](https://discord.gg/6NaFJWKDYu) (category “Script Support”) and link your purchase with `/verify` first.

## Changelog

Current version **1.0.0** (first version). All changes are listed in the `CHANGELOG.md` in the resource folder.
