Skip to main content

Setting Up Voicemail

This guide is using Relay V4

This guide is available for Relay V3 and for Relay V4. You are currently viewing the guide for Relay V4. To switch to the older Relay V3 guide, please use the selection field below:

A popular and important use case is recording a voicemail from your callers when you are unable to speak with them. This guide will show how to do exactly that.

In this guide we will see how to implement a voicemail using Node.js. This allows you the most flexibility in case you want to integrate voicemails with complex workflows.

Assigning a Phone Number to a Relay Context

To handle calls using Node.js, you should first set up a phone number to handle incoming calls using a Relay application.

Click the Phone Numbers tab on your lefthand side nav within your SignalWire Space, and click the specific number you would like to set up call forwarding on. If you don't have a number yet, now is the time to buy one!

A screenshot of the Voice and Fax Settings pane. Incoming calls will be accepted as voice calls, and handled with a Relay Application defined as the 'office' Relay context.

To configure your number to handle incoming calls with a Relay application, set "Handle calls using" to "Relay Application", then specify the name of a context (here we choose "office").

Building the application

Our phone number is now configured. Let's see how to build the voicemail with Node.js.

Installation

First, you need to obtain the Realtime SDK. From your terminal you can run:

npm install --save @signalwire/realtime-api@~3

This will install the Realtime SDK from npm into your project.

Code

The first thing we need to do is to import the Realtime SDK and initialize a Voice client. We can do it like this:

import { Voice } from "@signalwire/realtime-api";

const client = new Voice.Client({
project: "<project-id>",
token: "<api-token>",
contexts: ["office"],
});

We want to execute our logic whenever a call is received. Let's attach an event handler to the call.received event, from which we can answer the call and play a message:

client.on("call.received", async (call) => {
console.log("Got call", call.from, call.to);

await call.answer();

const tts = await call.playTTS({
text: "Please leave a message with your name and number at the beep. Press the pound key when finished.",
});
await tts.waitForEnded();
});

Right after playing the introduction message, we need to start recording. But before that, let's set up an event listener within the call.received handler which will notify us when the recording has ended:

// inside the "call.received" event handler

call.on("recording.ended", async (rec) => {
const tts = await call.playTTS({
text: "Thank you for your message. A member of our team will contact you shortly. Goodbye!",
});
await tts.waitForEnded();

console.log("Recording URL:", rec.url);

await call.hangup();
});

We can finally start the recording. Since we also want the recording to be no more than 15 seconds long, we will set a timeout which will stop it if it didn't already end.

const recording = await call.recordAudio({
endSilenceTimeout: 0,
terminators: "#",
});

// Stop the recording after 15 seconds.
setTimeout(() => recording.stop(), 15000);

Putting all of the parts together, here is the full code:

index.js
index.js
import { Voice } from "@signalwire/realtime-api";

const client = new Voice.Client({
project: "<project-id>",
token: "<api-token>",
contexts: ["office"],
});

client.on("call.received", async (call) => {
console.log("Got call", call.from, call.to);

await call.answer();

const tts = await call.playTTS({
text: "Please leave a message with your name and number at the beep. Press the pound key when finished.",
});
await tts.waitForEnded();

// Callback to be executed when the recording ends.
call.on("recording.ended", async (rec) => {
const tts = await call.playTTS({
text: "Thank you for your message. A member of our team will contact you shortly. Goodbye!",
});
await tts.waitForEnded();

console.log("Recording URL:", rec.url);

await call.hangup();
});

const recording = await call.recordAudio({
endSilenceTimeout: 0,
terminators: "#",
});

// Stop the recording after 15 seconds.
setTimeout(() => recording.stop(), 15000);
});

console.log("Started.");

Wrapping up

The Realtime SDK allows you to build powerful applications with a simple API. You are not limited to phone calls: you can also control messaging, chat, video, and more. See all available options in the Realtime SDK documentation.