@jambonz/node-red-contrib-jambonz 2.2.73 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/examples/Authenticating sip devices.json +1 -0
  2. package/examples/Conference with LCC.json +1 -0
  3. package/{src/examples → examples}/Connecting to a dialogflow bot.json +0 -0
  4. package/examples/Create Call and Send DTMF.json +1 -0
  5. package/examples/Get Log Data.json +1 -0
  6. package/examples/Leave Queue.json +1 -0
  7. package/examples/SIP Responses.json +1 -0
  8. package/{src/examples → examples}/SIP trunking outbound call.json +0 -0
  9. package/examples/Simple IVR.json +1 -0
  10. package/examples/Simple Queue.json +1 -0
  11. package/examples/Using Redirect.json +1 -0
  12. package/examples/Voicemail using Listen into S3 bucket.json +130 -0
  13. package/examples/config.json +1 -0
  14. package/examples/gather.json +1 -0
  15. package/examples/lex.json +1 -0
  16. package/examples/messages.json +1 -0
  17. package/examples/rasa.json +1 -0
  18. package/examples/tag a call.json +1 -0
  19. package/package.json +52 -14
  20. package/resources/editor.js +414 -0
  21. package/src/data/recognizer.json +685 -1
  22. package/src/data/tts.json +2970 -1
  23. package/src/nodes/auth.html +108 -0
  24. package/src/nodes/auth.js +43 -0
  25. package/src/nodes/conference.html +121 -0
  26. package/src/nodes/conference.js +31 -0
  27. package/src/nodes/config.html +484 -0
  28. package/src/nodes/config.js +74 -0
  29. package/src/nodes/create_call.html +287 -0
  30. package/src/nodes/create_call.js +104 -0
  31. package/src/nodes/create_sms.html +106 -0
  32. package/src/nodes/create_sms.js +65 -0
  33. package/src/nodes/dequeue.html +102 -0
  34. package/src/nodes/dequeue.js +25 -0
  35. package/src/nodes/dial.html +629 -0
  36. package/src/nodes/dial.js +141 -0
  37. package/src/nodes/dialogflow.html +260 -0
  38. package/src/nodes/dialogflow.js +53 -0
  39. package/src/nodes/dtmf.html +74 -0
  40. package/src/nodes/dtmf.js +22 -0
  41. package/src/nodes/enqueue.html +90 -0
  42. package/src/nodes/enqueue.js +25 -0
  43. package/src/nodes/gather.html +326 -0
  44. package/src/nodes/gather.js +83 -0
  45. package/src/nodes/get_alerts.html +94 -0
  46. package/src/nodes/get_alerts.js +47 -0
  47. package/src/nodes/get_calls.html +59 -0
  48. package/src/nodes/get_calls.js +38 -0
  49. package/src/nodes/get_recent_calls.html +95 -0
  50. package/src/nodes/get_recent_calls.js +47 -0
  51. package/src/nodes/hangup.html +46 -0
  52. package/src/nodes/hangup.js +20 -0
  53. package/src/nodes/jambonz.html +63 -38
  54. package/src/nodes/lcc.html +256 -0
  55. package/src/nodes/lcc.js +102 -0
  56. package/src/nodes/leave.html +40 -0
  57. package/src/nodes/leave.js +21 -0
  58. package/src/nodes/lex.html +264 -0
  59. package/src/nodes/lex.js +75 -0
  60. package/src/nodes/libs.js +100 -0
  61. package/src/nodes/listen.html +341 -0
  62. package/src/nodes/listen.js +82 -0
  63. package/src/nodes/message.html +95 -0
  64. package/src/nodes/message.js +32 -0
  65. package/src/nodes/pause.html +62 -0
  66. package/src/nodes/pause.js +25 -0
  67. package/src/nodes/play.html +76 -0
  68. package/src/nodes/play.js +23 -0
  69. package/src/nodes/rasa.html +106 -0
  70. package/src/nodes/rasa.js +22 -0
  71. package/src/nodes/redirect.html +64 -0
  72. package/src/nodes/redirect.js +24 -0
  73. package/src/nodes/s3-upload.html +29 -14
  74. package/src/nodes/s3-upload.js +24 -9
  75. package/src/nodes/say.html +119 -0
  76. package/src/nodes/say.js +38 -0
  77. package/src/nodes/sip-decline.html +76 -0
  78. package/src/nodes/sip-decline.js +25 -0
  79. package/src/nodes/sip-refer.html +116 -0
  80. package/src/nodes/sip-refer.js +33 -0
  81. package/src/nodes/sip-request.html +96 -0
  82. package/src/nodes/sip-request.js +36 -0
  83. package/src/nodes/tag.html +60 -0
  84. package/src/nodes/tag.js +22 -0
  85. package/src/nodes/template.html +63 -0
  86. package/src/nodes/template.js +9 -0
  87. package/src/nodes/userauth.html +85 -0
  88. package/src/nodes/userauth.js +70 -0
  89. package/src/nodes/webhooks.js +0 -16
  90. package/src/utils/http-helpers.js +68 -0
  91. package/src/examples/Authenticating sip devices.json +0 -10
  92. package/src/nodes/http-helpers.js +0 -26
  93. package/src/nodes/jambonz.js +0 -1044
