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:
export { offer, runSocketAgent, socket } from "../shared/voice.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.tsIt 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).