Skip to main content

useLumioAction

Execute a Lumio service action — a named operation on the host platform such as sending a chat message, changing an OBS scene, or emitting a custom event.

Signature

const { execute, data, isLoading, error } = useLumioAction(actionType: LumioActionType);

Parameters

ParameterTypeRequiredDescription
actionTypeLumioActionTypeYesThe action type to execute (e.g. "chat:send")

Return value

PropertyTypeDescription
execute(payload: unknown) => Promise<void>Call this to trigger the action
dataunknown | nullResponse data from the last execution
isLoadingbooleantrue while the action is in progress
errorstring | nullError message if the last execution failed

Supported action types

Chat

| Action type | Required permission | Payload | |-------------|--------------------|---------|| | "chat:send" | chat:send | { message: string } | | "chat:delete" | chat:delete | { messageId: string } | | "chat:ban" | chat:ban | { userId: string; reason?: string } | | "chat:unban" | chat:ban | { userId: string } | | "chat:timeout" | chat:ban | { userId: string; durationSeconds: number; reason?: string } |

OBS

| Action type | Required permission | Payload | |-------------|--------------------|---------|| | "obs:set_scene" | obs:control | { scene: string } | | "obs:set_source_visible" | obs:control | { source: string; visible: boolean } | | "obs:start_stream" | obs:control | {} | | "obs:stop_stream" | obs:control | {} | | "obs:start_recording" | obs:control | {} | | "obs:stop_recording" | obs:control | {} |

Spotify

| Action type | Required permission | Payload | |-------------|--------------------|---------|| | "spotify:play" | spotify:control | {} | | "spotify:pause" | spotify:control | {} | | "spotify:skip" | spotify:control | {} | | "spotify:seek" | spotify:control | { positionMs: number } | | "spotify:volume" | spotify:control | { volume: number } | | "spotify:shuffle" | spotify:control | { enabled: boolean } | | "spotify:repeat" | spotify:control | { mode: "off" \| "track" \| "context" } | | "spotify:queue_add" | spotify:control | { uri: string } |

Events

| Action type | Required permission | Payload | |-------------|--------------------|---------|| | "events:emit" | events:write | { type: string; data: unknown } |

Overlay

| Action type | Required permission | Payload | |-------------|--------------------|---------|| | "overlay:update_layer" | overlays:edit | { layerId: string; visible: boolean } |

Example: Send a chat message

import { Lumio, CompactView, Button, TextField, useLumioAction } from "@zaflun/lumio-sdk";
import { useState } from "react";

function ChatPanel() {
const { execute: sendMessage, isLoading, error } = useLumioAction("chat:send");
const [message, setMessage] = useState("");

const handleSend = async () => {
await sendMessage({ message });
setMessage("");
};

return (
<CompactView title="Send to chat">
<TextField
label="Message"
value={message}
onChange={setMessage}
/>
{error && <Text content={error} variant="muted" />}
<Button
label={isLoading ? "Sending..." : "Send"}
onClick={handleSend}
disabled={isLoading || !message.trim()}
/>
</CompactView>
);
}

Lumio.render(<ChatPanel />, { target: "editor" });

Example: Switch OBS scene

import { Button, Dropdown, useLumioAction } from "@zaflun/lumio-sdk";
import { useState } from "react";

function SceneSwitcher() {
const { execute: setScene, isLoading } = useLumioAction("obs:set_scene");
const [scene, setSceneValue] = useState("Main");

return (
<>
<Dropdown
label="Scene"
value={scene}
options={[
{ value: "Main", label: "Main" },
{ value: "BRB", label: "Be Right Back" },
{ value: "Ending", label: "Ending screen" },
]}
onChange={setSceneValue}
/>
<Button
label="Switch scene"
onClick={() => setScene({ scene })}
disabled={isLoading}
/>
</>
);
}

Declaring permissions

Actions require declaring the corresponding permission in lumio.config.json. Undeclared permissions are rejected at runtime:

{
"permissions": ["chat:send", "obs:set_scene"]
}

Declared permissions are shown to the user during installation, and they must grant consent before the extension can use them.

Notes

  • Actions can only be called from the editor surface — not from the layer surface (read-only) and not from the interactive surface (audience-facing)
  • The error property contains a human-readable message when an action fails (e.g., OBS is not connected)
  • Each action call creates a new entry in the audit log, visible in the extension dashboard