@babblevoice/babble-drachtio-callmanager 1.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Nick Knight
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # babble-drachtio-callmanager
2
+
3
+ Provide simplified interface to handle calls with drachtio. This project pulls together all of the required components for a scalable PBX. A registrar, RTP engine.
4
+
5
+ This project interfaces with babble-projectrtp.
6
+
7
+ ```javascript
8
+
9
+ const Srf = require( "drachtio-srf" )
10
+ const Registrar = require( "babble-drachtio-registrar" )
11
+ const CallManager = require( "babble-drachtio-callmanager" )
12
+ const config = require( "config" )
13
+
14
+ const srf = new Srf()
15
+ srf.connect( config.drachtio )
16
+
17
+ srf.on( "connect", ( err, hostport ) => {
18
+ console.log( `Connected to a drachtio server listening on: ${hostport}` )
19
+ } )
20
+
21
+ /* A simple example of looking up a password in our config */
22
+ function passwordLookup( username, realm, callback ) {
23
+ realm = realm.split( "." ).reverse().join( "." )
24
+ let key = "directory." + realm + "." + username
25
+ if( !config.has( key ) ) {
26
+ return callback( null, false )
27
+ }
28
+
29
+ key += ".secret"
30
+ return callback( null, config.get( key ) )
31
+ }
32
+
33
+ const r = new Registrar( {
34
+ "srf": srf,
35
+ //"optionsping": 30, /* Seconds between our OPTIONs packet to registered client - controls the stale flag */
36
+ "regping": 30, /* Number of seconds we force the client to reregister without requiring reauth - controls the stale flag */
37
+ "staletime": 180, /* number of seconds we consider a client stale if we don't hear a response from an OPTIONS or REGISTER ping */
38
+ "expires": 3600, /* default expires */
39
+ "minexpires": 3600, /* Force the client with 423 to extend expires to this amount - conflicts with regping */
40
+ "passwordLookup": passwordLookup
41
+ } )
42
+
43
+
44
+ const cm = new CallManager( {
45
+ "srf": srf,
46
+ "registrar": r,
47
+ "passwordLookup": passwordLookup
48
+ } )
49
+
50
+ cm.on( "call", async ( c ) => {
51
+
52
+ } )
53
+ ```
54
+
55
+ When call manager presents a new call it passes a call object as part of it. The original req and res from Drachtio are members of this object. The call object also has the following methods.
56
+
57
+ CallManager takes an options object as part of its construction. srf and a passwordLookup function are required. Options for codecs and transcoding can also be supplied:
58
+
59
+ ```json
60
+ {
61
+ "srf": srf,
62
+ "passwordLookup": passwordLookup,
63
+ "preferedcodecs": "pcmu pcma 2833",
64
+ "transcode": true
65
+ }
66
+ ```
67
+
68
+
69
+ ## auth
70
+
71
+ Forces the client to authenticate. Returns a promise.
72
+
73
+ ## ring
74
+
75
+ Sends back 180 (ringing).
76
+
77
+ ## busy
78
+
79
+ Ends the call with busy.
80
+
81
+ ## answer
82
+
83
+ Answers the call (creates a dialog) and opens the required channel. Returns a promise.
84
+
85
+ ## audio
86
+
87
+ Returns the audio channel.
88
+
89
+ ## hangup( cause )
90
+
91
+ Ends the call (or cancels).
92
+
93
+ ## waitforevents( regex, timeout = 30000mS )
94
+
95
+ Waits for telephone events (DTMF). We pass a regular expression in to match the entered digits. In the example below, 2 digits (any in the DTMF range) are required followed by the hash key.
96
+
97
+ If the user dials 123456 = it will not trigger as there is no '#' at the end. If they dial 1234567# then it will return with e = 67#
98
+
99
+ ```javascript
100
+ var e = await call.waitforevents( /[0-9A-D\*#]{2}#/ )
101
+ console.log( "waited and got " + e )
102
+ ```
103
+
104
+ ## waitforhangup
105
+
106
+ Returns a promise which is resolved when the call object is hungup. Useful if you wish to further actions when a child call has hung up.
107
+
108
+ ## Events
109
+
110
+ Events are published to either a global event emitter and a call specific one. This allows us to pass events back to a presences system (global) or for a call script to handle an event for that call.
111
+
112
+ To subscribe to call specific events:
113
+
114
+ ```javascript
115
+ cm.on( "call", async ( c ) => {
116
+ c.on( "call.destroyed", ( call ) => {
117
+ /* clean up */
118
+ } )
119
+ } )
120
+ ```
121
+
122
+ # Examples
123
+
124
+ Authorise the call, sending ringing then answer. Once answered, echo RTP data back to the client.
125
+
126
+ ```javascript
127
+ cm.on( "call", async ( c ) => {
128
+
129
+ await call.auth()
130
+ call.ring()
131
+ await call.answer()
132
+
133
+ call.channels.audio.echo()
134
+ } )
135
+ ```
136
+
137
+ An example for prompting and waiting for DTMF (auto attendant).
138
+
139
+ No auth or need to send ringing, we answer and when answered, we play a file then wait for caller to enter input.
140
+ ```javascript
141
+ cm.on( "call", async ( c ) => {
142
+
143
+ await call.answer()
144
+
145
+ call.channels.audio.play( { "files": [ { "wav": "pleasedialoneforsalesandtwofortech.wav" } ] } )
146
+
147
+ var e = await call.waitforevents( /[0-1]/ )
148
+ console.log( "waited and got " + e )
149
+ } )
150
+ ```
151
+
152
+ # JSDoc
153
+
154
+ jsdoc -r -p lib/
155
+
156
+ # Development
157
+
158
+ I use to develop locally other modules against this module
159
+
160
+ npm link projectrtp
161
+ npm link babble-drachtio-registrar
162
+ npm link babble-drachtio-auth
163
+
164
+ # References
165
+
166
+ * SIP: Session Initiation Protocol [RFC 3261](https://tools.ietf.org/html/rfc3261)
167
+ * The Session Initiation Protocol (SIP) Refer Method [RFC 3515](https://tools.ietf.org/html/rfc3515)
168
+ * Session Initiation Protocol (SIP) Call Control - Transfer [RFC 5589](https://tools.ietf.org/html/rfc5589)
169
+ * Session Timers in the Session Initiation Protocol (SIP) [RFC 4028](https://tools.ietf.org/html/rfc4028)
170
+ * Session Initiation Protocol Service Examples [RFC 5359](https://tools.ietf.org/html/rfc5359)
171
+ * HTTP Authentication: Basic and Digest Access Authentication [RFC 2617](https://tools.ietf.org/html/rfc2617)
172
+ * SIP Digest examples [draft-smith-sipping-auth-examples-01](https://datatracker.ietf.org/doc/html/draft-smith-sipping-auth-examples-01)
173
+ * Extended Secure RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/SAVPF) [RFC 5124](https://tools.ietf.org/html/rfc5124)
174
+ * Source-Specific Media Attributes in the Session Description Protocol (SDP)[RFC 5576](https://tools.ietf.org/html/rfc5576)
175
+ * Cross Session Stream Identification in the Session Description Protocol (msid in SDP) [draft-ietf-mmusic-msid-00](https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-msid-00)
176
+
177
+ Need to look at
178
+
179
+ * A Framework for Conferencing with the Session Initiation Protocol (SIP) [RFC 4353](https://tools.ietf.org/html/rfc4353)
package/index.js ADDED
@@ -0,0 +1,45 @@
1
+
2
+ const assert = require( "assert" )
3
+ const callmanager = require( "./lib/callmanager.js" )
4
+ const store = require( "./lib/store.js" )
5
+
6
+ const projectrtp = require( "projectrtp" ).projectrtp
7
+
8
+ const default_options = {
9
+ "preferedcodecs": "g722 ilbc pcmu pcma",
10
+ "transcode": true,
11
+ "uactimeout": 30000, /* timeout when calling a client */
12
+ "seexpire": 120000, /* session expires timeout */
13
+ "rfc2833": true, /* Enable RFC 2833 - DTMF */
14
+ "late": false, /* Late negotiation */
15
+ "registrar": false /* our registrar object or falsey */
16
+ }
17
+
18
+ /**
19
+ @param { object } options - see default_options
20
+ @returns { callmanager }
21
+ */
22
+ module.exports.callmanager = ( options ) => {
23
+ let ouroptions = { ...default_options, ...options }
24
+ return callmanager.callmanager( ouroptions )
25
+ }
26
+
27
+ /**
28
+ Expose our RTP interface
29
+ */
30
+ module.exports.projectrtp = projectrtp
31
+
32
+ /**
33
+ * Hangup Codes
34
+ */
35
+ module.exports.hangupcodes = callmanager.hangupcodes
36
+
37
+ /**
38
+ * Call store
39
+ */
40
+ module.exports.store = store
41
+
42
+ /**
43
+ * Call
44
+ */
45
+ module.exports.call = callmanager.call
@@ -0,0 +1,18 @@
1
+ {
2
+ "plugins": ["plugins/markdown"],
3
+ "recurseDepth": 10,
4
+ "source": {
5
+ "include": [ "index.js", "test", "test/interface", "lib" ],
6
+ "includePattern": ".+\\.js(doc|x)?$",
7
+ "excludePattern": "(^|\\/|\\\\)_"
8
+ },
9
+ "sourceType": "module",
10
+ "tags": {
11
+ "allowUnknownTags": true,
12
+ "dictionaries": ["jsdoc","closure"]
13
+ },
14
+ "templates": {
15
+ "cleverLinks": false,
16
+ "monospaceLinks": false
17
+ }
18
+ }