@jambonz/node-red-contrib-jambonz 2.4.10 → 2.4.12

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jambonz/node-red-contrib-jambonz",
3
- "version": "2.4.10",
3
+ "version": "2.4.12",
4
4
  "description": "Node-RED nodes for jambonz platform",
5
5
  "keywords": [
6
6
  "node-red"
@@ -16,8 +16,7 @@
16
16
  $('#btn-test-credentials').on('click', testCredentials);
17
17
  $('#node-config-input-url').typedInput({
18
18
  types: ['str',
19
- {value: 'https://api.jambonz.us', label : 'jambonz.us', hasValue: false},
20
- {value: 'https://api.jambonz.xyz', label : 'jambonz.xyz', hasValue: false}],
19
+ {value: 'https://api.jambonz.cloud', label : 'jambonz.cloud', hasValue: false}],
21
20
  typeField: $('#node-config-input-urlType')
22
21
  });
23
22
  },
@@ -27,11 +27,26 @@
27
27
  return action !== 'redirect' || v.length > 0;
28
28
  }},
29
29
  callHookType: {value: 'str'},
30
+ childCallHook: {value: ''},
31
+ childCallHookType: {value: 'str'},
30
32
  waitHook: {value: '', validate: function(v) {
31
33
  const action = $('#node-input-action').val();
32
34
  return action !== 'hold_conf' || v.length > 0;
33
35
  }},
34
36
  waitHookType: {value: 'str'},
