Onex
Onex
Home
Products
Documentation
Changelog
Login with FiveM
  • 👋 Welcome
  • Claim Purchase
  • Translations
    • Weaponmeta
    • Voice Interaction
      Integrations
      Installation
      Configuration
      Features
      Api
      Events
      Layers
      Npc
      Speech
Artifacts Tracker
  1. Onex Scripts
  2. Scripts_guides / Action System
Ctrl K

ACTION SYSTEM#

Actions are voice commands. Register them with registerAction and the SDK handles speech recognition, matching, variable extraction, and trigger execution.

registerAction#

Syntax
exports['onex-voiceInteraction']:registerAction(def)

Parameters#

NameTypeRequiredDefaultDescription
namestring✅—Unique action identifier. Duplicate names are rejected with DUPLICATE.
phrasesstring[]✅—Voice phrases to match. Use {variable} for extraction slots. Must be non-empty.
triggertable✅—What executes on match. At least one trigger type required.
descriptionstring—nilNatural language description for LLM tier matching. Max 200 chars.
minSimilaritynumber—0.7Minimum match score (0.0–1.0). Falls back to Config.Matching.MinConfidence.
groupstring—nilGroup name for batch enable/disable.
tagsstring[]—{}Additional tags. Can be disabled like groups with setActionEnabled.
layerstring—autoLayer assignment. Auto-assigned if omitted — see Layer Auto-Assignment below.
conditionfunction—nilPre-execution gate. Receives callback data. Return false to block.
variableAliasestable—nilPer-variable synonym map { amount = "sum" }.
variableTypestable—nilPer-variable type hints: "number", "boolean", "string".
variableDefaultstable—nilCustom word-to-value fallback mappings { size = "large" }.
numberNormalizationboolean—nilEnable automatic word-to-number parsing (e.g. "five" → 5).

Return value#

{ success = true, data = { name = "buy_item" } } { success = false, error = "...", code = "DUPLICATE" }

Layer auto-assignment#

If layer is not specified, it is automatically assigned based on the group field:

explicit layer field  →  uses that layer
has group, no layer   →  "context"
no group, no layer    →  "ambient"

Actions on "ambient" are active when no custom layer suppresses ambient. Actions on "context" or custom layers require the layer to be entered with a matching group. Actions on "global" are always active.

Basic example#

Your Script
exports['onex-voiceInteraction']:registerAction({ name = "buy_item", phrases = { "buy {item}", "i want {item}", "give me {item}" }, trigger = { event = { name = "myres:buyItem", type = "server", params = { shopId = "liquor_1" } } }, group = "voice_shop_liquor_1", minSimilarity = 0.7 })

Same-resource registration#

Within the same resource, use RegisterAction (global) instead of the export. Lua callbacks do not survive export boundaries — only the global bypasses this:

Your Script
-- Inside the same resource as onex-voiceInteraction scripts RegisterAction({ name = "internal_command", phrases = { "test voice" }, trigger = { callback = function(data) print("Matched:", data.transcript) end } })

Trigger types#

The trigger field is a table that can contain any combination of types. All provided types fire simultaneously when the action matches.

