mirror of
https://github.com/jambonz/next-static-site.git
synced 2026-01-25 02:08:03 +00:00
Feature/0.7.6 dh (#44)
* reset yarn lock * ws docs * answering machine detection spec * amd updates * 0.7.6 release notes and articles * update transcribe options Co-authored-by: kitajchuk <bk@kitajchuk.com>
This commit is contained in:
@@ -66,6 +66,9 @@ navi:
|
||||
-
|
||||
path: sip-decline
|
||||
title: sip:decline
|
||||
-
|
||||
path: sip-request
|
||||
title: sip:request
|
||||
-
|
||||
path: sip-refer
|
||||
title: sip:refer
|
||||
@@ -82,6 +85,40 @@ navi:
|
||||
-
|
||||
path: overview
|
||||
title: Overview
|
||||
-
|
||||
path: ws
|
||||
title: Websocket API
|
||||
pages:
|
||||
-
|
||||
path: overview
|
||||
title: Overview
|
||||
-
|
||||
path: session-new
|
||||
title: session:new
|
||||
-
|
||||
path: session-redirect
|
||||
title: session:redirect
|
||||
-
|
||||
path: session-reconnect
|
||||
title: session:reconnect
|
||||
-
|
||||
path: call-status
|
||||
title: call:status
|
||||
-
|
||||
path: verb-hook
|
||||
title: verb:hook
|
||||
-
|
||||
path: verb-status
|
||||
title: verb:status
|
||||
-
|
||||
path: jambonz-error
|
||||
title: jambonz:error
|
||||
-
|
||||
path: ack
|
||||
title: ack
|
||||
-
|
||||
path: command
|
||||
title: command
|
||||
-
|
||||
path: client-sdks
|
||||
title: Client SDKs
|
||||
@@ -115,6 +152,9 @@ navi:
|
||||
path: release-notes
|
||||
title: Release Notes
|
||||
pages:
|
||||
-
|
||||
path: v0.7.6
|
||||
title: v0.7.6
|
||||
-
|
||||
path: v0.7.5
|
||||
title: v0.7.5
|
||||
|
||||
44
markdown/docs/release-notes/v0.7.6.md
Normal file
44
markdown/docs/release-notes/v0.7.6.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Release v0.7.6
|
||||
> Release Date: Aug 26, 2022
|
||||
|
||||
#### New Features
|
||||
- Added support for [call recording](/docs/supporting-articles/siprec-client) via SIPREC (i.e. SIPREC client capability)
|
||||
- Added support for [agent assist](/docs/supporting-articles/siprec-server) scenarios using (i.e. SIPREC server capability)
|
||||
- Added support for [answering machine detection](/docs/supporting-articles/answering-machine-detection)
|
||||
- Added support for [continuous ASR](/docs/supporting-articles/continuous-asr)
|
||||
- Added support for sip:request verb, used to send SIP INFO/NOTIFY/MESSAGE during call
|
||||
- Added option to send DTMF events over [listen](/docs/webhooks/listen) socket
|
||||
- Accept DTMF via SIP INFO from webrtc clients and transcode into RFC 2833
|
||||
- Play verb can accept either a single URL or array of URLs
|
||||
- Support for custom headers in outbound REFER requests
|
||||
- Switch to faster [undici](https://undici.nodejs.org/#/) http client for webhooks
|
||||
- Alternate languages can now be set at the session level via [config](/docs/webhooks/config) verb.
|
||||
- createCall REST API can specify speech settings for TTS and STT
|
||||
- Update to Azure speech SDK 1.23.0
|
||||
- Update to drachtio server 0.8.18
|
||||
- Update to rtpengine mr10.5.1.3
|
||||
|
||||
#### Bug fixes
|
||||
- Enqueue waitHook was not working
|
||||
- Dial verb not ending when call no answer timeout exceeded
|
||||
- Fix dockerfile security issues
|
||||
- Hold music was being fetched when conference member removed from hold
|
||||
- Sending partial transcripts from gather was causing error
|
||||
- When bargein is disabled, kill the background gather and do not restart it
|
||||
- Aws region was not being passed to aws tts or stt
|
||||
- Add alert for jambonz parsing failure
|
||||
- Enforce min bargein word count even when we get final transcript
|
||||
- Add slight delay when releasing media after call answer, to allow A leg ACK transaction to complete on SBC
|
||||
- When releasing media, use asymetric flag so that rtpengine does react to a spurious final packet from freeswitch by incorrectly sending rtp there
|
||||
- Adding custom headers to REFER caused preferred hostname on Refer-To to be lost
|
||||
- MS Teams warm transfer (invite w/replaces) was broken
|
||||
- Increment sdp version on SIPREC reinvite
|
||||
- When releasing media anchor from FS, if we are using SRTP on A leg we need to reinvite
|
||||
- Make rtpengine transcode if non-preferred codec is selected by far end on outdial
|
||||
- When rtpengine restarted it did not come up gracefully
|
||||
|
||||
#### Availability
|
||||
- Available shortly on <a href="https://aws.amazon.com/marketplace/pp/prodview-55wp45fowbovo" target="_blank" >AWS Marketplace</a>
|
||||
- Deploy to Kubernetes using [this Helm chart](https://github.com/jambonz/helm-charts)
|
||||
|
||||
**Questions?** Contact us at <a href="mailto:support@jambonz.org">support@jambonz.org</a>
|
||||
120
markdown/docs/supporting-articles/answering-machine-detection.md
Normal file
120
markdown/docs/supporting-articles/answering-machine-detection.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Answering machine detection
|
||||
|
||||
The answering machine detection feature can be enabled on outbound calls to provide an indication of whether a call has been answered by a person or a machine. This is done by providing an `amd` property in a `dial` verb as shown in the simple example below:
|
||||
|
||||
```json
|
||||
{
|
||||
"verb": "dial",
|
||||
"actionHook": "/outdial",
|
||||
"callerId": "+16173331212",
|
||||
"target": [
|
||||
{
|
||||
"type": "phone",
|
||||
"number": "+15083084809",
|
||||
"trunk": "Twilio"
|
||||
}
|
||||
],
|
||||
"amd": {
|
||||
"hook": "/amdEvents"
|
||||
}
|
||||
}
|
||||
```
|
||||
In this example, when the dialed call is answered the answering machine detection feature will begin listening on the outbound call leg and after a short period of time will send a webhook to '/amdEvents' with an indication of whether a human or a machine has answered the call.
|
||||
|
||||
The payload in the webhook will look something like this:
|
||||
```json
|
||||
{"type":"amd_human_detected"}
|
||||
```
|
||||
or
|
||||
```json
|
||||
{"type":"amd_machine_detected","reason":"hint","hint":"call has been forwarded","language":"en-us"}
|
||||
```
|
||||
|
||||
If no speech is detected at all from the far end, the payload will look like this:
|
||||
```json
|
||||
{"type":"amd_no_speech_detected"}
|
||||
```
|
||||
|
||||
And, finally, if the answering machine detection feature is unable to determine whether the remote party is a machine or human it will return
|
||||
```json
|
||||
{"type":"amd_decision_timeout"}
|
||||
```
|
||||
|
||||
The application receiving the webhook can return a new jambonz payload of verbs. For instance, say you had an outbound dialer application in which if you connect to a person you want to deliver a message, but if you connect to someone's voicemail you simply want to hang up. In that case, your app can respond to the webhook with a simple [hangup](/docs/webhooks/hangup) verb if you receive an event payload indicating a machine has answered.
|
||||
|
||||
## How it works
|
||||
|
||||
### Length of greeting
|
||||
The answering machine detection feature leverages the fact that voicemail greetings are typically quite a bit more lengthy than a human's greeting. When the call is answered, speech recognition is used to determine the length of the greeting and if it is shorter than a (configurable) threshold, it is determined to be human; if longer then it is determined to be a machine.
|
||||
|
||||
### Key Voicemail phrases
|
||||
Optionally, the feature can also given a list of common phrases that one might hear on a voicemail greeting. If any of the phrases are detected then the determination is immediately made that this is a machine. These phrases are supplied via an external file, so they can be easily updated as needed for a specific deployment. As example, here are sample phrases that might be used for an english language greeting:
|
||||
|
||||
```json
|
||||
{
|
||||
"en-US": [
|
||||
"call has been forwarded",
|
||||
"at the beep",
|
||||
"at the tone",
|
||||
"leave a message",
|
||||
"leave me a message",
|
||||
"not available right now",
|
||||
"not available to take your call",
|
||||
"can't take your call",
|
||||
"I will get back to you",
|
||||
"I'll get back to you",
|
||||
"we will get back to you",
|
||||
"we are unable",
|
||||
"we are not available"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Beep detection
|
||||
The feature also attempts to detect audio tones, or beeps that are commonly used on voicemail systems. If detected, an event is sent via the actionHookf to the webapp.
|
||||
|
||||
### Determining when to leave a voicemail
|
||||
For an application that wishes to leave a message on a voicemail system, it is necessary to know when the voicemail greeting has completed and the voicemail system is now ready to record the message. If the feature determines that the remote party is a machine, it will continue listening to the greeting until it completes and then send an event via the `actionHook` to the application. This can be used as a cue to let the application know that it is time to start leaving the message.
|
||||
|
||||
## Events
|
||||
The payload that is included in the `actionHook` will always contain a `type` property describing the event type. Some event types may also include additional properties. These are described in the table below.
|
||||
|
||||
|type|meaning|additional properties|
|
||||
|----|-------|---------------------|
|
||||
|amd_human_detected|a human is speaking|{reason, greeting, language}<br> reason is 'short greeting', <br>greeting is the recognized greeting and <br>language is the recognized language|
|
||||
|amd_machine_detected|a machine is speaking|{reason, hint, transcript, language}<br> reason is 'hint' or 'long greeting', <br>hint is the recognized hint<br>transcript is the recognized greeting and <br>language is the recognized language|
|
||||
|amd_no_speech_detected|no speech was detected|none|
|
||||
|amd_decision_timeout|no decision was able to be made in the time given|none|
|
||||
|amd_machine_stopped_speaking|machine has completed the greeting|none|
|
||||
|amd_tone_detected|a beep was detected|none|
|
||||
|amd_error|an error has occurred|error - an error message|
|
||||
|amd_stopped|answering machine detection was stopped|none|
|
||||
|
||||
It is possible to receive more than one event for a single call. For instance, a possible sequence of events on a call to an answering machine is:
|
||||
|
||||
1. amd_machine_detected, then
|
||||
1. amd_tone_detected, then
|
||||
1. amd_machine_stopped_speaking
|
||||
|
||||
## Configuration
|
||||
|
||||
The full set of configuration parameters is shown below.
|
||||
|
||||
|property|meaning|required?|
|
||||
|--------|-------|---------|
|
||||
|actionHook|webhook to send amd events|yes|
|
||||
|thresholdWordCount|number of spoken words in a greeting that result in an amd_machine_detected result|no, default=9|
|
||||
|recognizer|speech recognition parameters, used as per [gather](/docs/webhooks/gather) and [transcribe](/docs/webhooks/transcribe)|no, default=app defaults|
|
||||
|timers|object containing various timeouts|no|
|
||||
|timers.noSpeechTimeoutMs|time in milliseconds to wait for speech before returning amd_no_speech_detected|no, default=5000|
|
||||
|timers.decisionTimeoutMs|time in milliseconds to wait before returning amd_decision_timeout|no, default=15000|
|
||||
|timers.toneTimeoutMs|time in milliseconds to wait to hear a tone|no, default=20000|
|
||||
|timers.greetingCompletionTimeoutMs|silence in milliseconds to wait for during greeting before returning amd_machine_stopped_speaking|no, default=2000|
|
||||
|
||||
### Voicemail phrases
|
||||
|
||||
If desired, a JSON file of voicemail phrases, organized by language as shown above can be supplied. If provided, the environment variable `VMD_HINTS_FILE` should point to the file path to this file.
|
||||
|
||||
## Answering machine detection on inbound calls
|
||||
|
||||
Answering machine detection can also be performed on an inbound leg by adding an `amd` property to a [config](/docs/webhooks/config) verb. While it is less common to need to do answering machine detection on an inbound leg, this can be useful when jambonz is behind a dialer that has placed the outbound call and then connected it to jambonz by sending an INVITE to jambonz.
|
||||
9
markdown/docs/supporting-articles/continuous-asr.md
Normal file
9
markdown/docs/supporting-articles/continuous-asr.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Continous ASR
|
||||
Continuous ASR (automatic speech recognition) is a feature that allows the speech-to-text (STT) recognition to be tuned for the collection of things like phone numbers, customer identifiers and other strings of digits or characters which when spoken are often spoken with pauses in between utterances.
|
||||
|
||||
As an example, consider someone speaking a customer pin of 5 digits. It might be common for them to pause while speaking, as they struggle to remember the full digit sequence. They might say, for instance, "four eight two ....pause.....five nine". In this situation, normal STT will be triggered by the pause to return "482" as the full utterance. In a case where the jambonz application is submitting the user input to an AI bot, the input will be invalid.
|
||||
|
||||
Continuous ASR applies to the [gather]() verb and provides the ability to specify some additional options that help ensure the collection of the full customer pin in the example above. Two additional options are provided:
|
||||
|
||||
- `asrTimeout`: this is a duration of silence, in seconds, to wait after a transcript is received from the STT vendor before returning the result. If another transcript is received before this timeout elapses, then the transcripts are combined and recognition continues. The combined transcripts are returned once a timeout between utterances exceeds this value or a specified dtmf termination key is detected (see below)
|
||||
- `asrDtmfTerminationDigit`: a DTMF key which, if entered, will also terminate the gather operation and immediately return the collected results.
|
||||
24
markdown/docs/supporting-articles/siprec-client.md
Normal file
24
markdown/docs/supporting-articles/siprec-client.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Call Recording using SIPREC
|
||||
|
||||
jambonz can integrate with external recording platforms using [SIPREC](https://datatracker.ietf.org/doc/html/draft-ietf-siprec-protocol). In this scenario, jambonz acts as a SIPREC client and forks the audio streams to send to a configured SIPREC server.
|
||||
|
||||
This feature is enabled via the [config](/docs/webhooks/config) verb using the `record` property. This property can be used to start, stop, pause or resume the recording.
|
||||
|
||||
```json
|
||||
{
|
||||
"verb": "config",
|
||||
"record": {
|
||||
"action": "startCallRecording",
|
||||
"siprecServerURL": "sip:srs@recording.example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The available properties are as follows:
|
||||
|
||||
| option | description | required |
|
||||
| ------------- |-------------| -----|
|
||||
|action|"startCallRecording", "stopCallRecording", "pauseCallRecording", or "resumeCallRecording"|yes|
|
||||
|siprecServerURL|sip uri for SIPREC server|required if action is "startCallRecording"|
|
||||
|recordingID|user-supplied string to identify the recording|no|
|
||||
|
||||
16
markdown/docs/supporting-articles/siprec-server.md
Normal file
16
markdown/docs/supporting-articles/siprec-server.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Agent Assist via SIPREC
|
||||
|
||||
jambonz can integrate with session border controllers (SBCs) that support SIPREC to receive listen-only audio streams of callers and agents in Contact Centre scenarios in order to provide agent assist type of functionality.
|
||||
|
||||
In this scenario, jambonz acts as a SIPREC server and receives incoming audio streams signaled in the SIPREC INVITE from the SBC. These audio streams can then be handled by a jambonz application, which can transcribe the audio as well as send it to 3rd parties via the [listen](/docs/webhooks/listen) verb.
|
||||
|
||||
Because these are listen-only audio streams, the application is limited in what it can do. It can not, for instance, play audio or say text back to the caller. In fact, the only verbs allowed in a jambonz application that is handling an incoming SIPREC call are:
|
||||
- [config](/docs/webhooks/config)
|
||||
- [gather](/docs/webhooks/gather)
|
||||
- [transcribe](/docs/webhooks/transcribe)
|
||||
- [listen](/docs/webhooks/listen)
|
||||
|
||||
Any other verbs present in the application will be removed and silently ignored.
|
||||
|
||||
## Routing SIPREC calls
|
||||
SIPREC calls are routed at the account level; that is to say that you must configure a webhook application for each account that will handle incoming SIPREC calls for that account. This can be done via the portal on the Edit Account page, or via the API.
|
||||
@@ -29,8 +29,8 @@ You can use the following attributes in the `config` command:
|
||||
| ------------- |-------------| -----|
|
||||
| synthesizer | change the session-level default text-to-speech settings. See [the say verb](/docs/webhooks/say) for details on the `synthesizer` property.| no |
|
||||
| recognizer | change the session-level default speech recognition settings. See [the transcribe verb](/docs/webhooks/transcribe) for details on the `recognizer` property.| no |
|
||||
| bargeIn.enable| if true, begin listening for speech or dtmf input while the session is executing other verbs. This is known as a "background gather" and an application to capture user input outside of a [gather verb](/docs/webhooks/gather). If false, stop any background listening task that is in progress| no|
|
||||
|bargein|this object contains properties that are used to instantiate a 'background' [gather verb](/docs/webhooks/gather)|no|
|
||||
| bargeIn.enable| if true, begin listening for speech or dtmf input while the session is executing other verbs. This is known as a "background gather" and an application to capture user input outside of a [gather verb](/docs/webhooks/gather). If false, stop any background listening task that is in progress| no|
|
||||
| bargeIn.actionHook | A webhook to call if user input is collected from the background gather.| no |
|
||||
| bargeIn.input |Array, specifying allowed types of input: ['digits'], ['speech'], or ['digits', 'speech']. | yes |
|
||||
| bargeIn.finishOnKey | Dmtf key that signals the end of dtmf input | no |
|
||||
@@ -38,6 +38,12 @@ You can use the following attributes in the `config` command:
|
||||
| bargeIn.minDigits | Minimum number of dtmf digits expected to gather. Defaults to 1. | no |
|
||||
| bargeIn.maxDigits | Maximum number of dtmf digits expected to gather | no |
|
||||
| bargeIn.interDigitTimeout | Amount of time to wait between digits after minDigits have been entered.| no |
|
||||
|amd|enable answering machine detection; see [answering machine detection](/docs/supporting-articles/answering-machine-detection) for details|no|
|
||||
|record|options to manage [call recording using SIPREC](/docs/supporting-articles/siprec-client)|no|
|
||||
|record.action|"startCallRecording", "stopCallRecording", "pauseCallRecording", or "resumeCallRecording"|yes|
|
||||
|record.siprecServerURL|sip uri for SIPREC server|required if action is "startCallRecording"|
|
||||
|record.recordingID|user-supplied string to identify the recording|no|
|
||||
|
||||
|
||||
|
||||
<p class="flex">
|
||||
|
||||
@@ -12,6 +12,11 @@ The `dial` verb is used to create a new call by dialing out to a telephone numbe
|
||||
"url": "/dtmf",
|
||||
"method": "GET"
|
||||
},
|
||||
"amd": {
|
||||
"hook": "/answeringMachineDetection",
|
||||
"disconnectOnAMD": true,
|
||||
|
||||
}
|
||||
"target": [
|
||||
{
|
||||
"type": "phone",
|
||||
@@ -49,6 +54,7 @@ You can use the following attributes in the `dial` command:
|
||||
| option | description | required |
|
||||
| ------------- |-------------| -----|
|
||||
| actionHook | webhook to invoke when the call ends. The webhook will include [properties](#dial-action-properties) describing the outcome of the call attempt.| no |
|
||||
|amd|enable answering machine detection; see [answering machine detection](/docs/supporting-articles/answering-machine-detection) for details|no|
|
||||
| answerOnBridge | If set to true, the inbound call will ring until the number that was dialed answers the call, and at that point a 200 OK will be sent on the inbound leg. If false, the inbound call will be answered immediately as the outbound call is placed. <br/>Defaults to false. | no |
|
||||
| callerId | The inbound caller's phone number, which is displayed to the number that was dialed. The caller ID must be a valid E.164 number. <br/>Defaults to caller id on inbound call. | no |
|
||||
| confirmHook | webhook for an application to run on the callee's end after the dialed number answers but before the call is connected. This allows the caller to provide information to the dialed number, giving them the opportunity to decline the call, before they answer the call. Note that if you want to run different applications on specific destinations, you can specify the 'url' property on the nested [target](#target-types) object. | no |
|
||||
@@ -121,6 +127,15 @@ The actionHook that is invoked when the dial command ends will include the follo
|
||||
| dial_status | the final status of the call attempt, one of 'completed', 'failed', 'busy', 'no-answer', or 'queued'|
|
||||
| dial_sip_status | the sip status of the final response to the INVITE that was sent|
|
||||
|
||||
<h5 id="dial-amd-properties">amd.hook properties</h5>
|
||||
|
||||
The webhook that is invoked when amd property is included and jambonz has either determined the type of called party (human or machine) or has detected a tone or beep.
|
||||
|
||||
| property name | description |
|
||||
| ------------- |-------------|
|
||||
| event | one of 'amd', 'beep', or 'silence' |
|
||||
| amd_type| 'human' or 'machine', only provided when event = 'amd'|
|
||||
|
||||
|
||||
<p class="flex">
|
||||
<a href="/docs/webhooks/dequeue">Prev: dequeue</a>
|
||||
|
||||
@@ -63,6 +63,8 @@ You can use the following options in the `gather` command:
|
||||
| recognizer.requestSnr | (microsoft only) Request signal to noise information| no |
|
||||
| recognizer.initialSpeechTimeoutMs | (microsoft only) Initial speech timeout in milliseconds| no |
|
||||
| recognizer.azureServiceEndpoint | (microsoft only) URI of a custom speech endpoint to connect to| no |
|
||||
| recognizer.asrTimeout|timeout value for [continuous ASR feature](/docs/supporting-articles/continuous-asr)| no |
|
||||
| recognizer.asrDtmfTerminationDigit|DMTF key that terminates [continuous ASR feature](/docs/supporting-articles/continuous-asr)| no |
|
||||
| say | nested [say](#say) Command that can be used to prompt the user | no |
|
||||
| timeout | The number of seconds of silence or inaction that denote the end of caller input. The timeout timer will begin after any nested play or say command completes. Defaults to 5 | no |
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ You can use the following options in the `listen` action:
|
||||
| maxLength | the maximum length of the listened audio stream, in secs | no |
|
||||
| metadata | arbitrary data to add to the JSON payload sent to the remote server when websocket connection is first connected | no |
|
||||
| mixType | "mono" (send single channel), "stereo" (send dual channel of both calls in a bridge), or "mixed" (send audio from both calls in a bridge in a single mixed audio stream) Default: mono | no |
|
||||
| passDtmf | if true, any dtmf digits detected from the caller will be passed over the websocket as text frames in JSON format. Default: false| no |
|
||||
| playBeep | true, false whether to play a beep at the start of the listen operation. Default: false | no |
|
||||
| sampleRate | sample rate of audio to send (allowable values: 8000, 16000, 24000, 48000, or 64000). Default: 8000 | no |
|
||||
| timeout | the number of seconds of silence that terminates the listen operation.| no |
|
||||
@@ -41,6 +42,18 @@ You can use the following options in the `listen` action:
|
||||
| wsAuth.username | HTTP basic auth username to use on websocket connection | no |
|
||||
| wsAuth.password | HTTP basic auth password to use on websocket connection | no |
|
||||
|
||||
<h4 id="pass_dtmf">Passing DTMF</h4>
|
||||
|
||||
Any DTMF digits entered by the far end party on the call can optionally be passed to the websocket server as JSON text frames by setting the `passDtmf` property to `true`. Each DTMF entry is reported separately in a payload that contains the specific DTMF key that was entered, as well as the duration which is reported in RTP timestamp units. The payload that is sent will look like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "dtmf",
|
||||
"dtmf": "2",
|
||||
"duration": "1600"
|
||||
}
|
||||
```
|
||||
|
||||
<h4 id="birectional_audio">Bidirectional audio</h4>
|
||||
|
||||
Audio can also be sent back over the websocket to jambonz. This audio, if supplied, will be played out to the caller. (Note: Bidirectional audio is not supported when the `listen` is nested in the context of a `dial` verb).
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Webhooks
|
||||
|
||||
jambonz uses JSON payloads that are exchanged in HTTP messages to control calls.
|
||||
jambonz controls calls through the use of JSON payloads that are exchanged either over an HTTP(s) or a websocket connection. When an incoming call for your account is received, jambonz retrieves the URL that you have configured for the application you want to run. If the URL begins with 'http(s)://' jambonz makes an http request to the URL, while if the URL starts with 'ws(s)://' jambonz establishes a websocket connection to that URL. jambonz then sends an initial message describing the incoming call, and your webapp is then responsible for returning a JSON payload that indicates how you want the call handled.
|
||||
|
||||
|
||||
Either way (http or websocket) the details of the JSON payloads are the same. The information below pertains to using HTTP connections; for information describing the websocket interface [see here](/docs/ws/overview).
|
||||
|
||||
When an incoming call for your account is received, jambonz makes an HTTP request to a URL that you have configured and your webapp will then return a response containing a JSON body that indicates how you want the call handled.
|
||||
|
||||
|
||||
@@ -42,5 +42,5 @@ The *eventHook* webhook will contain two parameters: `event` and `call_status`.
|
||||
|
||||
<p class="flex">
|
||||
<a href="/docs/webhooks/sip-decline">Prev: sip:decline</a>
|
||||
<a href="/docs/webhooks/tag">Next: tag</a>
|
||||
<a href="/docs/webhooks/sip-request">Next: sip:refer</a>
|
||||
</p>
|
||||
|
||||
35
markdown/docs/webhooks/sip-request.md
Normal file
35
markdown/docs/webhooks/sip-request.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# sip:request
|
||||
> Added in v0.7.6
|
||||
|
||||
The sip:request action is used to send a SIP INFO, NOTIFY, or MESSAGE request on an established call leg, i.e. an in-dialog request. This allows an application to send arbitrary SIP messages during a call; e.g. to transmit metadata to the calling sip endpoint using a SIP INFO message.
|
||||
|
||||
```json
|
||||
{
|
||||
"verb": "sip:request",
|
||||
"method": "INFO",
|
||||
"headers": {
|
||||
"X-Metadata": "my sip metadata"
|
||||
}
|
||||
"actionHook": "/info"
|
||||
}
|
||||
```
|
||||
|
||||
You can use the following options in the `sip:request` action:
|
||||
|
||||
| option | description | required |
|
||||
| ------------- |-------------| -----|
|
||||
| method |SIP method, should be one of INFO, MESSAGE, or NOTIFY| yes |
|
||||
| headers | an object containing headers (key-value) to include with the SIP request | no |
|
||||
| body | the body of the SIP request, if any | no |
|
||||
| actionHook | a webhook to call when the sip request has completed | no |
|
||||
|
||||
The sip:request verb completes when a response is received from the far end. The actionHook provides the status code of the sip response:
|
||||
|
||||
- `result`: 'success' or 'failed'
|
||||
- `sipStatus`: sip status code of response
|
||||
- `err`: error message, in the case of failure
|
||||
|
||||
<p class="flex">
|
||||
<a href="/docs/webhooks/sip-refer">Prev: sip:refer</a>
|
||||
<a href="/docs/webhooks/tag">Next: tag</a>
|
||||
</p>
|
||||
@@ -27,7 +27,7 @@ You can use the following options in the `transcribe` command:
|
||||
| recognizer.vad.voiceMs|If vad is enabled, the number of milliseconds of speech required before connecting to cloud recognizer|no|
|
||||
| recognizer.vad.mode|If vad is enabled, this setting governs the sensitivity of the voice activity detector; value must be between 0 to 3 inclusive, lower numbers mean more sensitive|no|
|
||||
| recognizer.separateRecognitionPerChannel | If true, recognize both caller and called party speech | no |
|
||||
| recognizer.altLanguages |(google only) An array of alternative languages that the speaker may be using | no |
|
||||
| recognizer.altLanguages |(google/microsoft only) An array of alternative languages that the speaker may be using | no |
|
||||
| recognizer.punctuation |(google only) Enable automatic punctuation | no |
|
||||
| recognizer.enhancedModel |(google only) Use enhanced model | no |
|
||||
| recognizer.words |(google only) Enable word offsets | no |
|
||||
@@ -37,6 +37,7 @@ You can use the following options in the `transcribe` command:
|
||||
| recognizer.interactionType |(google only) Set the interaction type: discussion, presentation, phone_call, voicemail, professionally_produced, voice_search, voice_command, dictation | no |
|
||||
| recognizer.naicsCode |(google only) set an industry [NAICS](https://www.census.gov/naics/?58967?yearbck=2022) code that is relevant to the speech | no |
|
||||
| recognizer.hints | (google and microsoft only) Array of words or phrases to assist speech detection | no |
|
||||
| recognizer.hintsBoost | (google only) Number indicating the strength to assign to the configured hints | no |
|
||||
| recognizer.profanityFilter | (google only) If true, filter profanity from speech transcription . Default: no| no |
|
||||
| recognizer.vocabularyName | (aws only) The name of a vocabulary to use when processing the speech.| no |
|
||||
| recognizer.vocabularyFilterName | (aws only) The name of a vocabulary filter to use when processing the speech.| no |
|
||||
@@ -46,7 +47,10 @@ You can use the following options in the `transcribe` command:
|
||||
| recognizer.outputFormat | (microsoft only) simple or detailed. Default: simple| no |
|
||||
| recognizer.requestSnr | (microsoft only) Request signal to noise information| no |
|
||||
| recognizer.initialSpeechTimeoutMs | (microsoft only) Initial speech timeout in milliseconds| no |
|
||||
| transcriptionHook | Webhook to receive an HTPP POST when an interim or final transcription is received. | yes |
|
||||
| recognizer.transcriptionHook | Webhook to receive an HTPP POST when an interim or final transcription is received. | yes |
|
||||
| recognizer.asrTimeout|timeout value for [continuous ASR feature](/docs/supporting-articles/continuous-asr)| no |
|
||||
| recognizer.asrDtmfTerminationDigit|DMTF key that terminates [continuous ASR feature](/docs/supporting-articles/continuous-asr)| no |
|
||||
|
||||
|
||||
<p class="flex">
|
||||
<a href="/docs/webhooks/tag">Prev: tag</a>
|
||||
|
||||
30
markdown/docs/ws/ack.md
Normal file
30
markdown/docs/ws/ack.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# ack
|
||||
|
||||
>> websocket server => jambonz
|
||||
|
||||
An `ack` message is sent by the websocket server to jambonz in response to a `session:new` or `verb:hook` message. The ack message may optionally contain a payload of new instructions for jambonz to execute.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "ack"|indicates this is an ack message|yes|
|
||||
|msgid|string|references the message this is in reply to|yes|
|
||||
|data|array|array of jambonz verbs to execute|no|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "ack",
|
||||
"msgid": "1cvh3MNHh1xrJaHmnitqA1",
|
||||
"data": [
|
||||
{
|
||||
"text": "Hi there and welcome!",
|
||||
"verb": "say"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/jambonz-error">Prev: jambonz:error</a>
|
||||
<a href="/docs/ws/command">Next: command</a>
|
||||
</p>
|
||||
53
markdown/docs/ws/call-status.md
Normal file
53
markdown/docs/ws/call-status.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# call:status
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `call:status` message is sent by jambonz to the websocket server any time the call status changes
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "call:status"|indicates this is an error notification from jambonz|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|data|object|current call information|yes|
|
||||
|data.call_status|string|one of 'trying', 'ringing', 'early-media', 'in-progress', 'completed', 'failed', 'no-answer', 'busy', 'queued'|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "call:status",
|
||||
"msgid": "eyvooFN3dRMpZ2ZxdRLvBm",
|
||||
"call_sid": "b5e39996-bd2f-4bda-b928-355147186a2a",
|
||||
"b3": "e72ef0d61bfb3e23c5e50c72496feb2e-6125806ded19bb18-1",
|
||||
"data": {
|
||||
"call_sid": "b5e39996-bd2f-4bda-b928-355147186a2a",
|
||||
"direction": "inbound",
|
||||
"from": "+441173185201",
|
||||
"to": "+441303763875",
|
||||
"call_id": "7ade3efb-7163-123b-e6ba-023fd61c5256",
|
||||
"sip_status": 200,
|
||||
"sip_reason": "OK",
|
||||
"call_status": "completed",
|
||||
"account_sid": "300be250-5a79-46bd-8393-45e7d26c2e34",
|
||||
"trace_id": "654c5323d6f907233a1069136b8a330e",
|
||||
"local_sip_address": "10.0.150.88:5070",
|
||||
"defaults": {
|
||||
"synthesizer": {
|
||||
"vendor": "microsoft",
|
||||
"language": "en-US",
|
||||
"voice": "en-US-JennyNeural"
|
||||
},
|
||||
"recognizer": {
|
||||
"vendor": "microsoft",
|
||||
"language": "en-US"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/session-reconnect">Prev: session:reconnect</a>
|
||||
<a href="/docs/ws/verb-hook">Next: verb:hook</a>
|
||||
</p>
|
||||
50
markdown/docs/ws/command.md
Normal file
50
markdown/docs/ws/command.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# command
|
||||
|
||||
>> websocket server => jambonz
|
||||
|
||||
A `command` message is sent by the websocket server to jambonz when the server wants to asynchronously provide a new set of instructions to jambonz.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "command"|indicates this is a command message|yes|
|
||||
|command|string|describes the action to take, see allowed commands below|yes|
|
||||
|queueCommand|boolean|if true, queue this command until previous commands are completed; otherwise, interrupt and flush all previous commands and execute this command immediately|no|
|
||||
|data|array or object|data pertaining to the requested command|yes|
|
||||
|
||||
The `command` property must be one of the values shown below.
|
||||
> Note: `redirect` is the most commonly-used value.
|
||||
|
||||
|command value|meaning|data requirements|
|
||||
|-------------|-------|-----------------|
|
||||
|redirect|execute the application provided|data must be an array of jambonz verbs; i.e. a jambonz application.|
|
||||
|call:status|change the call status (e.g. hangup the call)|data must include a `call_status` property with a value of 'completed' or 'no-answer'|
|
||||
|mute:status|mute or unmute the call|data must include a `mute_status` property with a value of 'mute' or 'unmute'|
|
||||
|conf:mute-status|mute or unmute all non-moderator conference legs|data must include a `conf_mute_status` property with a value of either 'mute' or 'unmute'|
|
||||
|conf:hold-status|place a conference leg on hold or take off hold|data must include a `conf_hold_status` property with a value of either 'hold' or 'unhold'|
|
||||
|listen:status|Change the status of a listen stream|data must include a `listen_status` property with a value of 'pause' or 'resume'|
|
||||
|whisper|Play a whisper prompt to the caller (i.e only one party hears the prompt)|data must include a `whisper` property that can be an array of say or play verbs|
|
||||
|sip:request|Send a SIP INFO, NOTIFY, or MESSAGE request to the far end party|data must include a 'method' property (allowed values: 'INFO', 'NOTIFY', 'MESSAGE') and can include 'content_type', 'content', and 'headers' properties.|
|
||||
|
||||
|
||||
> Note: In the data payload when `redirect` is used, each jambonz verb in the `data` array may optionally include an `id` property. If present, jambonz will provide `verb:status` notifications when the verb starts and ends execution.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "command",
|
||||
"command": "redirect",
|
||||
"queueCommand": true,
|
||||
"data": [
|
||||
{
|
||||
"say": {
|
||||
"id": "b5e39996",
|
||||
"text": "Hello it's me Mario"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/ack">Prev: ack</a>
|
||||
</p>
|
||||
33
markdown/docs/ws/jambonz-error.md
Normal file
33
markdown/docs/ws/jambonz-error.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# jambonz:error
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `jambonz:error` message is sent by jambonz to the websocket server if jambonz encounters some sort of fatal error (i.e. something that would necessitate ending the call unexpectedly) jambonz will send an error event to the far end app describing the problem.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "jambonz:error"|indicates this is an error notification from jambonz|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|data|object|error details|yes|
|
||||
|data.error|string|error message|yes|
|
||||
|data.verb|string|name of the verb that generated the error|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "jambonz:error",
|
||||
"msgid": "1cvh3MNHh1xrJaHmnitqA1",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"data": {
|
||||
"error": "Speech credentials not found",
|
||||
"verb": "say"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/verb-status">Prev: verb:status</a>
|
||||
<a href="/docs/ws/ack">Next: ack</a>
|
||||
</p>
|
||||
52
markdown/docs/ws/overview.md
Normal file
52
markdown/docs/ws/overview.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Websocket API
|
||||
|
||||
The websocket API is functionally equivalent to the Webhook API; it is simply an alternative way for an application to interact with and drive jambonz call and message processing.
|
||||
|
||||
The reason we created this alternative API is that there are some use cases - primarily those involving a lot of asynchronous interaction with jambonz - that can be done much easier over a single websocket connection than over a combination of HTTP webhooks and REST APIs.
|
||||
|
||||
When you create a jambonz application in the jambonz portal and you want to use the websocket API, simply provide a ws(s) URL for the calling webhook instead of an http(s) URL. The call status webhook can be the same ws(s) URL, in which case your application will get the call status notifications over the same websocket connections.
|
||||
> You can also have call status notifications sent to a completely separate http(s) webhook URL if you prefer.
|
||||
|
||||
The impact of specifying a ws(s) URL as the application calling webhook is that this causes jambonz to establish a websocket connection to that URL when an incoming call (or outbound call) is routed to the jambonz application, and then communicate with your application over that websocket connection.
|
||||
|
||||
## Connection management
|
||||
|
||||
The websocket connection will be established by jambonz to the specified websocket URL, The websocket subprotocol used shall be “ws.jambonz.org”. If jambonz fails to connect to the provided URL, there will be no retry and the call shall be rejected.
|
||||
|
||||
Once connected, jambonz will send an initial JSON text message to the your server with the same parameters as are provided in the webhook call. The full message set is described below, but for now we can simply say that:
|
||||
- Only text frames are ever sent over the websocket connections; i.e. no binary frames.
|
||||
- All text frames contain JSON-formatted data.
|
||||
- The information content sent from jambonz to the your server is exactly the same content as that supplied via http webhooks.
|
||||
|
||||
The websocket should generally be closed only from the jambonz side, which happens when the call is ended. If the your server closes the socket, jambonz will attempt to reconnect, up to a configurable number of reconnection attempts. Upon reconnecting, jambonz will send an initial reconnect message containing only the callSid of the session. It is up to the your server to maintain the state of the application between reconnections for the same call.
|
||||
|
||||
## Message format
|
||||
|
||||
As mentioned above, all messages will be JSON payloads sent as text frames. The following top-level properties will be commonly included:
|
||||
- *type*: all messages **must** have a type property.
|
||||
- Messages from jambonz to the your server will have the following types: [`session:new`, `session:reconnect`, `verb:hook`, `call:status`, `error`].
|
||||
- Messages from the your server to jambonz will have the following types: [`ack`, `command`].
|
||||
- *msgid*: every message sent from jambonz will include a unique message identifier. Messages from the your server application that are responses to jambonz messages (`ack`) **must** include the msgId that they are acknowledging.
|
||||
|
||||
Note that not all messages sent by jambonz need to be acknowledged. The message types which **must** be acknowledged are the `session:new`, and `verb:hook` messages.
|
||||
|
||||
## Message types
|
||||
In the sections that follow, we will describe each of the message types in detail. The table below provides summary information.
|
||||
|
||||
|message type|sent by|usage|
|
||||
|---|---|---|
|
||||
|session:new|jambonz|sent when a new call arrives (or an outbound call generated via the REST API has been answered). This is analogous to the initial webhook sent by jambonz to gather an initial set of instructions for the call.|
|
||||
|session:redirect|jambonz|sent when live call control has been used to retrieve a new application for either the parent or child call leg.|
|
||||
|session:reconnect|jambonz|sent when the websocket connection was closed unexpectedly by the websocket server and jambonz has successfully reconnected.|
|
||||
|call:status|jambonz|sent any time the call status changes.|
|
||||
|verb:hook|jambonz| sent when an action hook or event hook configured for a verb has been triggered (e.g. a “gather” verb has collected an utterance from the user).|
|
||||
|verb:status|jambonz|sent when a verb has just started or completed executing. See “command” below; this message is only sent if the app includes “id” properties on the verbs provided.|
|
||||
|jambonz:error|jambonz| if jambonz encounters some sort of fatal error (i.e. something that would necessitate ending the call unexpectedly) jambonz will send an error event to the far end app describing the problem.|
|
||||
|ack|websocket server|the ws server will respond to any `session:new` or `verb:hook` message with an `ack` message indicating that the provided content in the message has been processed. The ack message may optionally contain a payload of new instructions for jambonz.|
|
||||
|command|websocket server|the ws server will send this message when it wants to asynchronously provide a new set of instructions to jambonz. The app **may** include an `id` property in each of the verbs included in the command; if so, jambonz will send `verb:status` notifications back to the app when the verb is executed. The `id` property is a string value that is assigned by the app and is meaningful only to the app (i.e. to jambonz it is simply an opaque piece of tracking data).|
|
||||
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/session-new">Next: session:new</a>
|
||||
</p>
|
||||
77
markdown/docs/ws/session-new.md
Normal file
77
markdown/docs/ws/session-new.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# session:new
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `session:new` message is sent by jambonz to the websocket server when a new call arrives (or an outbound call generated via the REST API has been answered). This is analogous to the initial webhook sent by jambonz to gather an initial set of instructions for the call when using the HTTP-based webhook API.
|
||||
|
||||
The websocket server must reply reply to a `session:new` message with an [ack](/docs/ws/ack) response message containing the the jambonz verbs to execute for this call. If an `ack` message is not received within 5 seconds of sending the `session:new` jambonz will hang up the call.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|yes|
|
||||
|data|object|JSON payload describing the call|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "session:new",
|
||||
"msgid": "auuHioXGktYh2ZFYxf3hAA",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"data": {
|
||||
"sip": {
|
||||
"headers": {
|
||||
"via": "SIP/2.0/UDP 3.212.205.202;rport=5060;branch=z9hG4bK3tv053jp1mcHQ;received=10.0.13.72",
|
||||
"max-forwards": "70",
|
||||
"from": "<sip:+15083084809@3.212.205.202:5060>;tag=9mgyBeaUy4H2S",
|
||||
"to": "<sip:+15083728299@3.212.205.202>",
|
||||
"call-id": "d8907723-0bc7-123b-09b5-12e962f3039b",
|
||||
"cseq": "48063641 INVITE",
|
||||
"contact": "<sip:10.0.13.72:5060>",
|
||||
"user-agent": "Twilio Gateway",
|
||||
"allow": "INVITE, ACK, CANCEL, BYE, REFER, NOTIFY, OPTIONS",
|
||||
"content-type": "application/sdp",
|
||||
"content-length": "281",
|
||||
"X-Account-Sid": "9351f46a-678c-43f5-b8a6-d4eb58d131af",
|
||||
"X-CID": "dae8845526bf7fe640ad0162238473e4@0.0.0.0",
|
||||
"X-Forwarded-For": "54.172.60.3",
|
||||
"X-Originating-Carrier": "Twilio",
|
||||
"X-Voip-Carrier-Sid": "c763b9dc-7113-450d-b86e-b3781d5fbec1",
|
||||
"X-Application-Sid": "7087fe50-8acb-4f3b-b820-97b573723aab",
|
||||
"Diversion": "<sip:+15083728299@twilio.com>;reason=unconditional",
|
||||
"X-Twilio-AccountSid": "AC58f23d38858ac262d6ee2e554b30c561",
|
||||
"X-Twilio-CallSid": "CAeea292c8a7c71dc67de46155ec667826",
|
||||
"p-asserted-identity": "<sip:+15083084809@206.147.76.45:5060>"
|
||||
},
|
||||
"raw": "INVITE sip:+15083728299@10.0.13.72:5070 SIP/2.0\r\nVia: SIP/2.0/UDP 3.212.205.202;rport=5060;branch=z9hG4bK3tv053jp1mcHQ;received=10.0.13.72\r\nMax-Forwards: 70\r\nFrom: <sip:+15083084809@3.212.205.202:5060>;tag=9mgyBeaUy4H2S\r\nTo: <sip:+15083728299@3.212.205.202>\r\nCall-ID: d8907723-0bc7-123b-09b5-12e962f3039b\r\nCSeq: 48063641 INVITE\r\nContact: <sip:10.0.13.72:5060>\r\nUser-Agent: Twilio Gateway\r\nAllow: INVITE, ACK, CANCEL, BYE, REFER, NOTIFY, OPTIONS\r\nContent-Type: application/sdp\r\nContent-Length: 281\r\nX-Account-Sid: 9351f46a-678c-43f5-b8a6-d4eb58d131af\r\nX-CID: dae8845526bf7fe640ad0162238473e4@0.0.0.0\r\nX-Forwarded-For: 54.172.60.3\r\nX-Originating-Carrier: Twilio\r\nX-Voip-Carrier-Sid: c763b9dc-7113-450d-b86e-b3781d5fbec1\r\nX-Application-Sid: 7087fe50-8acb-4f3b-b820-97b573723aab\r\nDiversion: <sip:+15083728299@twilio.com>;reason=unconditional\r\nX-Twilio-AccountSid: AC58f23d38858ac262d6ee2e554b30c561\r\nX-Twilio-CallSid: CAeea292c8a7c71dc67de46155ec667826\r\nP-Asserted-Identity: <sip:+15083084809@206.147.76.45:5060>\r\n\r\nv=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n",
|
||||
"body": "v=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n",
|
||||
"method": "INVITE",
|
||||
"version": "2.0",
|
||||
"uri": "sip:+15083728299@10.0.13.72:5070",
|
||||
"payload": [{
|
||||
"type": "application/sdp",
|
||||
"content": "v=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n"
|
||||
}]
|
||||
},
|
||||
"direction": "inbound",
|
||||
"caller_name": "",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"account_sid": "9351f46a-678c-43f5-b8a6-d4eb58d131af",
|
||||
"application_sid": "7087fe50-8acb-4f3b-b820-97b573723aab",
|
||||
"from": "+15083084809",
|
||||
"to": "+15083728299",
|
||||
"call_id": "d8907723-0bc7-123b-09b5-12e962f3039b",
|
||||
"sip_status": 100,
|
||||
"call_status": "trying",
|
||||
"originating_sip_ip": "54.172.60.3",
|
||||
"originating_sip_trunk_name": "Twilio",
|
||||
"local_sip_address": "10.0.13.72:5070"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/overview">Prev: overview</a>
|
||||
<a href="/docs/ws/session-redirect">Next: session:redirect</a>
|
||||
</p>
|
||||
76
markdown/docs/ws/session-reconnect.md
Normal file
76
markdown/docs/ws/session-reconnect.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# session:reconnect
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `session:reconnect` message is sent by jambonz to the websocket server when the websocket connection was closed unexpectedly by the websocket server and jambonz has then successfully reconnected.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "session:reconnect"|indicates this is a session:reconnect message|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|data|object|JSON payload describing the call|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "session:reconnect",
|
||||
"msgid": "auuHioXGktYh2ZFYxf3hAA",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"data": {
|
||||
"sip": {
|
||||
"headers": {
|
||||
"via": "SIP/2.0/UDP 3.212.205.202;rport=5060;branch=z9hG4bK3tv053jp1mcHQ;received=10.0.13.72",
|
||||
"max-forwards": "70",
|
||||
"from": "<sip:+15083084809@3.212.205.202:5060>;tag=9mgyBeaUy4H2S",
|
||||
"to": "<sip:+15083728299@3.212.205.202>",
|
||||
"call-id": "d8907723-0bc7-123b-09b5-12e962f3039b",
|
||||
"cseq": "48063641 INVITE",
|
||||
"contact": "<sip:10.0.13.72:5060>",
|
||||
"user-agent": "Twilio Gateway",
|
||||
"allow": "INVITE, ACK, CANCEL, BYE, REFER, NOTIFY, OPTIONS",
|
||||
"content-type": "application/sdp",
|
||||
"content-length": "281",
|
||||
"X-Account-Sid": "9351f46a-678c-43f5-b8a6-d4eb58d131af",
|
||||
"X-CID": "dae8845526bf7fe640ad0162238473e4@0.0.0.0",
|
||||
"X-Forwarded-For": "54.172.60.3",
|
||||
"X-Originating-Carrier": "Twilio",
|
||||
"X-Voip-Carrier-Sid": "c763b9dc-7113-450d-b86e-b3781d5fbec1",
|
||||
"X-Application-Sid": "7087fe50-8acb-4f3b-b820-97b573723aab",
|
||||
"Diversion": "<sip:+15083728299@twilio.com>;reason=unconditional",
|
||||
"X-Twilio-AccountSid": "AC58f23d38858ac262d6ee2e554b30c561",
|
||||
"X-Twilio-CallSid": "CAeea292c8a7c71dc67de46155ec667826",
|
||||
"p-asserted-identity": "<sip:+15083084809@206.147.76.45:5060>"
|
||||
},
|
||||
"raw": "INVITE sip:+15083728299@10.0.13.72:5070 SIP/2.0\r\nVia: SIP/2.0/UDP 3.212.205.202;rport=5060;branch=z9hG4bK3tv053jp1mcHQ;received=10.0.13.72\r\nMax-Forwards: 70\r\nFrom: <sip:+15083084809@3.212.205.202:5060>;tag=9mgyBeaUy4H2S\r\nTo: <sip:+15083728299@3.212.205.202>\r\nCall-ID: d8907723-0bc7-123b-09b5-12e962f3039b\r\nCSeq: 48063641 INVITE\r\nContact: <sip:10.0.13.72:5060>\r\nUser-Agent: Twilio Gateway\r\nAllow: INVITE, ACK, CANCEL, BYE, REFER, NOTIFY, OPTIONS\r\nContent-Type: application/sdp\r\nContent-Length: 281\r\nX-Account-Sid: 9351f46a-678c-43f5-b8a6-d4eb58d131af\r\nX-CID: dae8845526bf7fe640ad0162238473e4@0.0.0.0\r\nX-Forwarded-For: 54.172.60.3\r\nX-Originating-Carrier: Twilio\r\nX-Voip-Carrier-Sid: c763b9dc-7113-450d-b86e-b3781d5fbec1\r\nX-Application-Sid: 7087fe50-8acb-4f3b-b820-97b573723aab\r\nDiversion: <sip:+15083728299@twilio.com>;reason=unconditional\r\nX-Twilio-AccountSid: AC58f23d38858ac262d6ee2e554b30c561\r\nX-Twilio-CallSid: CAeea292c8a7c71dc67de46155ec667826\r\nP-Asserted-Identity: <sip:+15083084809@206.147.76.45:5060>\r\n\r\nv=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n",
|
||||
"body": "v=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n",
|
||||
"method": "INVITE",
|
||||
"version": "2.0",
|
||||
"uri": "sip:+15083728299@10.0.13.72:5070",
|
||||
"payload": [{
|
||||
"type": "application/sdp",
|
||||
"content": "v=0\r\no=root 81565042 81565042 IN IP4 10.0.13.72\r\ns=Twilio Media Gateway\r\nc=IN IP4 10.0.13.72\r\nt=0 0\r\nm=audio 40150 RTP/AVP 0 8 101\r\na=maxptime:20\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephone-event/8000\r\na=fmtp:101 0-16\r\na=sendrecv\r\na=rtcp:40151\r\na=ptime:20\r\n"
|
||||
}]
|
||||
},
|
||||
"direction": "inbound",
|
||||
"caller_name": "",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"account_sid": "9351f46a-678c-43f5-b8a6-d4eb58d131af",
|
||||
"application_sid": "7087fe50-8acb-4f3b-b820-97b573723aab",
|
||||
"from": "+15083084809",
|
||||
"to": "+15083728299",
|
||||
"call_id": "d8907723-0bc7-123b-09b5-12e962f3039b",
|
||||
"sip_status": 100,
|
||||
"call_status": "trying",
|
||||
"originating_sip_ip": "54.172.60.3",
|
||||
"originating_sip_trunk_name": "Twilio",
|
||||
"local_sip_address": "10.0.13.72:5070"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/session-redirect">Prev: session:redirect</a>
|
||||
<a href="/docs/ws/call-status">Next: call:status</a>
|
||||
</p>
|
||||
54
markdown/docs/ws/session-redirect.md
Normal file
54
markdown/docs/ws/session-redirect.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# session:redirect
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `session:redirect` message is sent by jambonz to the websocket server when a call has been redirected to a new application and a relative URL was provided instead of an array of verbs.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "session:redirect"|indicates this is a session:redirect message|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|hook|string|url of the call_hook that was provided|yes|
|
||||
|data|object|JSON payload describing the current state of the call|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "session:redirect",
|
||||
"msgid": "cvY6kNE8RXdaZdaDcJbViG",
|
||||
"call_sid": "aad0115d-ec21-40db-aa02-31b7b01540c5",
|
||||
"b3": "18228daa536f82e0ec29074e7bf47b89-dd3bdf1f177f2995-1",
|
||||
"hook": "survey",
|
||||
"data": {
|
||||
"call_sid": "b5e39996-bd2f-4bda-b928-355147186a2a",
|
||||
"direction": "inbound",
|
||||
"from": "+441173185201",
|
||||
"to": "+441303763875",
|
||||
"call_id": "7ade3efb-7163-123b-e6ba-023fd61c5256",
|
||||
"sip_status": 200,
|
||||
"sip_reason": "OK",
|
||||
"call_status": "in-progress",
|
||||
"account_sid": "300be250-5a79-46bd-8393-45e7d26c2e34",
|
||||
"trace_id": "654c5323d6f907233a1069136b8a330e",
|
||||
"local_sip_address": "10.0.150.88:5070",
|
||||
"defaults": {
|
||||
"synthesizer": {
|
||||
"vendor": "microsoft",
|
||||
"language": "en-US",
|
||||
"voice": "en-US-JennyNeural"
|
||||
},
|
||||
"recognizer": {
|
||||
"vendor": "microsoft",
|
||||
"language": "en-US"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/session-new">Prev: session:new</a>
|
||||
<a href="/docs/ws/session-reconnect">Next: session:reconnect</a>
|
||||
</p>
|
||||
63
markdown/docs/ws/verb-hook.md
Normal file
63
markdown/docs/ws/verb-hook.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# verb:hook
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `verb:hook` message is sent by jambonz to the websocket server when an action hook or event hook configured for a verb has been triggered (e.g. a “gather” verb has collected an utterance from the user).
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "verb:hook"|indicates this is an error notification from jambonz|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|hook|string|url of hook that was providing in the eventHook or actionHook property|yes|
|
||||
|data|object|data payload describing the event|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "verb:hook",
|
||||
"msgid": "cvY6kNE8RXdaZdaDcJbViG",
|
||||
"call_sid": "aad0115d-ec21-40db-aa02-31b7b01540c5",
|
||||
"b3": "18228daa536f82e0ec29074e7bf47b89-dd3bdf1f177f2995-1",
|
||||
"hook": "voice",
|
||||
"data": {
|
||||
"speech": {
|
||||
"is_final": true,
|
||||
"transcripts": [
|
||||
{
|
||||
"is_final": true,
|
||||
"language_code": "en-US",
|
||||
"alternatives": [
|
||||
{
|
||||
"confidence": 0.91916794,
|
||||
"transcript": "I'd like to book a car"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"reason": "speechDetected",
|
||||
"call_sid": "aad0115d-ec21-40db-aa02-31b7b01540c5",
|
||||
"direction": "inbound",
|
||||
"from": "+15083084809",
|
||||
"to": "+15083728363",
|
||||
"call_id": "fc5f8190-718a-123b-e6ba-023fd61c5256",
|
||||
"sip_status": 200,
|
||||
"sip_reason": "OK",
|
||||
"call_status": "in-progress",
|
||||
"account_sid": "4bfe85c1-96bb-4af7-ac83-68fe7ebd562d",
|
||||
"trace_id": "18228daa536f82e0ec29074e7bf47b89",
|
||||
"application_sid": "3badbf0f-e778-44bb-a89a-dc2ca31f2f9c",
|
||||
"fs_sip_address": "10.0.150.88:5070",
|
||||
"originating_sip_ip": "54.172.60.1",
|
||||
"originating_sip_trunk_name": "Twilio - Dave trunk",
|
||||
"api_base_url": "http://3.71.131.50/v1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/call-status">Prev: call:status</a>
|
||||
<a href="/docs/ws/verb-status">Next: verb:status</a>
|
||||
</p>
|
||||
38
markdown/docs/ws/verb-status.md
Normal file
38
markdown/docs/ws/verb-status.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# verb:status
|
||||
|
||||
>> jambonz => websocket server
|
||||
|
||||
A `verb:status` message is sent by jambonz to the websocket server when a verb has just started or completed executing.
|
||||
|
||||
> Note: `verb:status` messages are only sent when the app has provided an `id` property on verbs it includes in a `command` message.
|
||||
|
||||
|property|type|meaning|required|
|
||||
|--------|----|-------|--------|
|
||||
|type|string "verb:status"|indicates this is an error notification from jambonz|yes|
|
||||
|msgid|string|unique message identifier|yes|
|
||||
|call_sid|string|unique call identifier|yes|
|
||||
|b3|string|open telemetry span identifier for this call (only provided if otel tracing is enabled)|no|
|
||||
|data|object|error details|yes|
|
||||
|data.id|string|verb id|yes|
|
||||
|data.verb|string|name of verb|yes|
|
||||
|data.status|string|'begin' or 'end'|yes|
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "verb:status",
|
||||
"msgid": "1cvh3MNHh1xrJaHmnitqA1",
|
||||
"call_sid": "9fb35c28-9688-4531-943c-e280b04f3adf",
|
||||
"data": {
|
||||
"id": "ueydf3",
|
||||
"verb": "say",
|
||||
"status": "begin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p class="flex">
|
||||
<span> </span>
|
||||
<a href="/docs/ws/verb-hook">Prev: verb:hook</a>
|
||||
<a href="/docs/ws/jambonz-error">Next: jambonz:error</a>
|
||||
</p>
|
||||
1289
package-lock.json
generated
1289
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user