@jambonz/node-red-contrib-jambonz 2.4.22 → 2.4.24
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 +8 -6
- package/src/nodes/answer.html +35 -0
- package/src/nodes/answer.js +16 -0
- package/src/nodes/config.html +60 -0
- package/src/nodes/config.js +8 -0
- package/src/nodes/dub.html +135 -0
- package/src/nodes/dub.js +24 -0
- package/src/nodes/tag.js +3 -0
- package/src/nodes/userauth.js +0 -3
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.24",
|
|
4
4
|
"description": "Node-RED nodes for jambonz platform",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node-red"
|
|
@@ -48,25 +48,27 @@
|
|
|
48
48
|
"get_alerts": "src/nodes/get_alerts.js",
|
|
49
49
|
"get_call": "src/nodes/get_call.js",
|
|
50
50
|
"get_calls": "src/nodes/get_calls.js",
|
|
51
|
-
"get_recent_calls": "src/nodes/get_recent_calls.js"
|
|
51
|
+
"get_recent_calls": "src/nodes/get_recent_calls.js",
|
|
52
|
+
"answer": "src/nodes/answer.js",
|
|
53
|
+
"dub": "src/nodes/dub.js"
|
|
52
54
|
}
|
|
53
55
|
},
|
|
54
56
|
"author": "Dave Horton",
|
|
55
57
|
"license": "MIT",
|
|
56
58
|
"dependencies": {
|
|
57
|
-
"aws-sdk": "^2.
|
|
59
|
+
"aws-sdk": "^2.1665.0",
|
|
58
60
|
"body-parser": "^1.20.2",
|
|
59
61
|
"cookie-parser": "^1.4.6",
|
|
60
62
|
"cors": "^2.8.5",
|
|
61
63
|
"hash-sum": "^2.0.0",
|
|
62
64
|
"is-utf8": "^0.2.1",
|
|
63
65
|
"media-typer": "^1.1.0",
|
|
64
|
-
"multer": "^1.4.
|
|
66
|
+
"multer": "^1.4.5-lts.1",
|
|
65
67
|
"mustache": "^4.2.0",
|
|
66
68
|
"on-headers": "^1.0.2",
|
|
67
69
|
"raw-body": "^2.5.2",
|
|
68
70
|
"s3-upload-stream": "^1.0.7",
|
|
69
|
-
"undici": "^5.
|
|
70
|
-
"ws": "^8.
|
|
71
|
+
"undici": "^5.28.4",
|
|
72
|
+
"ws": "^8.18.0"
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<!-- Javascript -->
|
|
2
|
+
<script type="text/javascript">
|
|
3
|
+
RED.nodes.registerType('answer',{
|
|
4
|
+
category: 'jambonz',
|
|
5
|
+
color: '#bbabaa',
|
|
6
|
+
defaults: {
|
|
7
|
+
name: {value: ''},
|
|
8
|
+
},
|
|
9
|
+
inputs: 1,
|
|
10
|
+
outputs: 1,
|
|
11
|
+
icon: "font-awesome/fa-cubes",
|
|
12
|
+
label: function() { return this.name || 'answer';},
|
|
13
|
+
});
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<!-- HTML -->
|
|
17
|
+
<script type="text/html" data-template-name="answer">
|
|
18
|
+
<div class="form-row">
|
|
19
|
+
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
20
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
21
|
+
</div>
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<!-- Help Text -->
|
|
25
|
+
<script type="text/html" data-help-name="answer">
|
|
26
|
+
<p>Answer the call</p>
|
|
27
|
+
|
|
28
|
+
<h3>Details</h3>
|
|
29
|
+
This is rarely used, as the call is typically answered automatically when required by the app,
|
|
30
|
+
but it can be useful to force an answer before a pause in some cases.
|
|
31
|
+
<h3>References</h3>
|
|
32
|
+
<ul>
|
|
33
|
+
<li><a href="https://www.jambonz.org/docs/webhooks/answer/">Jambonz answer reference</a></li>
|
|
34
|
+
</ul>
|
|
35
|
+
</script>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var {appendVerb} = require('./libs')
|
|
2
|
+
|
|
3
|
+
module.exports = function(RED) {
|
|
4
|
+
function answer(config) {
|
|
5
|
+
RED.nodes.createNode(this, config);
|
|
6
|
+
var node = this;
|
|
7
|
+
node.on('input', function(msg) {
|
|
8
|
+
var data = {
|
|
9
|
+
verb: 'answer'
|
|
10
|
+
};
|
|
11
|
+
appendVerb(msg, data);
|
|
12
|
+
node.send(msg);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
RED.nodes.registerType('answer', answer);
|
|
16
|
+
}
|
package/src/nodes/config.html
CHANGED
|
@@ -83,6 +83,14 @@
|
|
|
83
83
|
sipRequest: { value: false },
|
|
84
84
|
sipRequestWithinDialogHook: { value: "" },
|
|
85
85
|
sipRequestWithinDialogHookType: { value: "str" },
|
|
86
|
+
|
|
87
|
+
onHold: { value: false },
|
|
88
|
+
onHoldMusic: { value: "" },
|
|
89
|
+
onHoldMusicType: { value: "str" },
|
|
90
|
+
|
|
91
|
+
boostAudioSignal: { value: false },
|
|
92
|
+
boostAudioSignalLevel: { value: "" },
|
|
93
|
+
boostAudioSignalLevelType: { value: "str" },
|
|
86
94
|
},
|
|
87
95
|
inputs: 1,
|
|
88
96
|
outputs: 1,
|
|
@@ -263,6 +271,32 @@
|
|
|
263
271
|
}
|
|
264
272
|
});
|
|
265
273
|
|
|
274
|
+
$("#node-input-onHoldMusic").typedInput({
|
|
275
|
+
types: ["str", "msg", "flow", "global", "jsonata", "env", mustacheType],
|
|
276
|
+
typeField: $("#node-input-onHoldMusicType"),
|
|
277
|
+
});
|
|
278
|
+
$("#node-input-onHold").change(function () {
|
|
279
|
+
const doSipRequest = $("#node-input-onHold:checked").val();
|
|
280
|
+
if (doSipRequest) {
|
|
281
|
+
$("#onHold-options").show();
|
|
282
|
+
} else {
|
|
283
|
+
$("#onHold-options").hide();
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
$("#node-input-boostAudioSignalLevel").typedInput({
|
|
288
|
+
types: ["str", "msg", "flow", "global", "jsonata", "env", mustacheType],
|
|
289
|
+
typeField: $("#node-input-boostAudioSignalLevelType"),
|
|
290
|
+
});
|
|
291
|
+
$("#node-input-boostAudioSignal").change(function () {
|
|
292
|
+
const doSipRequest = $("#node-input-boostAudioSignal:checked").val();
|
|
293
|
+
if (doSipRequest) {
|
|
294
|
+
$("#boostAudioSignal-options").show();
|
|
295
|
+
} else {
|
|
296
|
+
$("#boostAudioSignal-options").hide();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
266
300
|
$("#node-input-listenRequest").change(function () {
|
|
267
301
|
const doListen = $("#node-input-listenRequest:checked").val();
|
|
268
302
|
if (doListen) {
|
|
@@ -569,6 +603,32 @@
|
|
|
569
603
|
<input type="hidden" id="node-input-sipRequestWithinDialogHookType">
|
|
570
604
|
</div>
|
|
571
605
|
</div>
|
|
606
|
+
|
|
607
|
+
<legend>On Hold Music</legend>
|
|
608
|
+
<div class="form-row">
|
|
609
|
+
<label for="node-input-onHold">Modify On Hold Music</label>
|
|
610
|
+
<input type="checkbox" id="node-input-onHold">
|
|
611
|
+
</div>
|
|
612
|
+
<div id="onHold-options">
|
|
613
|
+
<div class="form-row">
|
|
614
|
+
<label for="node-input-onHoldMusic">Url</label>
|
|
615
|
+
<input type="text" id="node-input-onHoldMusic">
|
|
616
|
+
<input type="hidden" id="node-input-onHoldMusicType">
|
|
617
|
+
</div>
|
|
618
|
+
</div>
|
|
619
|
+
|
|
620
|
+
<legend>Boost Audio Signal</legend>
|
|
621
|
+
<div class="form-row">
|
|
622
|
+
<label for="node-input-boostAudioSignal">Boost Audio</label>
|
|
623
|
+
<input type="checkbox" id="node-input-boostAudioSignal">
|
|
624
|
+
</div>
|
|
625
|
+
<div id="boostAudioSignal-options">
|
|
626
|
+
<div class="form-row">
|
|
627
|
+
<label for="node-input-boostAudioSignalLevel">Level</label>
|
|
628
|
+
<input type="text" id="node-input-boostAudioSignalLevel">
|
|
629
|
+
<input type="hidden" id="node-input-boostAudioSignalLevelType">
|
|
630
|
+
</div>
|
|
631
|
+
</div>
|
|
572
632
|
</fieldset>
|
|
573
633
|
</script>
|
|
574
634
|
|
package/src/nodes/config.js
CHANGED
|
@@ -86,6 +86,14 @@ module.exports = function(RED) {
|
|
|
86
86
|
if (config.sipRequest) {
|
|
87
87
|
config.sipRequestWithinDialogHook != '' ? obj.sipRequestWithinDialogHook = new_resolve(RED, config.sipRequestWithinDialogHook, config.sipRequestWithinDialogHookType, node, msg) : null;
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
if (config.onHold) {
|
|
91
|
+
config.onHoldMusic != '' ? obj.onHoldMusic = new_resolve(RED, config.onHoldMusic, config.onHoldMusicType, node, msg) : null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (config.boostAudioSignal) {
|
|
95
|
+
config.boostAudioSignal != '' ? obj.boostAudioSignal = new_resolve(RED, config.boostAudioSignalLevel, config.boostAudioSignalLevelType, node, msg) : null;
|
|
96
|
+
}
|
|
89
97
|
appendVerb(msg, obj);
|
|
90
98
|
node.send(msg);
|
|
91
99
|
});
|
|
@@ -0,0 +1,135 @@
|
|
|
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("dub", {
|
|
10
|
+
category: "jambonz",
|
|
11
|
+
color: "#bbabaa",
|
|
12
|
+
defaults: {
|
|
13
|
+
name: { value: "" },
|
|
14
|
+
action: { value: "addTrack" },
|
|
15
|
+
track: { value: "" },
|
|
16
|
+
trackType: { value: "str" },
|
|
17
|
+
play: { value: "" },
|
|
18
|
+
playType: { value: "str" },
|
|
19
|
+
say: { value: "" },
|
|
20
|
+
sayType: { value: "str" },
|
|
21
|
+
loop: { value: false },
|
|
22
|
+
gain: {
|
|
23
|
+
value: "",
|
|
24
|
+
validate: function (v) {
|
|
25
|
+
if (v.length) {
|
|
26
|
+
return v.match(/([+-]?\d+(\.\d+)?)\s*db/i) !== null;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
inputs: 1,
|
|
33
|
+
outputs: 1,
|
|
34
|
+
icon: "font-awesome/fa-cubes",
|
|
35
|
+
label: function () {
|
|
36
|
+
return this.name || "dub";
|
|
37
|
+
},
|
|
38
|
+
oneditprepare: function () {
|
|
39
|
+
var node = this;
|
|
40
|
+
$("#node-input-track").typedInput({
|
|
41
|
+
types: ["str", "msg", "flow", "global", "jsonata", "env", mustacheType],
|
|
42
|
+
typeField: $("#node-input-trackType"),
|
|
43
|
+
});
|
|
44
|
+
$("#node-input-play").typedInput({
|
|
45
|
+
types: ["str", "msg", "flow", "global", "jsonata", "env", mustacheType],
|
|
46
|
+
typeField: $("#node-input-playType"),
|
|
47
|
+
});
|
|
48
|
+
$("#node-input-say").typedInput({
|
|
49
|
+
types: ["str", "msg", "flow", "global", "jsonata", "env", mustacheType],
|
|
50
|
+
typeField: $("#node-input-sayType"),
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<!-- HTML -->
|
|
57
|
+
<script type="text/html" data-template-name="dub">
|
|
58
|
+
<div class="form-row">
|
|
59
|
+
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
|
|
60
|
+
<input type="text" id="node-input-name" placeholder="Name" />
|
|
61
|
+
</div>
|
|
62
|
+
<div class="form-row">
|
|
63
|
+
<label for="node-input-action">Action</label>
|
|
64
|
+
<select id="node-input-action">
|
|
65
|
+
<option value="addTrack">addTrack</option>
|
|
66
|
+
<option value="removeTrack">removeTrack</option>
|
|
67
|
+
<option value="silenceTrack">silenceTrack</option>
|
|
68
|
+
<option value="playOnTrack">playOnTrack</option>
|
|
69
|
+
<option value="sayOnTrack">sayOnTrack</option>
|
|
70
|
+
</select>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="form-row">
|
|
73
|
+
<label for="node-input-track">Track</label>
|
|
74
|
+
<input type="text" id="node-input-track" placeholder="The label for the track">
|
|
75
|
+
<input type="hidden" id="node-input-trackType">
|
|
76
|
+
</div>
|
|
77
|
+
<div class="form-row">
|
|
78
|
+
<label for="node-input-play">Play</label>
|
|
79
|
+
<input type="text" id="node-input-play" placeholder="The http(s) url to an mp3 file">
|
|
80
|
+
<input type="hidden" id="node-input-playType">
|
|
81
|
+
</div>
|
|
82
|
+
<div class="form-row">
|
|
83
|
+
<label for="node-input-say">Say</label>
|
|
84
|
+
<input type="text" id="node-input-say" placeholder="The label for the play">
|
|
85
|
+
<input type="hidden" id="node-input-sayType">
|
|
86
|
+
</div>
|
|
87
|
+
<div class="form-row">
|
|
88
|
+
<label for="node-input-loop">Loop</label>
|
|
89
|
+
<input type="checkbox" id="node-input-loop" />
|
|
90
|
+
</div>
|
|
91
|
+
<div class="form-row">
|
|
92
|
+
<label for="node-input-gain">Gain</label>
|
|
93
|
+
<input
|
|
94
|
+
type="text"
|
|
95
|
+
id="node-input-gain"
|
|
96
|
+
placeholder="The value must be between +- 50 dB"
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<!-- Help Text -->
|
|
102
|
+
<script type="text/html" data-help-name="dub">
|
|
103
|
+
<p>Adds one or more additional audio tracks</p>
|
|
104
|
+
<h3>Inputs</h3>
|
|
105
|
+
<h3>Properties</h3>
|
|
106
|
+
<p>
|
|
107
|
+
<code>Action</code> - One of 'addTrack', 'removeTrack', 'silenceTrack',
|
|
108
|
+
'playOnTrack', or 'sayOnTrack'.
|
|
109
|
+
</p>
|
|
110
|
+
<p><code>Track</code> - Label for the track</p>
|
|
111
|
+
<p>
|
|
112
|
+
<code>Play</code> - An http(s) url to an mp3 file to play into the track
|
|
113
|
+
</p>
|
|
114
|
+
<p><code>Loop</code> - Loop the mp3</p>
|
|
115
|
+
<p>
|
|
116
|
+
<code>Gain</code> - Decibels to boost or reduce the strength of the audio
|
|
117
|
+
signal
|
|
118
|
+
</p>
|
|
119
|
+
|
|
120
|
+
<h3>Details</h3>
|
|
121
|
+
The dub verb adds one or more additional audio tracks into the conversation
|
|
122
|
+
(currently, a max of two additional audio tracks may be added). Audio can then
|
|
123
|
+
be inserted into these tracks and it will be blended with the play or say
|
|
124
|
+
content being sent to the caller/called party. The source of the audio content
|
|
125
|
+
can be either text to speech or mp3 audio accessible via http(s).
|
|
126
|
+
|
|
127
|
+
<h3>References</h3>
|
|
128
|
+
<ul>
|
|
129
|
+
<li>
|
|
130
|
+
<a href="https://www.jambonz.org/docs/webhooks/dub/"
|
|
131
|
+
>Jambonz dub reference</a
|
|
132
|
+
>
|
|
133
|
+
</li>
|
|
134
|
+
</ul>
|
|
135
|
+
</script>
|
package/src/nodes/dub.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var {appendVerb, new_resolve} = require('./libs')
|
|
2
|
+
|
|
3
|
+
module.exports = function(RED) {
|
|
4
|
+
/** dub */
|
|
5
|
+
function dub(config) {
|
|
6
|
+
RED.nodes.createNode(this, config);
|
|
7
|
+
var node = this;
|
|
8
|
+
|
|
9
|
+
node.on('input', function(msg) {
|
|
10
|
+
var obj = {
|
|
11
|
+
verb: 'dub',
|
|
12
|
+
action: config.action,
|
|
13
|
+
track: new_resolve(RED, config.track, config.trackType, node, msg),
|
|
14
|
+
play: new_resolve(RED, config.play, config.playType, node, msg),
|
|
15
|
+
say: new_resolve(RED, config.say, config.sayType, node, msg),
|
|
16
|
+
loop: config.loop,
|
|
17
|
+
gain: config.gain
|
|
18
|
+
};
|
|
19
|
+
appendVerb(msg, obj);
|
|
20
|
+
node.send(msg);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
RED.nodes.registerType('dub', dub);
|
|
24
|
+
}
|
package/src/nodes/tag.js
CHANGED
|
@@ -6,6 +6,9 @@ module.exports = function(RED) {
|
|
|
6
6
|
var node = this;
|
|
7
7
|
node.on('input', function(msg) {
|
|
8
8
|
var data = new_resolve(RED, config.data, config.dataType, node, msg);
|
|
9
|
+
if (typeof(data) != 'object'){
|
|
10
|
+
data = JSON.parse(data)
|
|
11
|
+
}
|
|
9
12
|
appendVerb(msg, {
|
|
10
13
|
verb: 'tag',
|
|
11
14
|
data
|
package/src/nodes/userauth.js
CHANGED
|
@@ -7,8 +7,6 @@ module.exports = function(RED) {
|
|
|
7
7
|
RED.nodes.createNode(this, config);
|
|
8
8
|
var node = this;
|
|
9
9
|
node.on('input', function(msg) {
|
|
10
|
-
console.log(config.directUser)
|
|
11
|
-
console.log(config.directUserType)
|
|
12
10
|
var attemptedAuthentication = false;
|
|
13
11
|
var auth = msg.authRequest;
|
|
14
12
|
var authResponse = {};
|
|
@@ -62,7 +60,6 @@ module.exports = function(RED) {
|
|
|
62
60
|
const directUser = new_resolve(RED, config.directUser, config.directUserType, node, msg);
|
|
63
61
|
const directApp = new_resolve(RED, config.directApp, config.directAppType, node, msg);
|
|
64
62
|
const directQueue = new_resolve(RED, config.directQueue, config.directQueueType, node, msg);
|
|
65
|
-
console.log(directUser)
|
|
66
63
|
Object.assign(authResponse, {
|
|
67
64
|
status: 'ok',
|
|
68
65
|
expires: grantedExpires != null ? grantedExpires : null,
|