pipedog is an unofficial community port of Pipecat, not affiliated with Daily.
pipedog

Genesys

Genesys Cloud AudioHook sessions with GenesysAudioHookSerializer, used with FastAPIWebsocketTransport.

Overview

GenesysAudioHookSerializer speaks Genesys Cloud's AudioHook protocol, so a contact-center call flow can hand a caller to a bot and get results back:

  • Binary μ-law audio at 8 kHz both ways, resampled to and from the pipeline's rate. In stereo (external and internal), only the caller's (left) channel reaches the pipeline.
  • The handshake is answered for you: open → opened, ping → pong, close → closed, each returned from deserialize as an OutputTransportMessageUrgentFrame the transport sends back.
  • pause stops audio until you send createResumedResponse(); update refreshes the participant; dtmf becomes an InputDTMFFrame.
  • Architect variables in (inputVariables, from open) and out (setOutputVariables(), sent in closed and disconnect).
  • An InterruptionFrame sends a barge-in event; an EndFrame or CancelFrame sends disconnect.

Installation

bun add @pipedog/serializer-genesys @pipedog/transport-websocket
import {
  AudioHookChannel,
  GenesysAudioHookSerializer,
} from "@pipedog/serializer-genesys/genesys";

Prerequisites

  • A Genesys Cloud org with an AudioHook Monitor or AudioConnector integration whose connection URI is your WebSocket URL, and an Architect flow that uses it.

GenesysAudioHookSerializer

Configuration

Prop

Type

InputParams

params is a GenesysAudioHookSerializer.InputParams (GenesysAudioHookSerializerInputParams):

ParamTypeDefaultDescription
genesysSampleRatenumber8000Sample rate Genesys uses, in Hz.
sampleRatenumber | nullnullOverride for the pipeline input rate. null uses the pipeline's.
channelAudioHookChannelEXTERNALChannels to offer: EXTERNAL, INTERNAL or BOTH. Updated from Genesys's open.
mediaFormatAudioHookMediaFormatPCMUAudio format. Only PCMU is implemented, as upstream.
processExternalbooleantrueProcess the caller's audio.
processInternalbooleanfalseProcess the agent's audio.
supportedLanguagesstring[] | nullnullLanguages sent in opened.
selectedLanguagestring | nullnullLanguage selected in opened.
startPausedbooleanfalseAsk Genesys to start the session paused.
resamplerClearAfterSecsnumber | null0.2Seconds of silence after which the resamplers clear their history. null (never) suits Genesys's irregular chunks.
ignoreRtviMessagesbooleantrueDrop RTVI messages.

Usage

genesys.ts
import { AudioHookChannel, GenesysAudioHookSerializer } from "@pipedog/serializer-genesys/genesys";
import {
  FastAPIWebsocketParams,
  FastAPIWebsocketTransport,
} from "@pipedog/transport-websocket/fastapi";
import { websocketFetchHandler } from "@pipedog/transport-websocket/fetch";
import type { WebsocketConnection } from "@pipedog/transport-websocket/socket";

async function runSession(connection: WebsocketConnection): Promise<void> {
  const serializer = new GenesysAudioHookSerializer({
    params: new GenesysAudioHookSerializer.InputParams({
      channel: AudioHookChannel.EXTERNAL,
      supportedLanguages: ["en-US", "es-ES"],
      selectedLanguage: "en-US",
    }),
  });

  const transport = new FastAPIWebsocketTransport(
    connection,
    new FastAPIWebsocketParams({
      audioInEnabled: true,
      audioOutEnabled: true,
      serializer,
      // Genesys rate-limits (HTTP 429) many small audio messages.
      fixedAudioPacketSize: 1600,
    }),
  );
  // ... build and run the pipeline with transport.input() and transport.output()
}

// The AudioHook integration's connection URI points here.
const handler = websocketFetchHandler(runSession);

Read the caller's details and return variables to the flow:

const serializer = new GenesysAudioHookSerializer();

serializer.eventHandler("on_open", async () => {
  // From Genesys's "open" message.
  const ani = serializer.participant?.ani;
  const queue = serializer.inputVariables?.queue_name;
  console.log(`call from ${ani} for ${queue}`);
});

// Returned to the Architect flow in "closed" (and "disconnect").
serializer.setOutputVariables({ intent: "billing", resolved: true });

Events

EventWhen
on_openGenesys opened the session (before opened is sent).
on_closeGenesys closed the session.
on_pingA ping arrived.
on_pauseGenesys paused the stream (e.g. on hold).
on_updateAn update arrived.
on_errorGenesys reported an error.
on_dtmfA digit was pressed.

Notes

  • Audio is dropped until the session is open, and while it is paused.
  • Only transport messages that are AudioHook messages (with a version field) are sent; others are dropped.
  • Positions are ISO 8601 durations with millisecond precision (PT12.500S), echoed from the last client message.

Runtime notes

RuntimeWorksWhat it needs
Bun✅ yesNothing.
Node.js✅ yesNothing.
Deno✅ yesNothing.
Cloudflare Workers✅ yesNothing.

Generated from pipecat.runtimes and pipecat.compat in packages/serializer-genesys/package.json: ✅ means the compat smoke test passes on that runtime.

Runs on Bun, Node, Deno and Cloudflare Workers. The package's golden tests replay AudioHook sessions recorded from upstream, message by message.

pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.

Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).

On this page