twocents/open source

Run hooks on recording events

Run local programs when recording or transcription status changes.

The current events are:

channel.joined
channel.left
recording.started
recording.completed
recording.failed
transcription.completed
transcription.failed

channel.joined fires after a newly created Discord voice connection reaches ready. channel.left fires after that announced connection is destroyed. Ordinary transient connection-state changes that recover on the same connection do not emit another pair. If recovery is abandoned and Guildscribe creates a new connection, the actual departure and later ready connection each emit their corresponding event.

Each configured executable receives the event name as its first argument, uses the recording directory as its working directory, and receives one versioned JSON event on stdin. Every version-2 payload includes the recording, guild, and active channel IDs and databasePath instead of manifestPath. The child environment is restricted to ordinary process location variables plus GUILDSCRIBE_HOME and GUILDSCRIBE_EVENT; it never contains the Discord token.

Hooks run only after Guildscribe has saved the corresponding state. Their stdout and stderr are bounded and sent to Guildscribe diagnostics. A hook timeout or nonzero exit does not change recording status. Delivery is best effort. If you need several actions or an HTTP call, configure a script that performs them.

To generate transcripts, configure the separate transcription hook. A recording.completed notification does not enable or replace it.

Configure absolute executable paths under hooks through init or config update. The keys are channelJoined, channelLeft, recordingStarted, recordingCompleted, recordingFailed, transcriptionCompleted, and transcriptionFailed; request schemas define exact fields. Set a hook to JSON null in an update to clear it.

Executables run directly without shell interpolation. Use an executable file with an appropriate shebang. Treat hook code as trusted code with the daemon user's permissions and keep credentials out of output.

HookInputOutputFailure effect
LifecycleEvent-name argument and JSON on stdinNotificationRecording remains valid
TranscriptionRecording-directory argument, no structured stdinAtomic pending JSON fileFailed transcript; audio retained
Slash commandInvocation JSON on stdinOne JSON message on stdoutGeneric error; no automatic retry

See transcription and messaging for the separate interfaces.