Syntax
trigger = { callback = function(data) end, -- direct function call event = { ... }, -- single client/server event events = { ... }, -- multiple events export = { ... }, -- another resource's export }

At least one type must be present.

callback#

Direct function call. Best for logic that lives in the same resource.

Your Script
trigger = { callback = function(data) print("Transcript:", data.transcript) print("Confidence:", data.confidence) print("Amount:", data.extractedVariables.amount) end }

event (single)#

Fire one client or server event.

Your Script
trigger = { event = { name = "myresource:giveWater", -- required type = "server", -- "client" or "server" (required) params = { itemId = "water" } -- merged into callback data(optional) } }

The receiving handler gets all standard callback data fields plus your custom params:

Server Handler
RegisterNetEvent('myresource:giveWater') AddEventHandler('myresource:giveWater', function(data) -- data.transcript, data.confidence, data.score, data.extractedVariables -- data.itemId = "water" (from params) end)

events (multiple)#

Fire multiple events simultaneously.

Your Script
trigger = { events = { { name = "combat:attack", type = "client" }, { name = "combat:log", type = "server", params = { logAction = true } } } }

export#

Call an export function from another resource. Executed as exports["resource"].name(mergedData).

Your Script
trigger = { export = { resource = "ox_inventory", -- required name = "openInventory", -- required params = { type = "player" } } }

Combined triggers#

Your Script
exports['onex-voiceInteraction']:registerAction({ name = "buy_drink", phrases = { "buy {item}" }, trigger = { event = { name = "myres:logPurchase", type = "server", params = { shopId = "liquor_1" } }, callback = function(data) PlaySoundFrontend(-1, "PURCHASE", "HUD_LIQUOR_STORE_SOUNDSET", false) end }, group = "voice_shop_liquor_1" })

Callback data#

Every trigger receives this data object:

FieldTypeDescription
transcriptstringRecognized speech text
confidencenumberSTT confidence (0.0–1.0)
commandtableFull action definition
scorenumberMatch score (0.0–1.0)
tiernumberMatching tier used (1–4)
methodstringTier label: "tier1", "tier2", "tier3", or "llm"
extractedVariablestableVariables from {placeholder} phrases

For event, events, and export triggers, the params table is merged into this object before dispatch.

Variable extraction#

Use {variable} in phrases to capture spoken words. Extracted values arrive in data.extractedVariables.

Basic usage#

Your Script
exports['onex-voiceInteraction']:registerAction({ name = "give_cash", phrases = { "give me {amount} dollars", "transfer {amount}" }, trigger = { callback = function(data) local amount = data.extractedVariables.amount print("Amount:", amount) end }, variableTypes = { amount = "number" }, variableAliases = { amount = "sum" }, variableDefaults = { amount = "100" } })

variableTypes#

Coerce extracted string values to Lua types:

ValueBehavior
"number"tonumber() — "five" becomes 5
"boolean""yes"/"true" → true, others → false
"string"No conversion (default)

variableAliases#

Map spoken synonyms to canonical variable names. If the player says "sum" and you define { amount = "sum" }, the extracted value appears as extractedVariables.amount.

variableDefaults#

Fallback values used when the variable is not extracted from speech.

condition#

A pre-execution gate. If it returns false, the action is silently skipped — no trigger fires, no event emitted.

Your Script
exports['onex-voiceInteraction']:registerAction({ name = "rob_npc", phrases = { "give me your money", "hands up" }, condition = function(data) -- Only allow if player has a weapon drawn return IsPedArmed(PlayerPedId(), 4) end, trigger = { callback = function(data) TriggerEvent('robbery:start') end } })

The condition function receives the same data object as triggers (transcript, confidence, etc.).

unregisterAction#

Syntax
exports['onex-voiceInteraction']:unregisterAction(target)
Target formBehavior
"action_name"Unregister that specific action
"@resource_name"Unregister all actions from that resource
(omitted)Unregister all actions from the calling resource

Static actions (registered from config.lua) cannot be unregistered — they return STATIC_ACTION.

Actions from another resource cannot be unregistered — returns PERMISSION_DENIED.

Resources are also auto-cleaned when they stop (onResourceStop).

Your Script
exports['onex-voiceInteraction']:unregisterAction("buy_item") exports['onex-voiceInteraction']:unregisterAction("@my-resource") exports['onex-voiceInteraction']:unregisterAction()

queryActions#

Syntax
exports['onex-voiceInteraction']:queryActions(filter)

All filter fields are optional. Omit to return all registered actions.

Filter fieldTypeDescription
namestringExact action name
groupstringGroup name
tagstringTag value
enabledbooleanCurrent enabled state
resourcestringSource resource name

Returns: { success = true, data = { actions = { ... }, count = 5 } }

Each action in the array includes: name, phrases, trigger, minSimilarity, source, isStatic, group, tags, enabled.

Your Script
local r = exports['onex-voiceInteraction']:queryActions({ group = "voice_shop_1", enabled = true }) for _, action in ipairs(r.data.actions) do print(action.name, action.enabled) end

setActionEnabled / getActionEnabled#

setActionEnabled#

Syntax
exports['onex-voiceInteraction']:setActionEnabled(target, enabled)
Target formBehavior
"action_name"Enable/disable that specific action
"#group_name"Enable/disable all actions with that group
"*"Enable/disable all registered actions
Your Script
exports['onex-voiceInteraction']:setActionEnabled("buy_item", false) exports['onex-voiceInteraction']:setActionEnabled("#voice_shop_1", false) exports['onex-voiceInteraction']:setActionEnabled("*", true)

getActionEnabled#

Syntax
exports['onex-voiceInteraction']:getActionEnabled(target)
Target formReturns
"action_name"{ enabled = true }
"#group_name"{ enabled = true }
(omitted){ disabledActions = { ... }, disabledGroups = { ... } }
Your Script
local r = exports['onex-voiceInteraction']:getActionEnabled("#voice_shop_1") print("shop group enabled:", r.data.enabled)

Error codes#

CodeWhen it occurs
INVALID_INPUTdef is not a table, or required fields are missing/wrong type
DUPLICATEAn action with that name is already registered
NOT_FOUNDTarget action name does not exist
NOT_INITIALIZEDAction registry not yet ready (called too early)
STATIC_ACTIONAttempt to unregister a config-defined action
PERMISSION_DENIEDAttempt to unregister an action owned by another resource

Last updated 4 months ago

Quick Links

All DocumentationOur Products