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

# sh-telegram: RedM Telegraph & Parcel Office System

> sh-telegram adds a period-accurate telegraph office to RedM. Players send telegrams and parcels to unique character IDs with optional mishap events.

The sh-telegram resource brings a fully period-accurate communication system to your RedM roleplay server. Players visit staffed telegraph office locations, pay a clerk, and send written telegrams or physical item parcels to any other character using a unique six-character identifier. The system ships with a western-styled Vue 3 NUI inbox, configurable mishap events for parcels, and Discord webhook logging for every transaction.

## Framework Support

sh-telegram supports both **VORP** and **RSG** frameworks. Set the framework in your server-side `config.lua` before starting the resource:

```lua config.lua (server) theme={null}
Config.Framework = 'vorp'  -- 'vorp' or 'rsg'
```

## Localization

sh-telegram ships with English, Spanish, and German locale files. Set the active locale in the config:

```lua config.lua (server) theme={null}
Config.Locale = 'en'  -- 'en', 'es', or 'de'
```

Community-contributed translations can be added by duplicating an existing locale file and adjusting the string values.

## Telegram IDs

Every character receives a unique Telegram ID the first time they interact with a telegraph office. You can choose from three ID formats to match your server's theme:

<Tabs>
  <Tab title="numeric">
    A six-digit numeric code assigned randomly, for example `034921`. Best for servers that want a neutral, registry-style identifier.

    ```lua config.lua (server) theme={null}
    Config.TelegramIdMode = 'numeric'
    ```
  </Tab>

  <Tab title="town">
    A two-letter town prefix followed by four digits, for example `VA3921`, where the prefix is derived from the town nearest to the character at the moment of registration. Best for servers that want IDs to carry a sense of place.

    ```lua config.lua (server) theme={null}
    Config.TelegramIdMode = 'town'
    ```
  </Tab>

  <Tab title="custom">
    A fixed prefix string you define, followed by digits, for example `SPAZ-3921`. Best for servers with a branded or fictional setting.

    ```lua config.lua (server) theme={null}
    Config.TelegramIdMode = 'custom'
    Config.CustomPrefix   = 'SPAZ-'
    ```
  </Tab>
</Tabs>

## Features

<Accordion title="Send Telegrams">
  Players compose a text message at the telegraph office counter and pay a base fee to dispatch it. An optional anonymous send mode obscures the sender's identity for an additional surcharge. Sent telegrams are stored per-character in the database and appear in the recipient's NUI inbox.
</Accordion>

<Accordion title="Inbox UI">
  The NUI inbox uses Vue 3 with western-themed styling. Players can browse their message list, open individual telegrams, reply directly from the view pane, and delete messages they no longer need. An unread indicator persists on the HUD when new telegrams are waiting, and you can position the indicator anywhere on screen from the client config.
</Accordion>

<Accordion title="Parcel System">
  Players can bundle physical items into a parcel and send it to another character's Telegram ID. You control the base parcel fee, the maximum number of distinct item types per parcel, and optional per-item surcharges. The recipient collects the parcel from the telegraph office.
</Accordion>

<Accordion title="Parcel Mishaps">
  Enable mishap events to simulate the unpredictability of frontier mail. When a parcel triggers a mishap, one of three outcomes can apply: the parcel arrives `damaged` (cosmetic label only), the recipient receives only part of the contents (`lost_some`), or the entire parcel is lost (`lost_all`). You configure which outcome is active, the overall chance percentage, and the loss percentage range.
</Accordion>

<Accordion title="Return to Sender">
  Players can manually request that an uncollected parcel be returned to them for an optional fee. You can also enable automatic returns after a configurable number of unclaimed days so that inventory items are never permanently stuck in transit.
</Accordion>

<Accordion title="Contacts List">
  Players save frequently contacted characters with a friendly display name and can mark favorites for quick access when composing a new telegram or parcel.
</Accordion>

<Accordion title="NPC Clerks & Blips">
  Define telegraph office locations in the client config. Each location spawns a period-appropriate NPC clerk and a world blip so players can find offices on the map. You can add as many office locations as your map warrants.
</Accordion>

## Configuration

### Server Config

The following block covers every server-side option. Copy it into your `config.lua` and adjust values to match your server's economy and feature preferences:

