Koja Scripts

Client exports

koja-dispatcher client exports for checking the dispatcher state and raising alerts or 911 calls from client scripts, with the security rules that apply.

Client exports

All exports on this page are called from client scripts:

client.lua
local dispatch = exports['koja-dispatcher']
ExportReturnsYields
IsOnShift()booleanno
IsCadOpen()booleanno
SendAlert(data)id, route or false, erroryes
Call911(message)true, route or false, erroryes

SendAlert and Call911 send a request to the server and wait up to 10 seconds for the answer. Call them from a thread, a command or an event handler, never from the main chunk of a file.


IsOnShift()

Returns true when the local player is on shift as a dispatcher (at a station or with the remote CAD).

client.lua
if exports['koja-dispatcher']:IsOnShift() then
    return -- do not open my phone while the player is dispatching
end

IsCadOpen()

Returns true when the local player is on shift and the CAD has focus (mouse and keyboard captured by the dispatcher UI).

client.lua
CreateThread(function()
    while true do
        Wait(500)
        local busy = exports['koja-dispatcher']:IsCadOpen()
        exports['my-hud']:SetVisible(not busy)
    end
end)

SendAlert(data)

Raises a 911 alert from a client script, for example a robbery or a phone app that only runs on the client. It goes through the call router like /911.

FieldTypeRequiredDescription
messagestringnoText of the call. The server removes control characters and keeps 300 characters.
callerstringnoCaller name (max 64). Default Anonymous.
coordsvector3 / tablenoPosition of the alert. Defaults to the player's ped. Clamped, see below.
labelstringnoPlace label (max 96). Default: the street name at coords, read on the client.
needtablenoUnits needed, { police = 1 }.
prioritynumberno1 to 3.

Returns id, route (route is 'call', 'incident' or 'mdt'), or false, error.

Errors

CodeMeaning
disabledapi.clientAlerts is off (the default).
invaliddata is not a table, or the player has no ped.
no_dispatchersNobody on shift and mode.noDispatcher is reject (or mdt without koja-mdt).
cancelledA callCreate or incidentCreate hook blocked it. A callCreate hook's own reason is returned instead when it gave one.
no_responseThe server did not answer within 10 s, or the request was rate limited.
client.lua
RegisterCommand('reportcarjack', function()
    local id, route = exports['koja-dispatcher']:SendAlert({
        message = 'Someone is breaking into a car',
        caller = 'Anonymous',
        coords = GetEntityCoords(PlayerPedId()),
        need = { police = 1 },
        priority = 2,
    })
    if not id then
        print('alert failed: ' .. tostring(route))
    elseif route == 'call' then
        print('a dispatcher will answer the call')
    end
end, false)

Call911(message)

The same as typing /911 <message>, for phone apps and other client UIs. The call comes from the player's own position, and the dispatcher's answers, questions and replies come back to the player as notifications (or as phone messages when a supported phone is running).

ParamTypeRequiredDescription
messagestringyesAt least 3 characters. The server removes control characters and keeps 250.

Returns true, route, or false, error.

routeMeaning
'call'Rings at the dispatcher console.
'incident'Nobody on shift, mode.noDispatcher = 'auto': an incident was created and units are on the way.
'mdt'Sent to koja-mdt.
'update'Added to the player's open call (within calls.playerReplyWindow) or to the incident that follows them.

Errors invalid (message missing or shorter than 3 characters), no_dispatchers, cancelled or a callCreate hook's reason, no_response (timeout or rate limit: a burst of 2, then one every 20 seconds).

client.lua
RegisterNUICallback('phone:call911', function(data, cb)
    local ok, route = exports['koja-dispatcher']:Call911(data.text)
    cb({ ok = ok, route = route })
end)

Call911 does not depend on api.clientAlerts: it is the same path as the /911 command, which every player can already use.