> For the complete documentation index, see [llms.txt](https://mango-5m.gitbook.io/mango5m-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mango-5m.gitbook.io/mango5m-docs/resources/mango-dispatch/developer-guide/custom-framework-bridge.md).

# Custom Framework Bridge

Four functions are all it takes to run Mango Dispatch on any core.

If you are not on ESX, QBCore or Qbox, fill in `bridge/framework/custom.lua` and point the config at it. There are exactly four functions and none of them touch money, items or inventory.

{% stepper %}
{% step %}

### Open `bridge/framework/custom.lua`

It ships as a working stub - identifiers already fall back to the player's `license:`, and names to `GetPlayerName`.
{% endstep %}

{% step %}

### Implement the four functions

```lua
local Provider = {}

function Provider.detect()
    return GetResourceState('my_core') == 'started'
end

-- Unique, persistent player identifier (ESX identifier / QB citizenid).
function Provider.GetIdentifier(src)
    return exports['my_core']:GetPlayer(src).uid
end

-- Character name shown as the caller / responder name.
function Provider.GetPlayerName(src)
    return exports['my_core']:GetPlayer(src).fullName
end

-- { name = 'police', label = 'Police', grade = 3, onDuty = true }
function Provider.GetJob(src)
    local player = exports['my_core']:GetPlayer(src)
    if not player then return nil end
    return {
        name = player.job,
        label = player.jobLabel,
        grade = player.jobGrade,
        onDuty = player.onDuty,
    }
end

-- Phone number for the 911 caller line. Return nil if you have none.
function Provider.GetPhone(identifier)
    return nil
end

Mango.Bridge.Register('framework', 'custom', Provider)
```

{% endstep %}

{% step %}

### Bind it

```lua
-- config/bridge.lua
Config.Bridge.Framework = 'custom'
```

Setting it explicitly rather than leaving `'auto'` skips detection entirely, which is the safer choice on a server that also has an ESX or QB resource lying around.
{% endstep %}

{% step %}

### Verify

Restart and run `mango_dispatch_bridges` in the server console. It should report `Framework custom`.
{% endstep %}
{% endstepper %}

### What each function is used for

| Function        | Consequence if it returns `nil`                                                                   |
| --------------- | ------------------------------------------------------------------------------------------------- |
| `GetIdentifier` | Falls back to `license:`. Responders still work, but identities do not survive a character switch |
| `GetPlayerName` | Falls back to the Steam / FiveM name                                                              |
| `GetJob`        | Job-based recipients stop working. Run `Config.Recipients.mode = 'registered'`                    |
| `GetPhone`      | 911 calls show `Unknown` as the caller number. Nothing else changes                               |

{% hint style="info" %}
`GetJob` is called often, so keep it cheap - the resource caches the result for 5 seconds per player, but a function that hits the database on every call will still hurt.
{% endhint %}

### The safety net

A bridge function that errors is caught, logged once, and treated as returning `nil`. A missing function is reported once with the file it should live in. A broken bridge degrades the resource - it does not crash it.

### Running without any framework

```lua
Config.Bridge.Framework = 'none'
Config.Recipients.mode = 'registered'
```

Identifiers fall back to `license:` and you decide who is on the air with `RegisterUnit`. Everything else - alerts, the window, responding, Primary, Code 4 - works exactly the same.