```lua config.lua (server) theme={null}
Config.Framework = 'vorp'   -- 'vorp' or 'rsg'
Config.Locale    = 'en'     -- 'en', 'es', or 'de'

Config.UseSH_Identity = false  -- Require sh-identity ID card to use the office

Config.Cooldown = 60  -- Seconds between sends per character (nil = no cooldown)

Config.Command = {
    enabled     = true,
    commandname = 'telegram',   -- /telegram opens the telegraph UI
    permission  = nil           -- e.g. 'telegram.use' to gate with ACE
}

-- Telegrams
Config.TelegramFee               = 2.5   -- Base fee to send a telegram
Config.TelegramAnonymousExtraFee = 5.0   -- Extra fee for anonymous send
Config.TelegramIdMode            = 'town' -- 'numeric', 'town', or 'custom'
Config.CustomPrefix              = 'SPAZ-' -- Used when IdMode = 'custom'

-- Parcels
Config.EnableParcels  = true
Config.ParcelBaseFee  = 5.0
Config.ParcelMaxItems = 4        -- Max distinct item types per parcel
Config.ParcelItemFees = {
    -- ['goldbar'] = 10.0,       -- optional per-item surcharge
}

Config.ParcelMishaps = {
    enabled       = true,
    chancePercent = 15,          -- % chance a mishap occurs on each send
    types = {
        lost_some = false,       -- some items/quantities lost
        lost_all  = false,       -- whole parcel lost
        damaged   = true,        -- cosmetic 'damaged' label added
    },
    lostSomeMinPercent = 20,     -- min % of quantity lost on lost_some
    lostSomeMaxPercent = 60,     -- max % of quantity lost on lost_some
    showDamagedSuffix  = true,   -- append '(Damaged)' to labels
    notifyReceiver     = true,
    notifySender       = false,
}

Config.ParcelReturn = {
    enabled              = true,
    manualReturnFee      = 0.0,  -- fee to return an uncollected parcel (0 = free)
    notifySenderOnReturn = true,
    autoReturn = {
        enabled              = false,
        daysUnclaimed        = 5,   -- days before auto-return triggers
        checkIntervalMinutes = 30,  -- how often the server scans for old parcels
    },
}

Config.Discord = {
    enabled         = true,
    webhook         = '',                                          -- single webhook for everything
    telegramWebhook = 'https://discord.com/api/webhooks/YOUR_WEBHOOK', -- per-type override
    parcelWebhook   = 'https://discord.com/api/webhooks/YOUR_WEBHOOK',
    username        = 'Telegraph Office',
    avatar          = '',
}
```

### Client Config

NPC clerk spawn points, map blip settings (sprite, color, scale), and the on-screen position of the unread-telegram HUD indicator are all defined in the client-side `config.lua`. Each office entry uses a `vector4` coordinate (x, y, z, heading) for the NPC's spawn position and facing direction.

<Note>
  After editing either config file, restart the resource with `ensure sh-telegram` in your server console for changes to take effect.
</Note>

## sh-identity Integration

If your server runs [sh-identity](/redm/sh-identity), you can require players to hold a valid identity card before they can use the telegraph office:

```lua config.lua (server) theme={null}
Config.UseSH_Identity = true
```

When this option is enabled, characters without a registered identity card receive a clerk dialogue prompting them to obtain one before sending.

<Tip>
  Enable `Config.UseSH_Identity` if your server uses identity cards as a prerequisite for most civic services — it keeps the roleplay loop consistent and gives the sh-identity resource meaningful utility beyond document checks.
</Tip>

## Installation

<Steps>
  <Step title="Add the resource">
    Copy the `sh-telegram` folder into your server's `resources` directory.
  </Step>

  <Step title="Add to server.cfg">
    Add `ensure sh-telegram` to your `server.cfg` after your framework resource and, if applicable, after `sh-identity`.

    ```cfg server.cfg theme={null}
    ensure vorp_core       # or rsg-core
    ensure sh-identity     # if UseSH_Identity = true
    ensure sh-telegram
    ```
  </Step>

  <Step title="Import the SQL file">
    Run the SQL file found in the `sql/` folder of the resource against your database to create the required tables for telegrams, parcels, contacts, and character IDs.
  </Step>

  <Step title="Configure">
    Open `server/config.lua` and set your framework, fees, ID mode, and webhook URLs. Then open the client config to place your telegraph office NPC locations.
  </Step>

  <Step title="Restart and test">
    Start your server, approach an office NPC, and verify the clerk interaction opens correctly. Send a test telegram between two characters to confirm delivery and inbox display.
  </Step>
</Steps>

<Warning>
  If you change `Config.TelegramIdMode` after the resource has been running, it is recommended to clear all existing Telegram ID records from the database so that IDs are regenerated consistently in the new format. Mixed-format IDs in the same database can cause lookup failures.
</Warning>
