Perch
Lua APIVoice

Voice

perch.voice.on_intent: act on the intents Perch's voice router recognises. Always granted.

1 min readUpdated Sep 9, 2026

Perch’s voice router listens for the wake word and turns what was said into one of a closed set of intents. A mod hooks the intents it can serve; it never hears audio or a transcript, so no scope is needed.

perch.voice.on_intent

perch.voice.on_intent(intent: intent_t, handler: (args: intent_args_t) -> ()): connection_t
perch.voice.on_intent("play_pause", function(args: intent_args_t) perch.media.play_pause() end)
perch.voice.on_intent("set_volume", function(args: intent_args_t) perch.audio.volume.set(args.level or 50) end)

Returns a connection; :disconnect() unhooks it. An unknown intent name raises at connect time and lists the valid ones; a non-function handler raises perch.voice.on_intent: handler must be a function. The builtin media, system, Discord and pomodoro packages are ordinary listeners on these hooks.

IntentSpoken likeargs
play_pause, next, previous, restart”pause”, “next song”, “go back”, “start over”none
volume_up, volume_down”turn it up”, “quieter”none
set_volume”volume to forty”{ level = 0..100 }
toggle_mute, toggle_deafen, hangup, accept_call, decline_call”mute”, “deafen”, “hang up”, “pick up”, “decline”none
pomodoro_start_pause, pomodoro_reset”start the pomodoro”, “reset the pomodoro”none

Types

export type intent_t = "play_pause" | "next" | "previous" | "restart" | "volume_up" | "volume_down" | "set_volume" | "toggle_mute" | "toggle_deafen" | "hangup" | "accept_call" | "decline_call" | "pomodoro_start_pause" | "pomodoro_reset"
export type intent_args_t = { level: number? }

The intent names, and the argument table (level on set_volume only).

esc
Type to search
navigate open