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

Express

Mount the pipedog WebRTC offer endpoint in an Express 5 app.

Express 5 mounts the offer through nodeRequestListener, which turns a fetch handler into a Node request listener. This snippet mounts only the offer.

Install

bun add @pipedog/core @pipedog/asyncio @pipedog/transport-smallwebrtc @pipedog/transport-websocket @pipedog/serializer-protobuf @pipedog/openai @pipedog/audio-silero @pipedog/audio-smart-turn express

@pipedog/audio-smart-turn isn't imported anywhere: the default turn strategies load it. To run the snippet from a checkout instead, see Installation.

Files

The endpoints come from the shared module on the overview. voice.ts re-exports it:

voice.ts
export { offer, runSocketAgent, socket } from "../shared/voice.ts";
server.ts
import { nodeRequestListener } from "@pipedog/transport-smallwebrtc/http";
import express, { type Express } from "express";
import { offer } from "./voice.ts";

const app: Express = express();

// Don't add express.json(): the offer handler reads the body itself.
app.post("/api/offer", nodeRequestListener(offer));

export default app;

// `node server.ts` starts it on port 3000.
if (import.meta.main) {
  app.listen(3000);
}

Don't add express.json() in front of the route: the offer reads the body itself, and a body parser would consume it first.

Run it

OPENAI_API_KEY=sk-... node server.ts

It listens on port 3000. bun server.ts works too. Node runs the TypeScript with its built-in type stripping, in a workspace; see Runtimes.

Deploy

Run it as a long-lived Node or Bun process on a host that allows UDP traffic, for the offer's media.

WebSocket

This snippet mounts only the offer. To serve WebSocket sessions too, serve socket on a second port with serveFetch(socket, { port }) from @pipedog/transport-websocket/serve, which upgrades WebSockets on Node (with the ws package), Bun and Deno, or run a Bun or Deno server for it. See WebSocket.

Authentication

The route has no auth. Wrap offer with a session check before nodeRequestListener, or add an Express middleware in front of the route, as in Authentication.

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