@jambonz/node-red-contrib-jambonz 2.4.12 → 2.4.14
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 +3 -2
- package/src/nodes/conference.html +46 -23
- package/src/nodes/conference.js +7 -4
- package/src/nodes/create_call.html +90 -2
- package/src/nodes/create_call.js +17 -2
- package/src/nodes/get_call.html +57 -0
- package/src/nodes/get_call.js +45 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jambonz/node-red-contrib-jambonz",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.14",
|
|
4
4
|
"description": "Node-RED nodes for jambonz platform",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node-red"
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"create sms": "src/nodes/create_sms.js",
|
|
47
47
|
"lcc": "src/nodes/lcc.js",
|
|
48
48
|
"get_alerts": "src/nodes/get_alerts.js",
|
|
49
|
+
"get_call": "src/nodes/get_call.js",
|
|
49
50
|
"get_calls": "src/nodes/get_calls.js",
|
|
50
51
|
"get_recent_calls": "src/nodes/get_recent_calls.js"
|
|
51
52
|
}
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"author": "Dave Horton",
|
|
54
55
|
"license": "MIT",
|
|
55
56
|
"dependencies": {
|
|
56
|
-
"aws-sdk": "^2.
|
|
57
|
+
"aws-sdk": "^2.1405.0",
|
|
57
58
|
"bent": "^7.3.12",
|
|
58
59
|
"body-parser": "^1.20.2",
|
|
59
60
|
"cookie-parser": "^1.4.6",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Javascript -->
|
|
2
2
|
<script type="text/javascript">
|
|
3
|
-
|
|
3
|
+
var mustacheType = {
|
|
4
4
|
value: 'mustache',
|
|
5
5
|
label: 'mustache',
|
|
6
6
|
hasvalue: true,
|
|
@@ -16,13 +16,17 @@
|
|
|
16
16
|
conferenceType: {value: 'str'},
|
|
17
17
|
beep: {value: false},
|
|
18
18
|
endConferenceOnExit: {value: false},
|
|
19
|
-
startConferenceOnEnter: {value:
|
|
19
|
+
startConferenceOnEnter: {value: true},
|
|
20
20
|
maxParticipants: {},
|
|
21
21
|
maxParticipantsType: {value: 'num'},
|
|
22
22
|
enterHook: {},
|
|
23
23
|
enterHookType: {value: 'str'},
|
|
24
24
|
waitHook: {},
|
|
25
25
|
waitHookType: {value: 'str'},
|
|
26
|
+
actionHook: {},
|
|
27
|
+
actionHookType: {value: 'str'},
|
|
28
|
+
statusHook: {},
|
|
29
|
+
statusHookType: {value: 'str'},
|
|
26
30
|
joinMuted : {value: false}
|
|
27
31
|
},
|
|
28
32
|
inputs:1,
|
|
@@ -48,6 +52,14 @@
|
|
|
48
52
|
types: ['num', 'msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
49
53
|
typeField: $('#node-input-maxParticipantsType')
|
|
50
54
|
});
|
|
55
|
+
$('#node-input-actionHook').typedInput({
|
|
56
|
+
types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
57
|
+
typeField: $('#node-input-actionHookType')
|
|
58
|
+
});
|
|
59
|
+
$('#node-input-statusHook').typedInput({
|
|
60
|
+
types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
61
|
+
typeField: $('#node-input-statusHookType')
|
|
62
|
+
});
|
|
51
63
|
}
|
|
52
64
|
});
|
|
53
65
|
</script>
|
|
@@ -73,6 +85,16 @@
|
|
|
73
85
|
<input type="text" id="node-input-waitHook" placeholder="webhook url">
|
|
74
86
|
<input type="hidden" id="node-input-waitHookType">
|
|
75
87
|
</div>
|
|
88
|
+
<div class="form-row">
|
|
89
|
+
<label for="node-input-actionHook">Action hook</label>
|
|
90
|
+
<input type="text" id="node-input-actionHook" placeholder="webhook url">
|
|
91
|
+
<input type="hidden" id="node-input-actionHookType">
|
|
92
|
+
</div>
|
|
93
|
+
<div class="form-row">
|
|
94
|
+
<label for="node-input-statusHook">Status hook</label>
|
|
95
|
+
<input type="text" id="node-input-statusHook" placeholder="webhook url">
|
|
96
|
+
<input type="hidden" id="node-input-statusHookType">
|
|
97
|
+
</div>
|
|
76
98
|
<div class="form-row">
|
|
77
99
|
<label for="node-input-beep">Beep on entry</label>
|
|
78
100
|
<input type="checkbox" id="node-input-beep">
|
|
@@ -86,7 +108,7 @@
|
|
|
86
108
|
<input type="checkbox" id="node-input-endConferenceOnExit">
|
|
87
109
|
</div>
|
|
88
110
|
<div class="form-row">
|
|
89
|
-
<label for="node-input-joinMuted">Join
|
|
111
|
+
<label for="node-input-joinMuted">Join muted</label>
|
|
90
112
|
<input type="checkbox" id="node-input-joinMuted">
|
|
91
113
|
</div>
|
|
92
114
|
<div class="form-row">
|
|
@@ -94,30 +116,31 @@
|
|
|
94
116
|
<input type="text" id="node-input-maxParticipants">
|
|
95
117
|
<input type="hidden" id="node-input-maxParticipantsType">
|
|
96
118
|
</div>
|
|
97
|
-
|
|
119
|
+
</script>
|
|
98
120
|
|
|
99
121
|
<!-- Help Text -->
|
|
100
122
|
<script type="text/html" data-help-name="conference">
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
<
|
|
113
|
-
<
|
|
114
|
-
</
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
<p>Places a caller in a conference.</p>
|
|
124
|
+
<h3>Properties</h3>
|
|
125
|
+
<p><code>Conference Name</code> - The name of the conference to join the caller to.</p>
|
|
126
|
+
<p><code>Enter hook</code> - A webhook to retrieve something to play or say to the caller just before they are put into a conference after waiting for it to start</p>
|
|
127
|
+
<p><code>Wait hook</code> - A webhook to retrieve commands to play or say while the caller is waiting for the conference to start</p>
|
|
128
|
+
<p><code>Action hook</code> - A webhook to call when the conference ends</p>
|
|
129
|
+
<p><code>Status hook</code> - A webhook to call with conference status events</p>
|
|
130
|
+
<p><code>Beep on entry</code> - If checked, play a beep tone to the conference when caller enters </p>
|
|
131
|
+
<p><code>Start on entry</code> - If checked, start the conference only when this caller enters</p>
|
|
132
|
+
<p><code>End on exit</code> - If checked, end the conference when this caller hangs up</p>
|
|
133
|
+
<p><code>Max participants</code> - Maximum number of participants that will be allowed in the conference</p>
|
|
134
|
+
<h3>Outputs</h3>
|
|
135
|
+
<dl class="message-properties">
|
|
136
|
+
<dt>jambonz<span class="property-type">object</span></dt>
|
|
137
|
+
<dd> <code>msg.jambonz</code> will contain any previous actions provided to the input with the new <code>conference</code> action appended </dd>
|
|
138
|
+
</dl>
|
|
139
|
+
<h3>Details</h3>
|
|
140
|
+
The conference verb places a call into a conference.
|
|
141
|
+
<h3>References</h3>
|
|
119
142
|
<ul>
|
|
120
|
-
|
|
143
|
+
<li><a href="https://www.jambonz.org/docs/webhooks/conference/">Jambonz conference reference</a></li>
|
|
121
144
|
</ul>
|
|
122
145
|
</script>
|
|
123
146
|
|
package/src/nodes/conference.js
CHANGED
|
@@ -6,17 +6,20 @@ module.exports = function(RED) {
|
|
|
6
6
|
RED.nodes.createNode(this, config);
|
|
7
7
|
var node = this;
|
|
8
8
|
node.on('input', function(msg) {
|
|
9
|
-
var
|
|
9
|
+
var statusHook = new_resolve(RED, config.statusHook, config.statusHookType, node, msg);
|
|
10
10
|
appendVerb(msg, {
|
|
11
11
|
verb: 'conference',
|
|
12
12
|
name: new_resolve(RED, config.conference, config.conferenceType, node, msg),
|
|
13
13
|
enterHook: new_resolve(RED, config.enterHook, config.enterHookType, node, msg),
|
|
14
14
|
waitHook: new_resolve(RED, config.waitHook, config.waitHookType, node, msg),
|
|
15
|
-
|
|
15
|
+
actionHook: new_resolve(RED, config.actionHook, config.actionHookType, node, msg),
|
|
16
|
+
statusHook,
|
|
17
|
+
...(statusHook && { statusEvents: ['start', 'end', 'join', 'leave'] }),
|
|
18
|
+
maxParticipants: new_resolve(RED, config.maxParticipants, config.maxParticipantsType, node, msg),
|
|
16
19
|
beep: config.beep,
|
|
17
20
|
startConferenceOnEnter: config.startConferenceOnEnter,
|
|
18
|
-
|
|
19
|
-
joinMuted
|
|
21
|
+
endConferenceOnExit: config.endConferenceOnExit,
|
|
22
|
+
joinMuted: config.joinMuted
|
|
20
23
|
});
|
|
21
24
|
node.send(msg);
|
|
22
25
|
});
|
|
@@ -18,10 +18,15 @@
|
|
|
18
18
|
to: {value: '', required: true},
|
|
19
19
|
toType: {value: ''},
|
|
20
20
|
dest: {value: 'phone', required: true},
|
|
21
|
-
timeout: {},
|
|
21
|
+
timeout: {validate: RED.validators.regex(/^\d*$/) },
|
|
22
|
+
tag: {required: true},
|
|
23
|
+
tagType: {value: 'json'},
|
|
22
24
|
application: {value: ''},
|
|
23
25
|
appName: {},
|
|
24
26
|
mode: {value: 'app'},
|
|
27
|
+
callername: {value: ''},
|
|
28
|
+
callernameType: {value: ''},
|
|
29
|
+
headers: {value: []},
|
|
25
30
|
call_hook_url : {},
|
|
26
31
|
call_hook_urlType : {value: 'str'},
|
|
27
32
|
call_hook_method : {value : 'GET'},
|
|
@@ -84,6 +89,15 @@
|
|
|
84
89
|
types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
85
90
|
typeField: $('#node-input-call_status_urlType')
|
|
86
91
|
});
|
|
92
|
+
$('#node-input-callername').typedInput({
|
|
93
|
+
types: ['str', 'msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
94
|
+
typeField: $('#node-input-callernameType')
|
|
95
|
+
});
|
|
96
|
+
$('#node-input-tag').typedInput({
|
|
97
|
+
default: $('#node-input-tagType').val(),
|
|
98
|
+
types: ['json', 'msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
99
|
+
typeField: $('#node-input-tagType')
|
|
100
|
+
});
|
|
87
101
|
|
|
88
102
|
var populateApplications = function() {
|
|
89
103
|
var serverId = $('#node-input-server option:selected').val();
|
|
@@ -127,6 +141,60 @@
|
|
|
127
141
|
|
|
128
142
|
}
|
|
129
143
|
});
|
|
144
|
+
$('#node-input-headers-container').css('min-height','120px').css('min-width','450px').editableList({
|
|
145
|
+
addItem: function(container, i, opt) {
|
|
146
|
+
var header = opt;
|
|
147
|
+
if (!header.hasOwnProperty('h')) {
|
|
148
|
+
header = {h: '', v: ''};
|
|
149
|
+
}
|
|
150
|
+
container.css({
|
|
151
|
+
overflow: 'hidden',
|
|
152
|
+
whiteSpace: 'nowrap'
|
|
153
|
+
});
|
|
154
|
+
let fragment = document.createDocumentFragment();
|
|
155
|
+
var row1 = $('<div/>',{style:"display:flex;"}).appendTo(fragment);
|
|
156
|
+
$('<input/>', {
|
|
157
|
+
class:"node-input-header-property-name",
|
|
158
|
+
type:"text",
|
|
159
|
+
placeholder: 'SIP Header'
|
|
160
|
+
})
|
|
161
|
+
.appendTo(row1);
|
|
162
|
+
$('<input/>', {
|
|
163
|
+
class:"node-input-value-property-name",
|
|
164
|
+
type:"text",
|
|
165
|
+
placeholder: 'value'
|
|
166
|
+
})
|
|
167
|
+
.appendTo(row1);
|
|
168
|
+
row1.find('.node-input-header-property-name').val(header.h);
|
|
169
|
+
row1.find('.node-input-value-property-name').val(header.v);
|
|
170
|
+
container[0].appendChild(fragment);
|
|
171
|
+
},
|
|
172
|
+
removable: true
|
|
173
|
+
});
|
|
174
|
+
if (!this.headers) {
|
|
175
|
+
var header = {
|
|
176
|
+
h: '',
|
|
177
|
+
v: '',
|
|
178
|
+
};
|
|
179
|
+
this.headers = [header];
|
|
180
|
+
}
|
|
181
|
+
for (var i=0; i < this.headers.length; i++) {
|
|
182
|
+
var header = this.headers[i];
|
|
183
|
+
$("#node-input-headers-container").editableList('addItem', header);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
oneditsave: function () {
|
|
187
|
+
var node = this;
|
|
188
|
+
var headers = [];
|
|
189
|
+
$("#node-input-headers-container").editableList('items').each(function(i) {
|
|
190
|
+
var header = $(this);
|
|
191
|
+
var h = header.find(".node-input-header-property-name").val();
|
|
192
|
+
var v = header.find(".node-input-value-property-name").val();
|
|
193
|
+
var obj = {};
|
|
194
|
+
obj[h] = v;
|
|
195
|
+
headers.push({h, v});
|
|
196
|
+
});
|
|
197
|
+
node.headers = headers;
|
|
130
198
|
}
|
|
131
199
|
});
|
|
132
200
|
</script>
|
|
@@ -146,6 +214,11 @@
|
|
|
146
214
|
<input type="text" id="node-input-from" placeholder="calling party number">
|
|
147
215
|
<input type="hidden" id="node-input-fromType">
|
|
148
216
|
</div>
|
|
217
|
+
<div class="form-row">
|
|
218
|
+
<label for="node-input-callername">From name</label>
|
|
219
|
+
<input type="text" id="node-input-callername" placeholder="calling party name">
|
|
220
|
+
<input type="hidden" id="node-input-callernameType">
|
|
221
|
+
</div>
|
|
149
222
|
<div class="form-row">
|
|
150
223
|
<label for="node-input-to">To</label>
|
|
151
224
|
<input type="text" id="node-input-to" placeholder="called party info">
|
|
@@ -163,7 +236,11 @@
|
|
|
163
236
|
<div class="form-row">
|
|
164
237
|
<label for="node-input-timeout">Ring timeout</label>
|
|
165
238
|
<input type="text" id="node-input-timeout" placeholder="ring no answer timeout in secs (default: 60)">
|
|
166
|
-
|
|
239
|
+
</div>
|
|
240
|
+
<div class="form-row">
|
|
241
|
+
<label for="node-input-tag">Tag data</label>
|
|
242
|
+
<input type="text" id="node-input-tag" placeholder="tag object">
|
|
243
|
+
<input type="hidden" id="node-input-tagType">
|
|
167
244
|
</div>
|
|
168
245
|
<div class="form-row">
|
|
169
246
|
<label for="node-input-application">Connect to</label>
|
|
@@ -179,6 +256,15 @@
|
|
|
179
256
|
</select>
|
|
180
257
|
</div>
|
|
181
258
|
</div>
|
|
259
|
+
<fieldset>
|
|
260
|
+
<legend>SIP Headers</legend>
|
|
261
|
+
<div class="form-row" style="margin-bottom:0;">
|
|
262
|
+
<label style="width:100%"><i class="fa fa-list"></i> <span>Add custom headers</span></label>
|
|
263
|
+
</div>
|
|
264
|
+
<div class="form-row node-input-headers-container-row">
|
|
265
|
+
<ol id="node-input-headers-container"></ol>
|
|
266
|
+
</div>
|
|
267
|
+
</fieldset>
|
|
182
268
|
<div id="url-options">
|
|
183
269
|
<fieldset>
|
|
184
270
|
<legend>Webhook options</legend>
|
|
@@ -267,8 +353,10 @@
|
|
|
267
353
|
<h3>Properties</h3>
|
|
268
354
|
<p><code>Server</code> - Jambonz server to connect to</p>
|
|
269
355
|
<p><code>From</code> - Calling party phone number</p>
|
|
356
|
+
<p><code>From name</code> - Calling party name</p>
|
|
270
357
|
<p><code>To</code> - Called party phone number, or other identifier</p>
|
|
271
358
|
<p><code>Call type</code> - Type of destination: phone number, registered user, sip endpoint, or microsoft teams</p>
|
|
359
|
+
<p><code>Tag data</code> - Initial set of customer-supplied metadata to associate with the call</p>
|
|
272
360
|
<p><code>Application</code> - Application to execute when call is answered</p>
|
|
273
361
|
<p><code>Webhooks</code> - Webhooks to execute when call is answered</p>
|
|
274
362
|
|
package/src/nodes/create_call.js
CHANGED
|
@@ -19,16 +19,30 @@ module.exports = function(RED) {
|
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
var from = new_resolve(RED, config.from, config.fromType, node, msg)
|
|
23
|
-
var to =
|
|
22
|
+
var from = new_resolve(RED, config.from, config.fromType, node, msg);
|
|
23
|
+
var to = new_resolve(RED, config.to, config.toType, node, msg);
|
|
24
|
+
var tag = new_resolve(RED, config.tag, config.tagType, node, msg);
|
|
24
25
|
|
|
25
26
|
const opts = {
|
|
26
27
|
from,
|
|
27
28
|
to: {
|
|
28
29
|
type: config.dest
|
|
29
30
|
},
|
|
31
|
+
tag
|
|
30
32
|
};
|
|
31
33
|
|
|
34
|
+
if (config.headers) {
|
|
35
|
+
var headers = {};
|
|
36
|
+
config.headers.forEach(function(h) {
|
|
37
|
+
if (h.h.length && h.v.length) headers[h.h] = h.v;
|
|
38
|
+
});
|
|
39
|
+
Object.assign(opts, {headers});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (config.callername) {
|
|
43
|
+
opts.callerName = new_resolve(RED, config.callername, config.callernameType, node, msg);
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
switch (config.mode) {
|
|
33
47
|
case 'app':
|
|
34
48
|
opts.application_sid = config.application;
|
|
@@ -54,6 +68,7 @@ module.exports = function(RED) {
|
|
|
54
68
|
const timeout = parseInt(config.timeout);
|
|
55
69
|
if (timeout > 0) opts.timeout = timeout;
|
|
56
70
|
}
|
|
71
|
+
|
|
57
72
|
switch (config.dest) {
|
|
58
73
|
case 'phone':
|
|
59
74
|
opts.to.number = to;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!-- Javascript -->
|
|
2
|
+
<script type="text/javascript">
|
|
3
|
+
var mustacheType = {
|
|
4
|
+
value: 'mustache',
|
|
5
|
+
label: 'mustache',
|
|
6
|
+
hasvalue: true,
|
|
7
|
+
icon: 'resources/@jambonz/node-red-contrib-jambonz/icons/mustache.svg'
|
|
8
|
+
}
|
|
9
|
+
RED.nodes.registerType('get_call', {
|
|
10
|
+
category: 'jambonz',
|
|
11
|
+
color: '#aebfb9',
|
|
12
|
+
defaults: {
|
|
13
|
+
name: {value: ''},
|
|
14
|
+
server: {value: '', required: true, type: 'jambonz_auth'},
|
|
15
|
+
callSid: {value: '', validate: function(v) {
|
|
16
|
+
return v.length > 0;
|
|
17
|
+
}},
|
|
18
|
+
callSidType:{value: 'str'},
|
|
19
|
+
},
|
|
20
|
+
inputs: 1,
|
|
21
|
+
outputs: 1,
|
|
22
|
+
icon: "font-awesome/fa-cubes",
|
|
23
|
+
paletteLabel: "Get - Call",
|
|
24
|
+
label: function() { return this.name || 'Get Call';},
|
|
25
|
+
oneditprepare: () => {
|
|
26
|
+
$('#node-input-callSid').typedInput({
|
|
27
|
+
types: ['str','msg', 'flow', 'global', 'jsonata', 'env', mustacheType],
|
|
28
|
+
typeField: $('#node-input-callSidType')
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<!-- HTML -->
|
|
35
|
+
<script type="text/html" data-template-name="get_call">
|
|
36
|
+
<div class="form-row">
|
|
37
|
+
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
38
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
39
|
+
</div>
|
|
40
|
+
<div class="form-row">
|
|
41
|
+
<label for="node-input-server">Server</label>
|
|
42
|
+
<input type="text" id="node-input-server">
|
|
43
|
+
</div>
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label for="node-input-callSid">CallSid</label>
|
|
46
|
+
<input type="text" id="node-input-callSid">
|
|
47
|
+
<input type="hidden" id="node-input-callSidType">
|
|
48
|
+
</div>
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<!-- Help Text -->
|
|
52
|
+
<script type="text/html" data-help-name="get_call">
|
|
53
|
+
<p>Get call</p>
|
|
54
|
+
|
|
55
|
+
<h3>Details</h3>
|
|
56
|
+
Retrieve info for a single call under an account.
|
|
57
|
+
</script>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const bent = require("bent");
|
|
2
|
+
var { new_resolve} = require("./libs");
|
|
3
|
+
|
|
4
|
+
module.exports = function (RED) {
|
|
5
|
+
function get_call(config) {
|
|
6
|
+
RED.nodes.createNode(this, config);
|
|
7
|
+
var node = this;
|
|
8
|
+
const server = RED.nodes.getNode(config.server);
|
|
9
|
+
const { accountSid, apiToken } = server.credentials;
|
|
10
|
+
node.on("input", async (msg, send, done) => {
|
|
11
|
+
const callSid = new_resolve(RED, config.callSid, config.callSidType, node, msg);
|
|
12
|
+
if (!callSid) {
|
|
13
|
+
if (done) done(new Error('CallSid empty'));
|
|
14
|
+
else node.error(new Error('CallSid empty'), msg);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const req = bent(
|
|
18
|
+
`${server.url}/v1/Accounts/${accountSid}/Calls/${callSid}`,
|
|
19
|
+
'GET',
|
|
20
|
+
'json',
|
|
21
|
+
{
|
|
22
|
+
Authorization: `Bearer ${apiToken}`,
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
try {
|
|
26
|
+
const res = await req();
|
|
27
|
+
msg.payload = res;
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (err.statusCode) {
|
|
30
|
+
node.error(`GetCall failed with ${err.statusCode}`);
|
|
31
|
+
msg.statusCode = err.statusCode;
|
|
32
|
+
} else {
|
|
33
|
+
node.error(`Error getting call info ${JSON.stringify(err)}`);
|
|
34
|
+
if (done) done(err);
|
|
35
|
+
else node.error(err, msg);
|
|
36
|
+
send(msg);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
send(msg);
|
|
41
|
+
if (done) done();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
RED.nodes.registerType("get_call", get_call);
|
|
45
|
+
};
|