> For the complete documentation index, see [llms.txt](https://oph3zdev.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oph3zdev.gitbook.io/docs/free/phone/configuration.md).

# Configuration

Configuration of this resource

### Opening the phone

```lua
Config.ItemName  = 'phone'
Config.RequireItem = false
```

**`Config.ItemName`**

The inventory item that opens the phone. Must match the item name you registered in your inventory resource.

**`Config.RequireItem`**

`false` — the phone always opens, nobody needs an item. `true` — the phone only opens while the player carries `Config.ItemName`. Losing the item doesn't touch their data; contacts, messages and photos are all still there when they get one back.

{% hint style="warning" %}
With `RequireItem = true`, dont forget to add the item to your inventory!
{% endhint %}

***

### Numbers, email and language

```lua
Config.PhoneNumberPrefix = '555' -- 555 + 4 digits -> displayed as "555-0142"
Config.DefaultLocale = 'en' -- en, tr
Config.MailDomain = 'mail.com'
```

**`Config.PhoneNumberPrefix`**

The start of every phone number. Four random digits are added after it, so `555` gives `555-0142`.

Use a **3-character prefix**. The dash formatting only applies to 7-digit numbers — a longer or shorter prefix still works, it just shows as unbroken digits.

**`Config.DefaultLocale`**

Fallback language, used before a player has picked their own. Valid values are the file names in `locales/` — `en` and `tr` ship with the phone. Set this to the same value as `DefaultSettings.language` below.

**`Config.MailDomain`**

Domain for Mail addresses. Built from the character's name: `Oph3Z Test` becomes `oph3z.test@mail.com`. Duplicates get a number (`oph3z.test2@mail.com`).

{% hint style="warning" %}
Numbers and email addresses are generated once, when the character first loads in. Changing these later only affects new characters.
{% endhint %}

***

### Twexa verification badges

```lua
Config.XVerifyCommand = 'xverify' -- /xverify <@username> [gold|blue]
```

**`Config.XVerifyCommand`**

Name of the admin command that hands out badges in the Twexa app. Requires the `group.admin` ace, and works from the server console.

* `/xverify @oph3z gold` — gold badge
* `/xverify @oph3z blue` — back to the normal blue badge
* Tier left out defaults to `gold`

Every Twexa account already has a blue check, so this really switches between blue and gold. Updates live if the player is online.

***

### Billing

```lua
Config.BillingScript = 'qbox' -- 'esx_billing' | 'qb' | 'codem-billing' | 'qbox'
Config.BillingTax = 0
Config.QBBanking = true
Config.QBCreateJobAccount = false
```

The phone doesn't create bills — your billing resource does. The Wallet app is where players view and pay them.

{% hint style="info" %}
Billing is the only feature that uses your database. Set `Config.MySQL` (see Installation) or the Wallet shows no bills.
{% endhint %}

**`Config.BillingScript`**

Which billing resource to read invoices from:

| Value           | Table            | Society paid through        |
| --------------- | ---------------- | --------------------------- |
| `esx_billing`   | `billing`        | esx\_billing                |
| `qb`            | `phone_invoices` | qb-banking or qb-management |
| `qbox`          | -                | Renewed-Banking             |
| `codem-billing` | `codem_billing`  | codem-billing               |

Paying takes the money from the player's bank, credits the society, and deletes the invoice.

If the table doesn't exist the Wallet just shows an empty list. Turn on `Config.Debug` to get a console warning naming the missing table.

**`Config.BillingTax`**

Informational tax % shown on a bill when the biller doesn't send one.

{% hint style="warning" %}
Not read anywhere in the script right now, so it has no effect. Leave at `0`.
{% endhint %}

**`Config.QBBanking`**

Only used when `BillingScript = 'qb'`. `true` pays the society through qb-banking, `false` through qb-management (legacy). Pick the one your server runs — if it's wrong the player is still charged but the society never gets the money.

**`Config.QBCreateJobAccount`**

Only used when `BillingScript = 'qb'` and `QBBanking = true`. If the society's bank account doesn't exist yet, `true` creates it automatically instead of losing the payment.

***

### ShareDrop

```lua
Config.Sharedrop = {
    Range = 8.0,
    MaxPhotos = 20,
    RequirePhone = false,
}
```

**`Range`**

Metres — how close another player has to be to show up in the ShareDrop list.

**`MaxPhotos`**

Maximum photos or videos in a single ShareDrop. Stops someone sending their entire gallery at once.

**`RequirePhone`**

`false` — the receiver just needs ShareDrop enabled in their Control Center. `true` — they must also have their phone open.

***

### Clock

```lua
Config.Clock = {
    Range = 12.0,
    Volume = 0.5,
    RingSeconds = 30,
}
```

Alarms and timers play as 3D sound, so nearby players hear them too.

**`Range`**

Metres the alarm or timer sound carries.

**`Volume`**

Volume from `0.0` to `1.0`.

**`RingSeconds`**

How long a ringing alarm or finished timer keeps going before stopping on its own. Prevents a sound ringing forever if the player disconnects.

{% hint style="info" %}
The sound file is `web/public/audio/alarm.mp3`. Replace it to change the tone. (You have to "build" so it works in game!)
{% endhint %}

***

### Default phone settings

```lua
Config.DefaultSettings = {
    wallpaper = 'blackTitanium',
    brightness = 100,
    volume = 70,
    sharedrop = false,
    airplane = false,
    scale = 85,
    notifSound = true,
    notifMaster = true,
    language = 'en',
}
```

{% hint style="warning" %}
Written once, when a character's data file is created. Editing this later does **not** change anything for existing players — only new characters get the new defaults.
{% endhint %}

**`wallpaper`** — `blackTitanium`, `desertTitanium`, `naturalTitanium`, `whiteTitanium`, or a direct image URL. Add more by dropping images into `web/src/assets/wallpapers/` and rebuilding; the key is the file name without its extension.

**`brightness`** — screen brightness, `20`–`100`.

**`volume`** — media volume, `0`–`100`. Drives the Music app and the Control Center slider.

`sharedrop` — whether ShareDrop receiving starts enabled.

**`airplane`** — whether airplane mode starts enabled. Unreachable, can't call. Leave at `false`.

**`scale`** — phone size on screen, `75`–`100`.

**`notifSound`** — play a sound on new notifications.

**`notifMaster`** — master switch. Off silences all notifications, overriding `notifSound`.

**`language`** — starting language. Match `Config.DefaultLocale`.

***

### Apps and the home screen

```lua
Config.Apps = {
    { id = 'call',    label = 'Phone',    place = 'dock' },
    { id = 'maps',    label = 'Maps',     place = 'grid' },
    {
        id = 'music',
        label = 'Music',
        place = 'grid',
        store = true,
        description = 'Millions of songs, all in one place. ...',
    },
}
```

Which apps exist, what they're called, and where they start. Apps are placed in the order you list them.

**`id`**

Must match a built-in app:

`call`, `message`, `camera`, `photos`, `maps`, `clock`, `mail`, `wallet`, `settings`, `calculator`, `appstore`, `twexa`, `marketplace`, `music`

Removing an entry removes that app for everyone, including players who already had it.

**`label`**

Name shown under the icon and in the App Store. Free text — rename anything to fit your server.

**`place`**

* `'dock'` — the bar at the bottom. Holds **4 apps max**; extras move to the grid.
* `'grid'` — the home screen pages, 24 icons per page. New pages are created automatically.
* `'hidden'` — installed and working, but not on the home screen.

**`store`**

`true` lists the app in the App Store instead of placing it on the home screen. Players choose whether to install it, and these are the only apps they're allowed to delete.

**`description`**

Text on the app's App Store page. Only used with `store = true`. You can also add `headerImage` and `swiperItems` for a banner and screenshots.

**`enabled`**

`false` disables the app without deleting the line.

{% hint style="info" %}
Each player's home screen layout is saved to their profile, since they can move icons and make folders. A newly added app lands on their first page with free space — `place = 'dock'` only applies to layouts created from scratch.
{% endhint %}

***

### Calls

```lua
Config.RingTimeout = 30
Config.MaxRecents  = 50
Config.CallSpeakerRange = 6.0
Config.RingtoneUrl = 'https://cfx-nui-xsound/html/sounds/ringtone.mp3'

Config.Ringtones = {
    { id = 'default', name = 'Default', file = 'ringtone.mp3' },
}
```

**`Config.RingTimeout`**

Seconds an unanswered call rings before it's logged as missed.

**`Config.MaxRecents`**

How many call history entries to keep. Older ones are dropped.

**`Config.CallSpeakerRange`**

Metres nearby players can hear a call on speaker.

Speaker is a real speakerphone: everyone in range joins the call's voice channel, hears both sides, and can talk into it. The listener list updates as people walk in and out of range.

**`Config.RingtoneUrl`**

Fallback ringtone for players who haven't picked one in Settings > Ringtones. Played in 3D so nearby players hear it. The default points inside xsound, which you already have installed.

**`Config.Ringtones`**

Ringtones offered in Settings > Ringtones. Each needs an `id`, a `name`, and either:

* `file` — an audio file in `web/public/audio/`. Drop in `mytone.mp3`, add `{ id = 'mytone', name = 'My Tone', file = 'mytone.mp3' }`, rebuild.
* `url` — a direct link to an audio file.

Players can also add their own from a URL in the app, private to them.

***

### Photo and video uploads

```lua
ServerConfig.Camera = {
    provider = 'fivemanage', -- 'discord' or 'fivemanage'

    discord = {
        webhook = '',
    },

    fivemanage = {
        apiKey = '',
        url = 'https://api.fivemanage.com/api/v3/file',
    }
}
```

Where all the phone's media is stored. Not just the camera app, also voice messages in Messages, and profile pictures in Twexa. None of those work until this is filled in.

**`provider`**

`'fivemanage'` or `'discord'`. Fill in the matching block below.

**`discord.webhook`**

A Discord webhook URL. Free and quick, but Discord has file size limits and links break if the channel or webhook is deleted.

**`fivemanage.apiKey`**

An API key from [fivemanage.com](https://fivemanage.com). Handles larger files and gives you a dashboard.

**`fivemanage.url`**

The upload endpoint. Leave as is.

{% hint style="info" %}
These credentials are used by the phone's interface, so they reach the client. Use a key created only for this resource and scoped to uploads.
{% endhint %}

***

### GIFs

```lua
ServerConfig.Gif = {
    apiKey = '',
}
```

`ServerConfig.Gif.apiKey`

A GIPHY API key for the GIF picker in Messages. Get a free one at [developers.giphy.com](https://developers.giphy.com) — register an app and choose the API option, not the SDK.