37
+ sipRequestMethod: {value: 'INFO'},
38
+ sipRequestHeaders: {value: '{}'},
39
+ sipRequestHeadersType: {value: 'json'},
40
+ sipRequestContentType: {value: '', validate: function(v) {
41
+ const action = $('#node-input-action').val();
42
+ return action !== 'sip_request' || v.length > 0;
43
+ }},
44
+ sipRequestContentTypeType: {value: 'str'},
45
+ sipRequestBody: {value: '', validate: function(v) {
46
+ const action = $('#node-input-action').val();
47
+ return action !== 'sip_request' || v.length > 0;
48
+ }},
49
+ sipRequestBodyType: {value: 'str'},
35
50
  siprecServerURL: {value: '', validate: function(v) {
36
51
  const action = $('#node-input-action').val();
37
52
  return action !== 'start_call_recording' || v.length > 0;
@@ -58,6 +73,7 @@
58
73
  var redirectDiv = $('#redirect-options');
59
74
  var waitHookDiv = $('#wait-options');
60
75
  var recordDiv = $('#record-options');
76
+ var sipRequestDiv = $('#sip-request-options');
61
77
 
62
78
  $('#node-input-callSid').typedInput({
63
79
  default: $('#node-input-callSidType').val(),
@@ -69,11 +85,31 @@
69
85
  types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
70
86
  typeField: $('#node-input-callHookType')
71
87
  });
88
+ $('#node-input-childCallHook').typedInput({
89
+ default: $('#node-input-childCallHookType').val(),
90
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
91
+ typeField: $('#node-input-childCallHookType')
92
+ });
72
93
  $('#node-input-waitHook').typedInput({
73
94
  default: $('#node-input-waitHookType').val(),
74
95
  types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
75
96
  typeField: $('#node-input-waitHookType')
76
97
  });
98
+ $('#node-input-sipRequestContentType').typedInput({
99
+ default: $('#node-input-sipRequestContentTypeType').val(),
100
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
101
+ typeField: $('#node-input-sipRequestContentTypeType')
102
+ });
103
+ $('#node-input-sipRequestBody').typedInput({
104
+ default: $('#node-input-sipRequestBodyType').val(),
105
+ types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
106
+ typeField: $('#node-input-sipRequestBodyType')
107
+ });
108
+ $('#node-input-sipRequestHeaders').typedInput({
109
+ default: $('#node-input-sipRequestHeadersType').val(),
110
+ types: ['json','msg', 'flow', 'global'],
111
+ typeField: $('#node-input-sipRequestHeadersType')
112
+ });
77
113
  $('#node-input-siprecServerURL').typedInput({
78
114
  default: $('#node-input-siprecServerURLType').val(),
79
115
  types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
@@ -95,6 +131,8 @@
95
131
  else waitHookDiv.hide();
96
132
  if ('start_call_recording' === selectedAction) recordDiv.show();
97
133
  else recordDiv.hide();
134
+ if ('sip_request' === selectedAction) sipRequestDiv.show();
135
+ else sipRequestDiv.hide();
98
136
  }
99
137
 
100
138
  var onVendorChanged = function() {
@@ -254,6 +292,7 @@
254
292
  <option value="resume">resume listen audio feed</option>
255
293
  <option value="redirect">redirect call</option>
256
294
  <option value="whisper">whisper</option>
295
+ <option value="sip_request">sip request</option>
257
296
  <option value="start_call_recording">start call recording</option>
258
297
  <option value="stop_call_recording">stop call recording</option>
259
298
  <option value="pause_call_recording">pause call recording</option>
@@ -291,14 +330,19 @@
291
330
  </div>
292
331
  <div id="redirect-options">
293
332
  <div class="form-row">
294
- <label for="node-input-callHook">Call webhook</label>
333
+ <label for="node-input-callHook">Call hook</label>
295
334
  <input type="text" id="node-input-callHook" placeholder="/path">
296
335
  <input type="hidden" id="node-input-callHookType">
297
- </div>
336
+ </div>
337
+ <div class="form-row">
338
+ <label for="node-input-childCallHook">Child call hook</label>
339
+ <input type="text" id="node-input-childCallHook" placeholder="/path">
340
+ <input type="hidden" id="node-input-childCallHookType">
341
+ </div>
298
342
  </div>
299
343
  <div id="wait-options">
300
344
  <div class="form-row">
301
- <label for="node-input-waitHook">Wait webhook</label>
345
+ <label for="node-input-waitHook">Wait hook</label>
302
346
  <input type="text" id="node-input-waitHook" placeholder="/path">
303
347
  <input type="hidden" id="node-input-waitHookType">
304
348
  </div>
@@ -323,6 +367,31 @@
323
367
  </div>
324
368
  </fieldset>
325
369
  </div>
370
+ <div id="sip-request-options">
371
+ <div class="form-row">
372
+ <label for="node-input-sipRequestMethod">Method</label>
373
+ <select id="node-input-sipRequestMethod">
374
+ <option value="INFO" selected>INFO</option>
375
+ <option value="MESSAGE">MESSAGE</option>
376
+ <option value="NOTIFY">NOTIFY</option>
377
+ </select>
378
+ </div>
379
+ <div class="form-row">
380
+ <label for="node-input-sipRequestContentType">Content type</label>
381
+ <input type="text" id="node-input-sipRequestContentType" placeholder="SIP content type">
382
+ <input type="hidden" id="node-input-sipRequestContentTypeType">
383
+ </div>
384
+ <div class="form-row">
385
+ <label for="node-input-sipRequestBody">Body</label>
386
+ <input type="text" id="node-input-sipRequestBody" placeholder="SIP body">
387
+ <input type="hidden" id="node-input-sipRequestBodyType">
388
+ </div>
389
+ <div class="form-row">
390
+ <label for="node-input-sipRequestHeaders">Headers</label>
391
+ <input type="text" id="node-input-sipRequestHeaders" placeholder="SIP headers">
392
+ <input type="hidden" id="node-input-sipRequestHeadersType">
393
+ </div>
394
+ </div>
326
395
  </script>
327
396
 
328
397
  <!-- Help Text -->
package/src/nodes/lcc.js CHANGED
@@ -46,6 +46,9 @@ function lcc(config) {
46
46
  break;
47
47
  case 'redirect':
48
48
  opts.call_hook = {url: new_resolve(RED, config.callHook, config.callHookType, node, msg)};
49
+ if (config.childCallHook) {
50
+ opts.child_call_hook = {url: new_resolve(RED, config.childCallHook, config.childCallHookType, node, msg)};
51
+ }
49
52
  break;
50
53
  case 'hold_conf':
51
54
  opts.conf_hold_status = 'hold';
@@ -70,6 +73,14 @@ function lcc(config) {
70
73
  });
71
74
  }
72
75
  break;
76
+ case 'sip_request':
77
+ opts.sip_request = {
78
+ method: config.sipRequestMethod,
79
+ content_type: new_resolve(RED, config.sipRequestContentType, config.sipRequestContentTypeType, node, msg),
80
+ content: new_resolve(RED, config.sipRequestBody, config.sipRequestBodyType, node, msg),
81
+ headers: new_resolve(RED, config.sipRequestHeaders, config.sipRequestHeadersType, node, msg) || {}
82
+ };
83
+ break;
73
84
  case 'start_call_recording':
74
85
  opts.record = {
75
86
  action: 'startCallRecording',
@@ -105,7 +116,7 @@ function lcc(config) {
105
116
 
106
117
  try {
107
118
  msg.payload = await doLCC(node, url, accountSid, apiToken, callSid, opts);
108
- msg.statusCode = 202;
119
+ msg.statusCode = config.action === 'sip_request' ? 200 : 202;
109
120
  } catch (err) {
110
121
  if (err.statusCode) msg.statusCode = err.statusCode;
111
122
  else {
package/src/nodes/libs.js CHANGED
@@ -112,7 +112,7 @@ exports.appendVerb = (msg, obj) => {
112
112
 
113
113
 
114
114
  exports.doLCC = (node, baseUrl, accountSid, apiToken, callSid, opts) => {
115
- const post = bent(`${baseUrl}/v1/`, 'POST', 'string', 202, {
115
+ const post = bent(`${baseUrl}/v1/`, 'POST', 'string', [200, 202], {
116
116
  'Authorization': `Bearer ${apiToken}`
117
117
  });
118
118
  const url = `Accounts/${accountSid}/Calls/${callSid}`;