tap

View as MarkdownOpen in Claude

Intercept call media (audio) and stream it to an external destination such as a WebSocket or RTP endpoint. Returns a TapAction that you can use to stop the tap or wait for it to finish.

This method emits calling.call.tap events. See Call Events for payload details.

Parameters

tap
Record<string, unknown>Required

Tap configuration specifying which audio to intercept.

tap.type
stringRequired

Tap type. Valid values: "audio".

tap.params
Record<string, unknown>

Tap parameters. Supports a direction key with the following values:

  • "listen" — capture audio heard by the caller
  • "speak" — capture audio spoken by the caller
  • "both" — capture audio in both directions
device
Record<string, unknown>Required

Destination device for the tapped media.

device.type
stringRequired

Device type.

  • "ws" — WebSocket endpoint
  • "rtp" — RTP endpoint
device.params
Record<string, unknown>Required

Device-specific parameters (e.g., uri for WebSocket, addr/port for RTP).

controlId
string | undefined

Custom control ID. Auto-generated if not provided.

onCompleted
(event: RelayEvent) => void | Promise<void>

Callback invoked when the tap operation ends.

Returns

Promise<TapAction> — An action handle with stop() and wait() methods.

Example

1import { RelayClient } from '@signalwire/sdk';
2
3const client = new RelayClient({
4 project: process.env.SIGNALWIRE_PROJECT_ID!,
5 token: process.env.SIGNALWIRE_TOKEN!,
6 contexts: ['default']
7});
8
9client.onCall(async (call) => {
10 await call.answer();
11
12 // Tap audio and stream to a WebSocket endpoint
13 const action = await call.tap(
14 { type: 'audio', params: { direction: 'both' } },
15 { type: 'ws', params: { uri: 'wss://example.com/tap' } }
16 );
17
18 // Tap runs in background; stop it later
19 await new Promise((resolve) => setTimeout(resolve, 30_000));
20 await action.stop();
21});
22
23await client.run();