Realtime Output with PSTN Dialing using Symbl's Javascript SDK

In this example let's walk through how to get the real-time transcription and insights events in a Telephone call.

Throughout the documentation you'll find various references to these variable names, which you will have to replace with your own values:

KeyDescription
APP_IDThe application ID you get from the home page of the platform.
APP_SECRETThe application secret you get from the home page of the platform.
AUTH_TOKENThe JWT you get after authentication with Sybml.
YOUR_PHONE_NUMBERA phone number that you want the API to connect to. Be sure to include the country code.
EMAIL_ADDRESSThe email address you wish to send the summary email to.

View on Github

Getting started#

In order to get started using this API, you need to sign up for the Symbl Developer Platform and receive your API credentials.

For this example you will be using Node.js and the Symbl Javascript SDK. You can install this using the Node Package Manager:

npm install symbl-node

You can then use the library within your project like this:

const {sdk} = require('symbl-node')

Initliaze the SDK:

await sdk.init({
appId: APP_ID,
appSecret: APP_SECRET,
basePath: 'https://api.symbl.ai',
});

Open up the connection and pass the configuration options:

const connection = await sdk.startEndpoint({
endpoint: {
type: 'pstn',
phoneNumber: YOUR_PHONE_NUMBER,
},
insightTypes: ['action_item', 'question'],
actions: [
{
invokeOn: 'stop',
name: 'sendSummaryEmail',
parameters: {
emails: [SUMMARY_EMAIL], // Add valid email addresses to received email
},
},
],
data: {
session: {
name: 'My Test Meeting',
},
},
});

You'll notice various configuration options available such as endpoint, insightTypes, and actions.

Endpoints#

This example uses a PSTN connection but you can also connect via SIP:

endpoint: {
dtmf: DTMF_MEETING_CODE,
type: 'sip',
uri: 'sip:124@domain.com'
}

Insight Types#

Symbl provide various insights from the call. Main insights categories are question and action_item. In order to include insights in processing, you need to specify them in configuration like so:

{
insightTypes: ['action_item', 'question']
}

Actions#

You can specify different actions to happen during the call. you will define just one, which defines an email which Symbl will use to send a summary email of the conversation to.

actions: [
{
invokeOn: 'stop',
name: 'sendSummaryEmail',
parameters: {
emails: [SUMMARY_EMAIL] // Add valid email addresses to received email
}
}
]

Getting the Connection ID#

For subscribing to the data, we will need to use connectionId unique to each active connection. to get it you can simply retrieve it from connection response:

const connectionId = connection.connectionId

Realtime insights#

For subscribing to the data, you will need to use connectionId unique to each active connection. to get it you can simply retrieve it from connection response:

const connectionId = connection.connectionId;

After you have the connection ID you can use that to subscribe to our connection:

sdk.subscribeToConnection(connectionId, (data) => {});

data is an object with a type field. Supported types are transcript_response, insight_response and message_response.

For real time trasncription you want to check for transcript_response.

if (type === 'transcript_response') {
const {payload} = data;
process.stdout.write('Live: ' + payload && payload.content + '\r');
}

Transcripts are changing all the time, but once they are processed into reasonable message and not just words, you will get a message_response which you will want to handle:

if (type === 'message_response') {
const {messages} = data;
messages.forEach((message) => {
process.stdout.write('Message: ' + message.payload.content + '\n');
})
}

And finally if there will be any question or action item during conversation, you will get insight_response:

if (type === 'insight_response') {
const {insights} = data;
insights.forEach((insight) => {
process.stdout.write(`Insight: ${insight.type} - ${insight.text} \n\n`);
})
}

Speaker separization#

We can send different speaker events to our connection indicating that different speakers started speaking. That will give us more personalised insights and get better meeting summary

In our example we will do it by calling helper getScheduleEvent function, that we will review in a bit. We pass SpeakerEvent type to it by using SpeakerEvent.types enum from symbl-node, passing user data and timestamp:

const scheduleEvent = getScheduleEvent(sdk, connectionId)
setTimeout(() => {
// Schedule all the events to be sent.
scheduleEvent(SpeakerEvent.types.startedSpeaking, users.john, 0)
scheduleEvent(SpeakerEvent.types.stoppedSpeaking, users.john, 5)
}, 1000)

We retrieve users just from the global array of users but in real world example that might be users data retrieved from database:

const users = {
john: {
userId: 'john@example.com',
name: 'John'
},
mary: {
userId: 'mary@example.com',
name: 'Mary'
}
}

In order to push event to our connection we will create an event like so:

const speakerEvent = new SpeakerEvent({
type: eventType,
user
});
speakerEvent.timestamp = new Date().toISOString();

And push it using pushEventOnConnection function provided by SDK:

sdk.pushEventOnConnection(connectionId, speakerEvent.toJSON(), (err) => {
if (err) {
console.error('Error during push event.', err);
} else {
console.log('Event pushed!');
}
});

This example just touches the surface of what you can do with our Streaming API. If you would like to learn more about it you can visit the Streaming API documentation.