@@ -0,0 +1,141 @@
1
+ var {createHash} = require('crypto');
2
+ const bent = require('bent');
3
+ var {appendVerb, v_resolve} = require('./libs')
4
+
5
+ module.exports = function(RED) {
6
+ function dial(config) {
7
+ RED.nodes.createNode(this, config);
8
+ var node = this;
9
+
10
+ node.on('input', function(msg) {
11
+
12
+ node.log(`dial config: ${JSON.stringify(config)}, msg.call: ${JSON.stringify(msg.call)}`);
13
+ var target = config.targets.map((t) => {
14
+ const obj = Object.assign({}, t);
15
+ var dest = v_resolve(obj.dest, obj.varType, this.context(), msg);
16
+ var trunk = v_resolve(obj.trunk, obj.trunkType, this.context(), msg);
17
+ node.log(`dial: dest ${t.varType}:${t.dest} resolved to ${dest}`);
18
+ switch (t.type) {
19
+ case 'phone':
20
+ obj.number = dest;
21
+ obj.trunk = trunk;
22
+ break;
23
+ case 'user':
24
+ obj.name = dest;
25
+ break;
26
+ case 'sip':
27
+ obj.sipUri = dest;
28
+ if (t.user) {
29
+ obj.auth = {
30
+ username: t.user,
31
+ password: t.pass
32
+ };
33
+ }
34
+ delete obj.user;
35
+ delete obj.pass;
36
+ break;
37
+ case 'teams':
38
+ obj.number = dest;
39
+ break;
40
+ }
41
+ delete obj.varType;
42
+ delete obj.trunkType;
43
+ delete obj.dest;
44
+ return obj;
45
+ });
46
+ var data = {
47
+ verb: 'dial',
48
+ target,
49
+ answerOnBridge: config.answeronbridge,
50
+ timeLimit: config.timelimit ? parseInt(config.timelimit) : null,
51
+ timeout: config.timeout ? parseInt(config.timeout) : null,
52
+ callerId: v_resolve(config.callerid, config.calleridType, this.context(), msg),
53
+ actionHook: v_resolve(config.actionhook, config.actionhookType, this.context(), msg),
54
+ confirmHook: v_resolve(config.confirmhook, config.confirmhookType, this.context(), msg),
55
+ dialMusic: v_resolve(config.dialmusic, config.dialmusicType, this.context(), msg),
56
+ dtmfHook: v_resolve(config.dtmfhook, config.dtmfhookType, this.context(), msg)
57
+ };
58
+
59
+
60
+ // headers
61
+ var headers = {};
62
+ config.headers.forEach(function(h) {
63
+ if (h.h.length && h.v.length) headers[h.h] = h.v;
64
+ });
65
+ Object.assign(data, {headers});
66
+
67
+ // nested listen
68
+ if (config.listenurl && config.listenurl.length > 0) {
69
+ data.listen = {
70
+ url: v_resolve(config.listenurl, config.listenurlType, this.context(), msg),
71
+ mixType: 'stereo'
72
+ };
73
+ }
74
+
75
+ // nested transcribe
76
+ if (config.transcriptionhook) {
77
+ const recognizer = {
78
+ vendor: config.transcriptionvendor,
79
+ language: config.recognizerlang,
80
+ interim: config.interim,
81
+ separateRecognitionPerChannel: config.mixtype === 'stereo' && config.separaterecog,
82
+ diarization: config.diarization
83
+ };
84
+ if (recognizer.vendor === 'google') {
85
+ var diarizationMin = v_resolve(config.diarizationmin, config.diarizationminType, this.context(), msg);
86
+ var diarizationMax = v_resolve(config.diarizationmax, config.diarizationmaxType, this.context(), msg);
87
+ var hints = v_resolve(config.transcriptionhints, config.transcriptionhintsType, this.context(), msg);
88
+ var altlangs = v_resolve(config.recognizeraltlang, config.recognizeraltlangType, this.context(), msg);
89
+ var naics = v_resolve(config.naics, config.naicsType, this.context(), msg);
90
+ Object.assign(recognizer, {
91
+ profanityFilter: config.profanityfilter,
92
+ hints: hints.length > 0 ?
93
+ hints.split(',').map((w) => w.trim()) :
94
+ [],
95
+ punctuation: config.punctuation,
96
+ enhancedModel: config.useenhanced,
97
+ words: config.words,
98
+ interactionType: config.interactiontype,
99
+ });
100
+ if (recognizer.diarization) {
101
+ if (diarizationMin) recognizer.diarizationMinSpeakers = parseInt(diarizationMin) || 0;
102
+ if (diarizationMax) recognizer.diarizationMaxSpeakers = parseInt(diarizationMax) || 0;
103
+ }
104
+ if (naics) recognizer.naicsCode = parseInt(naics) || 0;
105
+ if (altlangs) {
106
+ recognizer.altLanguages = altlangs.split(',').map((e) => e.trim());
107
+ }
108
+ }
109
+ else if (recognizer.vendor === 'aws') {
110
+ var vocab = v_resolve(config.vocabularyname, config.vocabularynameType, this.context(), msg);
111
+ var vocabFilter = v_resolve(config.vocabularyfiltername, config.vocabularynameType, this.context(), msg);
112
+ Object.assign(recognizer, {
113
+ vocabularyName: vocab,
114
+ vocabularyFilterName: vocabFilter,
115
+ filterMethod: config.vocabularyfiltermethod
116
+ });
117
+ }
118
+ data.transcribe = {
119
+ transcriptionHook: v_resolve(config.transcriptionhook, config.transcriptionhookType, this.context(), msg),
120
+ recognizer
121
+ };
122
+ }
123
+ // dtmf capture
124
+ const dtmfCapture = v_resolve(config.dtmfcapture, config.dtmfcaptureType, this.context(), msg);
125
+ if (dtmfCapture && dtmfCapture.length) {
126
+ data.dtmfCapture = dtmfCapture.split(',').map((i) => i.trim());
127
+ }
128
+ else {
129
+ delete data.dtmfHook;
130
+ }
131
+
132
+
133
+ node.log(`dial verb: ${JSON.stringify(data)}`);
134
+
135
+ appendVerb(msg, data);
136
+ node.log(`dial jambonz: ${JSON.stringify(msg.jambonz)}`);
137
+ node.send(msg);
138
+ });
139
+ }
140
+ RED.nodes.registerType('dial', dial);
141
+ }
@@ -0,0 +1,260 @@
1
+ <!-- Javascript -->
2
+ <script type="text/javascript">
3
+ RED.nodes.registerType('dialogflow',{
4
+ category: 'jambonz',
5
+ color: '#bbabaa',
6
+ defaults: {
7
+ name: {value: ''},
8
+ recognizerlang: {value: 'en-US'},
9
+ serviceAccountCredentials: {required: true, value: ''},
10
+ serviceAccountCredentialsType: {value: 'msg'},
11
+ project: {required: true, value: ''},
12
+ projectType: {value: 'str'},
13
+ environment: {value: ''},
14
+ environmentType: {value: 'str'},
15
+ welcomeEvent: {},
16
+ welcomeEventType: {value: 'str'},
17
+ welcomeEventParams: {},
18
+ welcomeEventParamsType: {value: 'json'},
19
+ passDtmf: {value: false},
20
+ inputTimeout: {},
21
+ inputTimeoutType: {value: 'num'},
22
+ noInputEvent: {},
23
+ noInputEventType: {value: 'str'},
24
+ bargein: {value: false},
25
+ eventHook: {},
26
+ eventHookType: {value: 'str'},
27
+ actionHook: {},
28
+ actionHookType: {value: 'str'},
29
+ evtAll: {value: true},
30
+ evtIntent: {value: false},
31
+ evtTranscript: {value: false},
32
+ evtInterimTranscript: {value: false},
33
+ evtDtmf: {value: false},
34
+ evtEndUtterance: {value: false},
35
+ evtStartPlay: {value: false},
36
+ evtEndPlay: {value: false},
37
+ evtNoInput: {value: false},
38
+ prompt: {value: 'dialogflow', required: true},
39
+ vendor: {value: 'default'},
40
+ lang: {value: 'default'},
41
+ voice: {value: 'default'},
42
+ xlang: {},
43
+ xvoice: {}
44
+ },
45
+ inputs:1,
46
+ outputs:1,
47
+ icon: "font-awesome/fa-cubes",
48
+ label: function() { return this.name || 'dialogflow';},
49
+ oneditprepare: function() {
50
+ var node = this;
51
+ $('#node-input-serviceAccountCredentials').typedInput({
52
+ typeField: $('#node-input-serviceAccountCredentialsType'),
53
+ types: ['json', 'msg', 'flow', 'global', 'jsonata', 'env']
54
+ });
55
+ $('#node-input-project').typedInput({
56
+ typeField: $('#node-input-projectType'),
57
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
58
+ });
59
+ $('#node-input-environment').typedInput({
60
+ typeField: $('#node-input-environmentType'),
61
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
62
+ });
63
+ $('#node-input-welcomeEvent').typedInput({
64
+ typeField: $('#node-input-welcomeEventType'),
65
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
66
+ });
67
+ $('#node-input-welcomeEventParams').typedInput({
68
+ typeField: $('#node-input-welcomeEventParamsType'),
69
+ types: ['json', 'msg', 'flow', 'global', 'jsonata', 'env']
70
+ });
71
+ $('#node-input-eventHook').typedInput({
72
+ typeField: $('#node-input-eventHookType'),
73
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
74
+ });
75
+ $('#node-input-actionHook').typedInput({
76
+ typeField: $('#node-input-actionHookType'),
77
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
78
+ });
79
+ $('#node-input-inputTimeout').typedInput({
80
+ typeField: $('#node-input-inputTimeout'),
81
+ types: ['num','msg', 'flow', 'global', 'jsonata', 'env']
82
+ });
83
+ $('#node-input-noinputEvent').typedInput({
84
+ typeField: $('#node-input-noinputEventType'),
85
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env']
86
+ });
87
+ var promptElem = $('#node-input-prompt');
88
+ var ttsDiv = $('#tts-options');
89
+ var recLangElem = $('#node-input-recognizerlang');
90
+
91
+ prepareTtsControls(node);
92
+ var onPromptChanged = function () {
93
+ node.action = promptElem.find(':selected').val();
94
+ if ('tts' === node.action) ttsDiv.show();
95
+ else ttsDiv.hide();
96
+ }
97
+ promptElem.change(onPromptChanged);
98
+
99
+ var setTranscriptionLanguage = function() {
100
+ console.log(`setting transcription languages: ${dialogFlowOptions}`);
101
+ recLangElem.find('option').remove();
102
+ recLangElem.append(dialogFlowOptions);
103
+ }
104
+
105
+ setTranscriptionLanguage();
106
+ console.log(`setting lang to ${node.recognizerlang}`);
107
+ recLangElem.val(node.recognizerlang);
108
+ }
109
+ });
110
+
111
+ </script>
112
+
113
+
114
+ <!-- HTML -->
115
+ <script type="text/html" data-template-name="dialogflow">
116
+ <div class="form-row">
117
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
118
+ <input type="text" id="node-input-name" placeholder="Name">
119
+ </div>
120
+ <div class="form-row">
121
+ <label for="node-input-project">Dialogflow project ID</label>
122
+ <input type="text" id="node-input-project">
123
+ <input type="hidden" id="node-input-projectType">
124
+ </div>
125
+ <div class="form-row">
126
+ <label for="node-input-project">Environment</label>
127
+ <input type="text" id="node-input-environment">
128
+ <input type="hidden" id="node-input-enviromentType">
129
+ </div>
130
+ <div class="form-row">
131
+ <label for="node-input-recognizerlang">Speaker language</label>
132
+ <select id="node-input-recognizerlang">
133
+ <option value="placeholder"></option>
134
+ </select>
135
+ </div>
136
+ <div class="form-row">
137
+ <label for="node-input-serviceAccountCredentials">Service account key</label>
138
+ <input type="text" id="node-input-serviceAccountCredentials">
139
+ <input type="hidden" id="node-input-serviceAccountCredentialsType">
140
+ </div>
141
+ <div class="form-row">
142
+ <label for="node-input-welcomeEvent">Welcome intent</label>
143
+ <input type="text" id="node-input-welcomeEvent" placeholder="event to send on connect">
144
+ <input type="hidden" id="node-input-welcomeEventType">
145
+ </div>
146
+ <div class="form-row">
147
+ <label for="node-input-welcomeEventParams">Welcome intent parameters</label>
148
+ <input type="text" id="node-input-welcomeEventParams">
149
+ <input type="hidden" id="node-input-welcomeEventParamsType">
150
+ </div>
151
+ <div class="form-row">
152
+ <label for="node-input-inputTimeout">Input timeout</label>
153
+ <input type="text" id="node-input-inputTimeout" placeholder="seconds to wait for a response">
154
+ <input type="hidden" id="node-input-inputTimeoutType">
155
+ </div>
156
+ <div class="form-row">
157
+ <label for="node-input-noInputEvent">Input timeout intent</label>
158
+ <input type="text" id="node-input-noInputEvent" placeholder="event to send on input timeout">
159
+ <input type="hidden" id="node-input-noInputEventType">
160
+ </div>
161
+ <div class="form-row">
162
+ <label for="node-input-bargein">Barge in on speech?</label>
163
+ <input type="checkbox" id="node-input-bargein">
164
+ </div>
165
+ <div class="form-row">
166
+ <label for="node-input-eventHook">Event Hook</label>
167
+ <input type="text" id="node-input-eventHook">
168
+ <input type="hidden" id="node-input-eventHookType">
169
+ </div>
170
+ <div class="form-row">
171
+ <label for="node-input-actionHook">Action Hook</label>
172
+ <input type="text" id="node-input-actionHook">
173
+ <input type="hidden" id="node-input-actionHookType">
174
+ </div>
175
+ <div class="form-row">
176
+ <label for="node-input-prompt">Prompt audio</label>
177
+ <select id="node-input-prompt" style="width:250px;">
178
+ <option value="dialogflow">Use dialogflow-provided audio</option>
179
+ <option value="tts">Use text to speech</option>
180
+ </select>
181
+ </div>
182
+ <div id="tts-options">
183
+ <div class="form-row">
184
+ <label for="node-input-vendor"> Vendor</label>
185
+ <select id="node-input-vendor">
186
+ <option value="default" selected>--application default--</option>
187
+ <option value="google">google</option>
188
+ <option value="aws">aws/polly</option>
189
+ <option value="microsoft">microsoft</option>
190
+ <option value="ibm">ibm</option>
191
+ <option value="nuance">nuance</option>
192
+ </select>
193
+ </div>
194
+ <div class="form-row" style="display: none;">
195
+ <label for="node-input-lang"> Lang</label>
196
+ <input type="text" id="node-input-lang">
197
+ </div>
198
+ <div class="form-row">
199
+ <label for="node-input-xlang">Language</label>
200
+ <select id="node-input-xlang">
201
+ <option value="default" selected>--application default--</option>
202
+ </select>
203
+ </div>
204
+ <div class="form-row" style="display: none;">
205
+ <label for="node-input-voice"> Voice</label>
206
+ <input type="text" id="node-input-voice">
207
+ </div>
208
+ <div class="form-row">
209
+ <label for="node-input-xvoice">Voice</label>
210
+ <select id="node-input-xvoice">
211
+ <option value="default" selected>--application default--</option>
212
+ </select>
213
+ </div>
214
+ </div>
215
+ </script>
216
+
217
+ <!-- Help Text -->
218
+
219
+ <script type="text/html" data-help-name="audio in">
220
+ <script type="text/html" data-help-name="dialogflow">
221
+ <p>Run a Google dialogflow bot on the call</p>
222
+ <h3>Properties</h3>
223
+ <p><code>Dialogflow Project ID</code> -
224
+ The name of the dialogflow project to execute. Required.</p>
225
+ <p><code>Service Account Key</code> -
226
+ A Google service account key in JSON format is used to authenticate to dialogflow. Required.</p>
227
+ <p><code>Language</code> -
228
+ The ISO language code to use for speech recognition. Required.</p>
229
+ <p><code>Welcome Intent</code> -
230
+ The name of a dialogflow intent to send when the call is first connected. Optional.</p>
231
+ <p><code>Welcome Intent Parameters</code> -
232
+ A JSON object containing parameters to send along with the welcome intent. Optional.</p>
233
+ <p><code>Input Timeout</code> -
234
+ Number of seconds to wait for no response. Optional.</p>
235
+ <p><code>Event Hook</code> -
236
+ Webhook to call when an intent, transcription or other dialogflow event is received. Optional.</p>
237
+ <p><code>Action Hook</code> -
238
+ Webhook to call when the dialogflow bot interaction concludes. Optional.</p>
239
+
240
+
241
+ <h3>Outputs</h3>
242
+ <dl class="message-properties">
243
+ <dt>jambonz<span class="property-type">object</span></dt>
244
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>dialogflow</code> action appended </dd>
245
+ </dl>
246
+
247
+ <h3>Details</h3>
248
+ The dialogflow action connects the call to a Google dialogflow voicebot.
249
+ The action completes either when a new application is returned in a response to an eventHook, or the call is terminated from the dialogflow side.
250
+
251
+ <h3>References</h3>
252
+ <ul>
253
+ <li><a href="https://docs.jambonz.org/jambonz/#dialogflow">Jambonz dialogflow reference</a></li>
254
+ </ul>
255
+ </script>
256
+
257
+
258
+
259
+
260
+ </script>
@@ -0,0 +1,53 @@
1
+ var {createHash} = require('crypto');
2
+ const bent = require('bent');
3
+ var mustache = require('mustache');
4
+ mustache.escape = function(text) {return text;};
5
+ var {appendVerb, v_resolve} = require('./libs')
6
+
7
+ module.exports = function(RED) {
8
+ function dialogflow(config) {
9
+ RED.nodes.createNode(this, config);
10
+ var node = this;
11
+ node.on('input', function(msg) {
12
+ var val = v_resolve(config.inputTimeout, config.inputTimeoutType, this.context(), msg);
13
+ var timeout = /^\d+$/.test(val) ? parseInt(val) : 0;
14
+ var eventHook = v_resolve(config.eventHook, config.eventHookType, this.context(), msg);
15
+ var actionHook = v_resolve(config.actionHook, config.actionHookType, this.context(), msg);
16
+ var welcomeEvent = v_resolve(config.welcomeEvent, config.welcomeEventType, this.context(), msg);
17
+ var environment = v_resolve(config.environment, config.environmentType, this.context(), msg);
18
+ var welcomeEventParams;
19
+ if (welcomeEvent && welcomeEvent.length > 0) {
20
+ welcomeEventParams = v_resolve(config.welcomeEventParams, config.welcomeEventParamsType, this.context(), msg);
21
+ }
22
+ var noInputEvent = v_resolve(config.noInputEvent, config.noInputEventType, this.context(), msg);
23
+ const obj = {
24
+ verb: 'dialogflow',
25
+ credentials: v_resolve(config.serviceAccountCredentials,
26
+ config.serviceAccountCredentialsType, this.context(), msg),
27
+ project: v_resolve(config.project, config.projectType, this.context(), msg),
28
+ lang: config.recognizerlang,
29
+ bargein: config.bargein
30
+ };
31
+ if (welcomeEvent) {
32
+ obj.welcomeEvent = welcomeEvent;
33
+ if (welcomeEventParams) obj.welcomeEventParams = welcomeEventParams;
34
+ }
35
+ if (environment && environment.length > 0) obj.environment = environment;
36
+ if (eventHook && eventHook.length > 0) obj.eventHook = eventHook;
37
+ if (actionHook && actionHook.length > 0) obj.actionHook = actionHook;
38
+ if (timeout) obj.noInputTimeout = timeout;
39
+ if (timeout && noInputEvent) obj.noInputEvent = noInputEvent;
40
+ if (config.prompt === 'tts') {
41
+ obj.tts = {
42
+ vendor: config.vendor,
43
+ language: config.lang,
44
+ voice: config.voice
45
+ };
46
+ }
47
+
48
+ appendVerb(msg, obj);
49
+ node.send(msg);
50
+ });
51
+ }
52
+ RED.nodes.registerType('dialogflow', dialogflow);
53
+ }
@@ -0,0 +1,74 @@
1
+ <!-- Javascript -->
2
+ <script type="text/javascript">
3
+ RED.nodes.registerType('dtmf',{
4
+ category: 'jambonz',
5
+ color: '#bbabaa',
6
+ defaults: {
7
+ name: {value: ''},
8
+ dtmf: {required: true},
9
+ duration: {value: '500'}
10
+ },
11
+ inputs:1,
12
+ outputs:1,
13
+ icon: "font-awesome/fa-cubes",
14
+ label: function() { return this.name || 'dtmf';},
15
+ oneditprepare: function() {
16
+
17
+ $('#node-input-dtmf').typedInput({
18
+ default: $('#node-input-dtmfType').val(),
19
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env'],
20
+ typeField: $('#node-input-dtmfType')
21
+ })
22
+ $('#node-input-duration').typedInput({
23
+ default: $('#node-input-durationType').val(),
24
+ types: ['num','msg', 'flow', 'global', 'jsonata', 'env'],
25
+ typeField: $('#node-input-durationType')
26
+ })
27
+ }
28
+ });
29
+
30
+ </script>
31
+
32
+
33
+ <!-- HTML -->
34
+ <script type="text/html" data-template-name="dtmf">
35
+ <div class="form-row">
36
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
37
+ <input type="text" id="node-input-name" placeholder="Name">
38
+ </div>
39
+ <div class="form-row">
40
+ <label for="node-input-dtmf">DTMF</label>
41
+ <input type="text" id="node-input-dtmf" placeholder="0-9 * #">
42
+ <input type="hidden" id="node-input-dtmfType">
43
+ </div>
44
+ <div class="form-row">
45
+ <label for="node-input-duration">Duration</label>
46
+ <input type="text" id="node-input-duration" placeholder="500">
47
+ <input type="hidden" id="node-input-durationType">
48
+ </div>
49
+ </script>
50
+
51
+ <!-- Help Text -->
52
+ <script type="text/html" data-help-name="play">
53
+ <p>generates a string of dtmf digit signals</p>
54
+ <h3>Properties</h3>
55
+ <p><code>DTMF</code> - a string containing a sequence of dtmf digits (0-9,*,#)</p>
56
+ <p><code>Duration</code> - the length of each digit, in milliseconds, Defaults to 500</p>
57
+
58
+
59
+ <h3>Outputs</h3>
60
+ <dl class="message-properties">
61
+ <dt>jambonz<span class="property-type">object</span></dt>
62
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>play</code> action appended </dd>
63
+ </dl>
64
+
65
+ <h3>Details</h3>
66
+ The dtmf action generates a string of dtmf digit signals. These are sent as RTP payloads using RFC 2833.
67
+
68
+
69
+
70
+ <h3>References</h3>
71
+ <ul>
72
+ <li><a href="https://www.jambonz.org/docs/webhooks/dtmf/">Jambonz play reference</a></li>
73
+ </ul>
74
+ </script>
@@ -0,0 +1,22 @@
1
+ var {createHash} = require('crypto');
2
+ const bent = require('bent');
3
+ var mustache = require('mustache');
4
+ mustache.escape = function(text) {return text;};
5
+ var {appendVerb} = require('./libs')
6
+
7
+
8
+ module.exports = function(RED) {
9
+ function dtmf(config) {
10
+ RED.nodes.createNode(this, config);
11
+ var node = this;
12
+ node.on('input', function(msg) {
13
+ appendVerb(msg, {
14
+ verb: 'dtmf',
15
+ dtmf: config.dtmf,
16
+ duration: parseInt(config.duration)
17
+ });
18
+ node.send(msg);
19
+ });
20
+ }
21
+ RED.nodes.registerType('dtmf', dtmf);
22
+ }
@@ -0,0 +1,90 @@
1
+ <!-- Javascript -->
2
+
3
+
4
+ <script type="text/javascript">
5
+ RED.nodes.registerType('enqueue',{
6
+ category: 'jambonz',
7
+ color: '#bbabaa',
8
+ defaults: {
9
+ name: {value: ''},
10
+ queue: {required: true, value: ''},
11
+ queueType: {value: 'str'},
12
+ actionHook: {},
13
+ actionHookType: {value: 'str'},
14
+ waitHook: {},
15
+ waitHookType: {value: 'str'}
16
+ },
17
+ inputs:1,
18
+ outputs:1,
19
+ icon: "font-awesome/fa-cubes",
20
+ label: function() {
21
+ return this.name || 'enqueue';
22
+ },
23
+ oneditprepare: function() {
24
+ $('#node-input-queue').typedInput({
25
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
26
+ typeField: $('#node-input-queueType')
27
+ });
28
+ $('#node-input-actionHook').typedInput({
29
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
30
+ typeField: $('#node-input-actionHookType')
31
+ });
32
+ $('#node-input-waitHook').typedInput({
33
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
34
+ typeField: $('#node-input-waitHookType')
35
+ });
36
+ }
37
+ });
38
+
39
+ </script>
40
+
41
+
42
+ <!-- HTML -->
43
+
44
+ <script type="text/html" data-template-name="enqueue">
45
+ <div class="form-row">
46
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
47
+ <input type="text" id="node-input-name" placeholder="Name">
48
+ </div>
49
+ <div class="form-row">
50
+ <label for="node-input-queue">Queue name</label>
51
+ <input type="text" id="node-input-queue" placeholder="name of queue">
52
+ <input type="hidden" id="node-input-queueType">
53
+ </div>
54
+ <div class="form-row">
55
+ <label for="node-input-actionHook">Action hook</label>
56
+ <input type="text" id="node-input-actionHook" placeholder="webhook url">
57
+ <input type="hidden" id="node-input-actionHookType">
58
+ </div>
59
+ <div class="form-row">
60
+ <label for="node-input-waitHook">Wait hook</label>
61
+ <input type="text" id="node-input-waitHook" placeholder="webhook url">
62
+ <input type="hidden" id="node-input-waitHookType">
63
+ </div>
64
+ </script>
65
+
66
+ <!-- Help Text -->
67
+
68
+ <script type="text/html" data-help-name="enqueue">
69
+ <p>places a caller in a queue.</p>
70
+ <h3>Properties</h3>
71
+ <p><code>Queue name</code> -
72
+ The name of the queue</p>
73
+ <p><code>Action hook</code> -
74
+ A webhook invoke when operation completes.</p>
75
+ <p><code>Wait hook</code> -
76
+ A webhook to invoke while the caller is in queue. The only allowed verbs in the application returned from this webhook are say, play, pause, and leave,.</p>
77
+
78
+ <h3>Outputs</h3>
79
+ <dl class="message-properties">
80
+ <dt>jambonz<span class="property-type">object</span></dt>
81
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>enqueue</code> action appended </dd>
82
+ </dl>
83
+
84
+ <h3>Details</h3>
85
+ The enqueue command is used to place a caller in a queue.
86
+ <h3>References</h3>
87
+ <ul>
88
+ <li><a href="https://docs.jambonz.org/jambonz/#enqueue">Jambonz enqueue reference</a></li>
89
+ </ul>
90
+ </script>
@@ -0,0 +1,25 @@
1
+ var {createHash} = require('crypto');
2
+ const bent = require('bent');
3
+ var mustache = require('mustache');
4
+ mustache.escape = function(text) {return text;};
5
+ var {appendVerb, v_resolve} = require('./libs')
6
+
7
+
8
+ module.exports = function(RED) {
9
+ /** enqueue */
10
+ function enqueue(config) {
11
+ RED.nodes.createNode(this, config);
12
+ var node = this;
13
+ node.on('input', function(msg, send, done) {
14
+ appendVerb(msg, {
15
+ verb: 'enqueue',
16
+ name: v_resolve(config.queue, config.queueType, this.context(), msg),
17
+ actionHook: v_resolve(config.actionHook, config.actionHookType, this.context(), msg),
18
+ waitHook: v_resolve(config.waitHook, config.waitHookType, this.context(), msg)
19
+ });
20
+ node.send(msg);
21
+ });
22
+ }
23
+ RED.nodes.registerType('enqueue', enqueue);
24
+
25
+ }