@jambonz/node-red-contrib-jambonz 2.2.72 → 2.3.0

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 +619 -0
  36. package/src/nodes/dial.js +138 -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 +322 -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 +96 -42
  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 +99 -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 +115 -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 -1032
@@ -0,0 +1,341 @@
1
+ <!-- Javascript -->
2
+ <script type="text/javascript">
3
+ RED.nodes.registerType('listen',{
4
+ category: 'jambonz',
5
+ color: '#bbabaa',
6
+ defaults: {
7
+ name: {value: ''},
8
+ actionhook: {},
9
+ actionhookType: {value: 'str'},
10
+ url: {required: true},
11
+ urlType: {value: 'str'},
12
+ authuser: {},
13
+ authuserType: {val: 'str'},
14
+ authpass: {},
15
+ authpassType: {val: 'str'},
16
+ finishonkey: {},
17
+ maxlength: {},
18
+ metadata: {},
19
+ metadataType: {value: 'json'},
20
+ mixtype: {value: 'mono'},
21
+ beep: {value: false},
22
+ samplerate: {value: 8000},
23
+ timeout: {},
24
+ transcriptionhook: {},
25
+ transcriptionhookType: {value: 'str'},
26
+ transcriptionvendor: {value: 'default'},
27
+ recognizerlang: {value: 'default'},
28
+ recognizeraltlang: {},
29
+ recognizeraltlangType: {val: 'str'},
30
+ interim: {value: false},
31
+ profanityfilter: {value: false},
32
+ transcriptionhints: {},
33
+ transcriptionhintsType: {val: 'str'},
34
+ separaterecog: {value: false},
35
+ useenhanced: {value: false},
36
+ words: {value: false},
37
+ punctuation: {value: false},
38
+ diarization: {value: false},
39
+ diarizationmin: {value: 2},
40
+ diarizationminType: {value: 'num'},
41
+ diarizationmax: {value: 6},
42
+ diarizationmaxType: {value: 'num'},
43
+ interactiontype: {value: 'unspecified'},
44
+ naics: {value: 0},
45
+ naicsType: {value: 'num'},
46
+ identifychannels: {value: false},
47
+ speakerlabel: {value: false},
48
+ vocabularyname: {},
49
+ vocabularynameType: {value: 'str'},
50
+ vocabularyfiltername: {},
51
+ vocabularyfilternameType: {value: 'str'},
52
+ vocabularyfiltermethod: {}
53
+ },
54
+ inputs:1,
55
+ outputs:1,
56
+ icon: "font-awesome/fa-cubes",
57
+ label: function() { return this.name || 'listen';},
58
+ oneditprepare: function() {
59
+ var node = this;
60
+ $('#node-input-actionhook').typedInput({
61
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
62
+ typeField: $('#node-input-actionhookType')
63
+ });
64
+ $('#node-input-url').typedInput({
65
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
66
+ typeField: $('#node-input-urlType')
67
+ });
68
+ $('#node-input-authuser').typedInput({
69
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
70
+ typeField: $('#node-input-authuserType')
71
+ });
72
+ $('#node-input-authpassword').typedInput({
73
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
74
+ typeField: $('#node-input-authpasswordType')
75
+ });
76
+ $('#node-input-metadata').typedInput({
77
+ types: ['json', 'msg', 'flow', 'global'],
78
+ typeField: $('#node-input-metadataType')
79
+ });
80
+ $('#node-input-transcriptionhook').typedInput({
81
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
82
+ typeField: $('#node-input-transcriptionhookType')
83
+ });
84
+ $('#node-input-transcriptionhints').typedInput({
85
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
86
+ typeField: $('#node-input-transcriptionhintsType')
87
+ });
88
+ $('#node-input-recognizeraltlang').typedInput({
89
+ types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env'],
90
+ typeField: $('#node-recognizeraltlangType')
91
+ });
92
+ $('#node-input-diarizationmin').typedInput({
93
+ types: ['num', 'msg', 'flow', 'global'],
94
+ typeField: $('#node-input-diarizationminType')
95
+ });
96
+ $('#node-input-diarizationmax').typedInput({
97
+ types: ['num', 'msg', 'flow', 'global'],
98
+ typeField: $('#node-input-diarizationmaxType')
99
+ });
100
+ $('#node-input-naics').typedInput({
101
+ types: ['num', 'msg', 'flow', 'global'],
102
+ typeField: $('#node-input-naicsType')
103
+ });
104
+
105
+ prepareSttControls(node);
106
+ }
107
+ });
108
+ </script>
109
+
110
+
111
+ <!-- HTML -->
112
+ <script type="text/html" data-template-name="listen">
113
+ <div class="form-row">
114
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
115
+ <input type="text" id="node-input-name" placeholder="Name">
116
+ </div>
117
+ <div class="form-row">
118
+ <label for="node-input-url">Url</label>
119
+ <input type="text" id="node-input-url" placeholder="ws url">
120
+ <input type="hidden" id="node-input-urlType">
121
+ </div>
122
+ <div class="form-row">
123
+ <label for="node-input-authuser">User</label>
124
+ <input type="text" id="node-input-authuser" placeholder="basic auth username">
125
+ <input type="hidden" id="node-input-authuserType">
126
+ </div>
127
+ <div class="form-row">
128
+ <label for="node-input-authpassword">Password</label>
129
+ <input type="text" id="node-input-authpassword" placeholder="basic auth password">
130
+ <input type="hidden" id="node-input-authpasswordType">
131
+ </div>
132
+ <div class="form-row">
133
+ <label for="node-input-actionhook">Action hook</label>
134
+ <input type="text" id="node-input-actionhook" placeholder="webhook url to invoke when operation ends">
135
+ <input type="hidden" id="node-input-actionhookType">
136
+ </div>
137
+ <div class="form-row">
138
+ <label for="node-input-metadata">Metadata</label>
139
+ <input type="text" id="node-input-metadata">
140
+ <input type="hidden" id="node-input-metadataType">
141
+ </div>
142
+ <div class="form-row">
143
+ <label for="node-input-maxlength">Max duration</label>
144
+ <input type="text" id="node-input-maxlength">
145
+ </div>
146
+ <div class="form-row">
147
+ <label for="node-input-finishonkey">End key</label>
148
+ <input type="text" id="node-input-finishonkey">
149
+ </div>
150
+ <div class="form-row">
151
+ <label for="node-input-beep">Beep</label>
152
+ <input type="checkbox" id="node-input-beep">
153
+ </div>
154
+ <div class="form-row">
155
+ <label for="node-input-mixtype">Mix type</label>
156
+ <select id="node-input-mixtype">
157
+ <option selected>mono</option>
158
+ <option>stereo</option>
159
+ </select>
160
+ </div>
161
+ <div class="form-row">
162
+ <label for="node-input-samplerate">Sample rate</label>
163
+ <select id="node-input-samplerate">
164
+ <option selected>8000</option>
165
+ <option>16000</option>
166
+ <option>24000</option>
167
+ <option>48000</option>
168
+ <option>64000</option>
169
+ </select>
170
+ </div>
171
+ <fieldset>
172
+ <legend>Transcription (optional)</legend>
173
+ <div class="form-row">
174
+ <label for="node-input-transcriptionhook"><i class="icon-tag"></i> Transcription hook</label>
175
+ <input type="text" id="node-input-transcriptionhook" placeholder="transcription webhook">
176
+ <input type="hidden" id="node-input-transcriptionhookType">
177
+ </div>
178
+ <div class="form-row">
179
+ <label for="node-input-transcriptionvendor">Vendor</label>
180
+ <select id="node-input-transcriptionvendor">
181
+ <option value="default" selected>--application default--</option>
182
+ <option value="google">Google</option>
183
+ <option value="aws">AWS</option>
184
+ <option value="deepgram">Deepgram</option>
185
+ <option value="microsoft">Microsoft</option>
186
+ <option value="ibm">IBM</option>
187
+ <option value="nuance">Nuance</option>
188
+ </select>
189
+ </div>
190
+ <div class="form-row">
191
+ <label for="node-input-recognizerlang"><i class="icon-tag"></i> Language</label>
192
+ <select id="node-input-recognizerlang">
193
+ </select>
194
+ </div>
195
+ <div id="interim" class="form-row">
196
+ <label for="node-input-interim">Interim transcriptions</label>
197
+ <input type="checkbox" id="node-input-interim">
198
+ </div>
199
+ <div id="stt-identify-channels" class="form-row">
200
+ <label for="node-input-separaterecog">Separate recognition per channel</label>
201
+ <input type="checkbox" id="node-input-separaterecog">
202
+ </div>
203
+ <div id="google-stt-options">
204
+ <legend>Google Transcription Options</legend>
205
+ <div class="form-row">
206
+ <label for="node-input-transcriptionhints">Hints</label>
207
+ <input type="text" id="node-input-transcriptionhints" placeholder="comma-separated list of phrases">
208
+ <input type="hidden" id="node-input-transcriptionhintsType">
209
+ </div>
210
+ <div class="form-row">
211
+ <label for="node-input-recognizeraltlang">Alternative languages</label>
212
+ <input type="text" id="node-input-recognizeraltlang" placeholder="comma-separated list of add'l lang codes">
213
+ <input type="hidden" id="node-input-recognizeraltlangType">
214
+ </div>
215
+ <div class="form-row">
216
+ <label for="node-input-useenhanced">Use enhanced model</label>
217
+ <input type="checkbox" id="node-input-useenhanced">
218
+ </div>
219
+ <div class="form-row">
220
+ <label for="node-input-profanityfilter">Profanity filter</label>
221
+ <input type="checkbox" id="node-input-profanityfilter">
222
+ </div>
223
+ <div class="form-row">
224
+ <label for="node-input-words">Word time offsets</label>
225
+ <input type="checkbox" id="node-input-words">
226
+ </div>
227
+ <div class="form-row">
228
+ <label for="node-input-punctuation">Automatic punctuation</label>
229
+ <input type="checkbox" id="node-input-punctuation">
230
+ </div>
231
+ <div class="form-row">
232
+ <label for="node-input-diarization">Speaker diarization</label>
233
+ <input type="checkbox" id="node-input-diarization">
234
+ </div>
235
+ <div class="form-row">
236
+ <label for="node-input-diarizationmin">Min speaker count</label>
237
+ <input type="text" id="node-input-diarizationmin" placeholder="2">
238
+ <input type="hidden" id="node-input-diarizationminType">
239
+ </div>
240
+ <div class="form-row">
241
+ <label for="node-input-diarizationmax">Max speaker count</label>
242
+ <input type="text" id="node-input-diarizationmax" placeholder="6">
243
+ <input type="hidden" id="node-input-diarizationmaxType">
244
+ </div>
245
+ <div class="form-row">
246
+ <label for="node-input-interactiontype">Type of Interaction</label>
247
+ <select id="node-input-interactiontype">
248
+ <option value="unspecified" selected>Unspecified</option>
249
+ <option value="discussion">Discusssion</option>
250
+ <option value="presentation">Presentation</option>
251
+ <option value="phone_call">Phone call</option>
252
+ <option value="voicemail">Voicemail</option>
253
+ <option value="voice_search">Voice search</option>
254
+ <option value="voice_command">Voice command</option>
255
+ <option value="dictation">Dictation</option>
256
+ </select>
257
+ </div>
258
+ <div class="form-row">
259
+ <label for="node-input-naics">Industry NAICS code</label>
260
+ <input type="text" id="node-input-naics">
261
+ <input type="hidden" id="node-input-naicsType">
262
+ </div>
263
+ </div>
264
+ <div id="aws-stt-options">
265
+ <legend>AWS Transcription Options</legend>
266
+ <div class="form-row">
267
+ <label for="node-input-identifychannels">Enable channel identification</label>
268
+ <input type="checkbox" id="node-input-identifychannels">
269
+ </div>
270
+ <div class="form-row">
271
+ <label for="node-input-speakerlabel">Show speaker labels</label>
272
+ <input type="checkbox" id="node-input-speakerlabel">
273
+ </div>
274
+ <div class="form-row">
275
+ <label for="node-input-vocabularyname">Vocabulary name</label>
276
+ <input type="text" id="node-input-vocabularyname">
277
+ <input type="hidden" id="node-input-vocabularynameType">
278
+ </div>
279
+ <div class="form-row">
280
+ <label for="node-input-vocabularyfiltername">Vocabulary filter name</label>
281
+ <input type="text" id="node-input-vocabularyfiltername">
282
+ <input type="hidden" id="node-input-vocabularyfilternameType">
283
+ </div>
284
+ <div class="form-row">
285
+ <label for="node-input-vocabularyfiltermethod">Filter method</label>
286
+ <select id="node-input-vocabularyfiltermethod">
287
+ <option value="remove" selected>Remove</option>
288
+ <option value="mask" selected>Mask</option>
289
+ <option value="tag" selected>Tag</option>
290
+ </select>
291
+ </div>
292
+ </div>
293
+ </fieldset>
294
+
295
+ </script>
296
+
297
+ <!-- Help Text -->
298
+ <script type="text/html" data-help-name="listen">
299
+ <p>send live audio for the call to an over a websocket connection</p>
300
+ <h3>Properties</h3>
301
+ <p><code>ws url</code> -
302
+ url of remote server to connect to </p>
303
+ <p><code>User</code> -
304
+ Username for HTTP Basic Auth</p>
305
+ <p><code>Password</code> -
306
+ Password for HTTP Basic Auth</p>
307
+ <p><code>Action hook</code> -
308
+ webhook to invoke when listen operation ends</p>
309
+ <p><code>Metadata</code> -
310
+ arbitrary data to add to the JSON payload sent to the remote server when websocket connection is first connected</p>
311
+ <p><code>Max duration</code> -
312
+ the maximum length of the listened audio stream, in secs</p>
313
+ <p><code>End key</code> -
314
+ The set of digits that can end the listen action</p>
315
+ <p><code>Beep</code> -
316
+ if checked, play a beep at the start of the listen operation</p>
317
+ <p><code>Mix type</code> -
318
+ whether to record a mono or stereo stream</p>
319
+ <p><code>Sample rate</code> -
320
+ Sample rate of audio to stream</p>
321
+ <p><code>Transcription hook</code> -
322
+ webhook to call when a transcription is received</p>
323
+ <p><code>Language</code> -
324
+ Language to use for transcription</p>
325
+ <p><code>Send interim transcriptions</code> -
326
+ if checked, send interim transcriptions</p>
327
+ <p><code>Profanity filter</code> -
328
+ if checked, enable profanity filtering</p>
329
+
330
+ <h3>Outputs</h3>
331
+ <dl class="message-properties">
332
+ <dt>jambonz<span class="property-type">object</span></dt>
333
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>listen</code> action appended </dd>
334
+ </dl>
335
+
336
+ <h3>Details</h3>
337
+ The listen verb establishes a connection to a websocket server and sends live audio for the current call.<h3>References</h3>
338
+ <ul>
339
+ <li><a href="https://docs.jambonz.org/jambonz/#listen">Jambonz listen reference</a></li>
340
+ </ul>
341
+ </script>
@@ -0,0 +1,82 @@
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
+ function listen(config) {
10
+ RED.nodes.createNode(this, config);
11
+ var node = this;
12
+ node.on('input', function(msg) {
13
+ const obj = {
14
+ verb: 'listen',
15
+ url: v_resolve(config.url, config.urlType, this.context(), msg),
16
+ actionHook: v_resolve(config.actionhook, config.actionhookType, this.context(), msg),
17
+ finishOnKey: config.finishonkey,
18
+ mixType: config.mixtype,
19
+ playBeep: config.beep,
20
+ sampleRate: config.sampleRate,
21
+ };
22
+
23
+ if (config.transcriptionhook) {
24
+ const recognizer = {
25
+ vendor: config.transcriptionvendor,
26
+ language: config.recognizerlang,
27
+ interim: config.interim,
28
+ separateRecognitionPerChannel: config.mixtype === 'stereo' && config.separaterecog,
29
+ diarization: config.diarization
30
+ };
31
+ if (recognizer.vendor === 'google') {
32
+ var diarizationMin = v_resolve(config.diarizationmin, config.diarizationminType, this.context(), msg);
33
+ var diarizationMax = v_resolve(config.diarizationmax, config.diarizationmaxType, this.context(), msg);
34
+ var hints = v_resolve(config.transcriptionhints, config.transcriptionhintsType, this.context(), msg);
35
+ var altlangs = v_resolve(config.recognizeraltlang, config.recognizeraltlangType, this.context(), msg);
36
+ var naics = v_resolve(config.naics, config.naicsType, this.context(), msg);
37
+ Object.assign(recognizer, {
38
+ profanityFilter: config.profanityfilter,
39
+ hints: hints.length > 0 ?
40
+ hints.split(',').map((w) => w.trim()) :
41
+ [],
42
+ punctuation: config.punctuation,
43
+ enhancedModel: config.useenhanced,
44
+ words: config.words,
45
+ interactionType: config.interactiontype,
46
+ });
47
+ if (recognizer.diarization) {
48
+ if (diarizationMin) recognizer.diarizationMinSpeakers = parseInt(diarizationMin) || 0;
49
+ if (diarizationMax) recognizer.diarizationMaxSpeakers = parseInt(diarizationMax) || 0;
50
+ }
51
+ if (naics) recognizer.naicsCode = parseInt(naics) || 0;
52
+ if (altlangs) {
53
+ recognizer.altLanguages = altlangs.split(',').map((e) => e.trim());
54
+ }
55
+ }
56
+ else if (recognizer.vendor === 'aws') {
57
+ var vocab = v_resolve(config.vocabularyname, config.vocabularynameType, this.context(), msg);
58
+ var vocabFilter = v_resolve(config.vocabularyfiltername, config.vocabularynameType, this.context(), msg);
59
+ Object.assign(recognizer, {
60
+ vocabularyName: vocab,
61
+ vocabularyFilterName: vocabFilter,
62
+ filterMethod: config.vocabularyfiltermethod
63
+ });
64
+ }
65
+ obj.transcribe = {
66
+ transcriptionHook: v_resolve(config.transcriptionhook, config.transcriptionhookType, this.context(), msg),
67
+ recognizer
68
+ };
69
+ }
70
+ if (/^\d+$/.test(config.timeout)) obj.timeout = parseInt(config.timeout);
71
+ if (/^\d+$/.test(config.maxlength)) obj.maxLength = parseInt(config.maxLength);
72
+ if (config.finishonkey.length) obj.finishOnKey = config.finishonkey;
73
+
74
+ var data = v_resolve(config.metadata, config.metadataType, this.context(), msg, true);
75
+ if (data) obj.metadata = data;
76
+
77
+ appendVerb(msg, obj);
78
+ node.send(msg);
79
+ });
80
+ }
81
+ RED.nodes.registerType('listen', listen);
82
+ }
@@ -0,0 +1,95 @@
1
+ <!-- Javascript -->
2
+ <script type="text/javascript">
3
+ RED.nodes.registerType('message', {
4
+ category: 'jambonz',
5
+ color: '#bbabaa',
6
+ defaults: {
7
+ name: {value: ''},
8
+ from: {value: '', required: true},
9
+ fromType: {value: ''},
10
+ to: {value: '', required: true},
11
+ toType: {value: ''},
12
+ text: {value: '', required: true},
13
+ textType: {value: ''},
14
+ provider: {value: ''},
15
+ providerType: {value: ''},
16
+ },
17
+ inputs:1,
18
+ outputs:1,
19
+ icon: "font-awesome/fa-cubes",
20
+ label: function() {
21
+ return this.name || 'message';
22
+ },
23
+ oneditprepare: function() {
24
+ var node = this;
25
+
26
+ $('#node-input-from').typedInput({
27
+ default: $('#node-input-fromType').val(),
28
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env'],
29
+ typeField: $('#node-input-fromType')
30
+ });
31
+ $('#node-input-to').typedInput({
32
+ default: $('#node-input-toType').val(),
33
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env'],
34
+ typeField: $('#node-input-toType')
35
+ });
36
+ $('#node-input-text').typedInput({
37
+ default: $('#node-input-textType').val(),
38
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env'],
39
+ typeField: $('#node-input-textType')
40
+ });
41
+ $('#node-input-provider').typedInput({
42
+ default: $('#node-input-providerType').val(),
43
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env'],
44
+ typeField: $('#node-input-providerType')
45
+ });
46
+ }
47
+ });
48
+ </script>
49
+
50
+
51
+ <!-- HTML -->
52
+ <script type="text/html" data-template-name="message">
53
+ <div class="form-row">
54
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
55
+ <input type="text" id="node-input-name" placeholder="Name">
56
+ </div>
57
+ <div class="form-row">
58
+ <label for="node-input-from">From</label>
59
+ <input type="text" id="node-input-from" placeholder="sending number">
60
+ <input type="hidden" id="node-input-fromType">
61
+ </div>
62
+ <div class="form-row">
63
+ <label for="node-input-to">To</label>
64
+ <input type="text" id="node-input-to" placeholder="destination number">
65
+ <input type="hidden" id="node-input-toType">
66
+ </div>
67
+ <div class="form-row">
68
+ <label for="node-input-text">Text</label>
69
+ <input type="text" id="node-input-text" placeholder="Text">
70
+ <input type="hidden" id="node-input-textType">
71
+ </div>
72
+ <div class="form-row">
73
+ <label for="node-input-provider">SMS Provider</label>
74
+ <input type="text" id="node-input-provider">
75
+ <input type="hidden" id="node-input-providerType">
76
+ </div>
77
+ </script>
78
+
79
+ <!-- Help Text -->
80
+ <script type="text/html" data-help-name="message">
81
+ <p>Send an SMS</p>
82
+
83
+ <h3>Outputs</h3>
84
+ <dl class="message-properties">
85
+ <dt>jambonz<span class="property-type">object</span></dt>
86
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>message</code> action appended </dd>
87
+ </dl>
88
+
89
+ <h3>Details</h3>
90
+ The message verb sends an SMS message.
91
+ <h3>References</h3>
92
+ <ul>
93
+ <li><a href="https://docs.jambonz.org/jambonz/#message">Jambonz redirect reference</a></li>
94
+ </ul>
95
+ </script>
@@ -0,0 +1,32 @@
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
+ function message(config) {
10
+ RED.nodes.createNode(this, config);
11
+ var node = this;
12
+ node.on('input', function(msg, send, done) {
13
+ var from = v_resolve(config.from, config.fromType, this.context(), msg);
14
+ var to = v_resolve(config.to, config.toType, this.context(), msg);
15
+ var text = v_resolve(config.text, config.textType, this.context(), msg);
16
+ var provider = v_resolve(config.provider, config.providerType, this.context(), msg);
17
+ if ((!provider || 0 === provider.length) && msg.sms.provider) {
18
+ provider = msg.sms.provider;
19
+ }
20
+
21
+ appendVerb(msg, {
22
+ verb: 'message',
23
+ from,
24
+ to,
25
+ text,
26
+ provider
27
+ });
28
+ node.send(msg);
29
+ });
30
+ }
31
+ RED.nodes.registerType('message', message);
32
+ }
@@ -0,0 +1,62 @@
1
+ <!-- Javascript -->
2
+ <script type="text/javascript">
3
+ RED.nodes.registerType('pause',{
4
+ category: 'jambonz',
5
+ color: '#bbabaa',
6
+ defaults: {
7
+ name: {value: ''},
8
+ len: {required: true},
9
+ lenType: {value: 'num'},
10
+
11
+ },
12
+ inputs:1,
13
+ outputs:1,
14
+ icon: "font-awesome/fa-cubes",
15
+ label: function() { return this.name || 'pause';},
16
+ oneditprepare: function() {
17
+ $('#node-input-len').typedInput({
18
+ default: $('#node-input-lenType').val(),
19
+ types: ['num','msg', 'flow', 'global', 'jsonata', 'env'],
20
+ typeField: $('#node-input-lenType')
21
+ });
22
+ }
23
+ });
24
+
25
+ </script>
26
+
27
+
28
+ <!-- HTML -->
29
+ <script type="text/html" data-template-name="pause">
30
+ <div class="form-row">
31
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
32
+ <input type="text" id="node-input-name" placeholder="Name">
33
+ </div>
34
+ <div class="form-row">
35
+ <label for="node-input-length">Duration</label>
36
+ <input type="text" id="node-input-len" placeholder="number of seconds to pause">
37
+ <input type="hidden" id="node-input-lenType">
38
+ </div>
39
+ </script>
40
+
41
+ <!-- Help Text -->
42
+ <script type="text/html" data-help-name="pause">
43
+ <p>Pause a specified number of seconds</p>
44
+ <h3>Inputs</h3>
45
+ <dl class="message-properties">
46
+ <dt>Duration<span class="property-type">object</span></dt>
47
+ <dd>Number of seconds pause</dd>
48
+ </dl>
49
+
50
+ <h3>Outputs</h3>
51
+ <dl class="message-properties">
52
+ <dt>jambonz<span class="property-type">object</span></dt>
53
+ <dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>pause</code> action appended </dd>
54
+ </dl>
55
+
56
+ <h3>Details</h3>
57
+ The pause verb waits a specified number of seconds before continuing to execute the application.
58
+ <h3>References</h3>
59
+ <ul>
60
+ <li><a href="https://docs.jambonz.org/jambonz/#pause">Jambonz pause reference</a></li>
61
+ </ul>
62
+ </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
+ /** pause */
10
+ function pause(config) {
11
+ RED.nodes.createNode(this, config);
12
+ var node = this;
13
+ node.on('input', function(msg) {
14
+ var val = v_resolve(config.len, config.lenType, this.context(), msg);
15
+ var length = /^\d+$/.test(val) ? parseInt(val) : parseFloat(val);
16
+ appendVerb(msg, {
17
+ verb: 'pause',
18
+ length
19
+ });
20
+ node.send(msg);
21
+ });
22
+ }
23
+ RED.nodes.registerType('pause', pause);
24
+
25
+ }