Documentation

Pepper Chat

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

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

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

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

-- 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

Questions or bugs? Open a ticket in our Discord: https://discord.gg/6NaFJWKDYu – link your purchase with /verify first. The source code is on GitHub: https://github.com/PepperScripts/pepper_chat

Permanently tested on the Pepper Scripts dev server.

Changelog

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


Found a mistake? Report it on Discord.