crisp-api 5.3.0 → 6.0.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.
- package/CHANGELOG.md +15 -0
- package/README.md +8 -2
- package/lib/crisp.js +119 -42
- package/package.json +3 -4
- package/types/crisp.d.ts +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## v6.0.0
|
|
5
|
+
|
|
6
|
+
### Breaking Changes
|
|
7
|
+
|
|
8
|
+
* Support for NodeJS 6 has been removed. The minimum version is now NodeJS 8.
|
|
9
|
+
* The `CrispClient.on` method now returns a `Promise`. Please update your code accordingly. We do recommend that you add error catchers.
|
|
10
|
+
|
|
11
|
+
### New Features
|
|
12
|
+
|
|
13
|
+
* The RTM API URL is now dynamically pulled from the REST API, based on the authentication tier. This allows for (much) more efficient message routing at Crisp scale, and offers performance and stability benefits to your integration.
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* Fixed an issue where the library would not reconnect to the RTM API when it lost connection with the server.
|
|
18
|
+
|
|
4
19
|
## v5.3.0
|
|
5
20
|
|
|
6
21
|
### New Features
|
package/README.md
CHANGED
|
@@ -79,7 +79,13 @@ CrispClient.on("message:send", function(message) {
|
|
|
79
79
|
.catch(function(error) {
|
|
80
80
|
console.error("Error sending message:", error);
|
|
81
81
|
});
|
|
82
|
-
})
|
|
82
|
+
})
|
|
83
|
+
.then(function() {
|
|
84
|
+
console.error("Requested to listen to sent messages");
|
|
85
|
+
})
|
|
86
|
+
.catch(function(error) {
|
|
87
|
+
console.error("Failed listening to sent messages:", error);
|
|
88
|
+
});
|
|
83
89
|
```
|
|
84
90
|
|
|
85
91
|
## Resource Methods
|
|
@@ -2338,7 +2344,7 @@ _👉 Notice: The `peopleID` argument can be an email or the `peopleID`._
|
|
|
2338
2344
|
|
|
2339
2345
|
You can bind to realtime events from Crisp, in order to get notified of incoming messages and updates in websites.
|
|
2340
2346
|
|
|
2341
|
-
You won't receive any event if you don't explicitly subscribe to realtime events using `CrispClient.on()`, as the library doesn't connect to the realtime backend automatically.
|
|
2347
|
+
You won't receive any event if you don't explicitly subscribe to realtime events using `CrispClient.on()`, as the library doesn't connect to the realtime backend automatically. This method returns a `Promise` object.
|
|
2342
2348
|
|
|
2343
2349
|
Available events are listed below:
|
|
2344
2350
|
|
package/lib/crisp.js
CHANGED
|
@@ -10,15 +10,12 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
// Imports
|
|
13
|
-
var pkg = require(
|
|
13
|
+
var pkg = require("../package.json");
|
|
14
14
|
var got = require("got");
|
|
15
15
|
|
|
16
|
+
var URL = require("url").URL;
|
|
16
17
|
var EventEmitter = require("fbemitter").EventEmitter;
|
|
17
18
|
|
|
18
|
-
var __Promise = (
|
|
19
|
-
(typeof Promise !== "undefined") ? Promise : require("q").Promise
|
|
20
|
-
);
|
|
21
|
-
|
|
22
19
|
|
|
23
20
|
// Base configuration
|
|
24
21
|
Crisp.DEFAULT_REQUEST_TIMEOUT = 10000;
|
|
@@ -36,8 +33,6 @@ Crisp.DEFAULT_REST_BASE_PATH = "/v1/";
|
|
|
36
33
|
|
|
37
34
|
|
|
38
35
|
// RTM API defaults
|
|
39
|
-
Crisp.DEFAULT_RTM_HOST = "https://app.relay.crisp.chat";
|
|
40
|
-
|
|
41
36
|
Crisp.DEFAULT_RTM_EVENTS = [
|
|
42
37
|
// Session Events
|
|
43
38
|
"session:update_availability",
|
|
@@ -165,7 +160,7 @@ function Crisp() {
|
|
|
165
160
|
|
|
166
161
|
/** @private */
|
|
167
162
|
this._rtm = {
|
|
168
|
-
host :
|
|
163
|
+
host : null
|
|
169
164
|
};
|
|
170
165
|
|
|
171
166
|
/** @private */
|
|
@@ -270,7 +265,7 @@ Crisp.prototype = {
|
|
|
270
265
|
head : function(resource, query, body) {
|
|
271
266
|
var self = this;
|
|
272
267
|
|
|
273
|
-
return new
|
|
268
|
+
return new Promise(function(resolve, reject) {
|
|
274
269
|
self._request(
|
|
275
270
|
resource, "head", (query || {}), null, resolve, reject
|
|
276
271
|
);
|
|
@@ -288,7 +283,7 @@ Crisp.prototype = {
|
|
|
288
283
|
get : function(resource, query) {
|
|
289
284
|
var self = this;
|
|
290
285
|
|
|
291
|
-
return new
|
|
286
|
+
return new Promise(function(resolve, reject) {
|
|
292
287
|
self._request(
|
|
293
288
|
resource, "get", (query || {}), null, resolve, reject
|
|
294
289
|
);
|
|
@@ -306,7 +301,7 @@ Crisp.prototype = {
|
|
|
306
301
|
post : function(resource, query, body) {
|
|
307
302
|
var self = this;
|
|
308
303
|
|
|
309
|
-
return new
|
|
304
|
+
return new Promise(function(resolve, reject) {
|
|
310
305
|
self._request(
|
|
311
306
|
resource, "post", (query || {}), (body || {}), resolve, reject
|
|
312
307
|
);
|
|
@@ -324,7 +319,7 @@ Crisp.prototype = {
|
|
|
324
319
|
patch : function(resource, query, body) {
|
|
325
320
|
var self = this;
|
|
326
321
|
|
|
327
|
-
return new
|
|
322
|
+
return new Promise(function(resolve, reject) {
|
|
328
323
|
self._request(
|
|
329
324
|
resource, "patch", (query || {}), (body || {}), resolve, reject
|
|
330
325
|
);
|
|
@@ -342,7 +337,7 @@ Crisp.prototype = {
|
|
|
342
337
|
put : function(resource, query, body) {
|
|
343
338
|
var self = this;
|
|
344
339
|
|
|
345
|
-
return new
|
|
340
|
+
return new Promise(function(resolve, reject) {
|
|
346
341
|
self._request(
|
|
347
342
|
resource, "put", (query || {}), (body || {}), resolve, reject
|
|
348
343
|
);
|
|
@@ -360,7 +355,7 @@ Crisp.prototype = {
|
|
|
360
355
|
delete : function(resource, query, body) {
|
|
361
356
|
var self = this;
|
|
362
357
|
|
|
363
|
-
return new
|
|
358
|
+
return new Promise(function(resolve, reject) {
|
|
364
359
|
self._request(
|
|
365
360
|
resource, "delete", (query || {}), (body || null), resolve, reject
|
|
366
361
|
);
|
|
@@ -409,7 +404,7 @@ Crisp.prototype = {
|
|
|
409
404
|
this._boundEvents.push(event);
|
|
410
405
|
|
|
411
406
|
// Socket not connected? Connect now.
|
|
412
|
-
this._prepareSocket(
|
|
407
|
+
return this._prepareSocket(
|
|
413
408
|
function(socket, emitter) {
|
|
414
409
|
// Listen for event (once socket is bound)
|
|
415
410
|
socket.on(event, function(data) {
|
|
@@ -418,6 +413,8 @@ Crisp.prototype = {
|
|
|
418
413
|
}
|
|
419
414
|
);
|
|
420
415
|
}
|
|
416
|
+
|
|
417
|
+
return Promise.resolve();
|
|
421
418
|
},
|
|
422
419
|
|
|
423
420
|
/**
|
|
@@ -455,7 +452,10 @@ Crisp.prototype = {
|
|
|
455
452
|
// No resources defined in service?
|
|
456
453
|
if (!serviceInstance._resources ||
|
|
457
454
|
serviceInstance._resources.length === 0) {
|
|
458
|
-
throw new Error(
|
|
455
|
+
throw new Error(
|
|
456
|
+
"[Crisp] prepareServices: service '" + name + "' has no resources " +
|
|
457
|
+
"defined"
|
|
458
|
+
);
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
// Prepare all resources (for service)
|
|
@@ -471,9 +471,9 @@ Crisp.prototype = {
|
|
|
471
471
|
* Binds resources to the service object
|
|
472
472
|
* @memberof Crisp
|
|
473
473
|
* @private
|
|
474
|
+
* @method _prepareResources
|
|
474
475
|
* @param {object} serviceInstance
|
|
475
476
|
* @param {Array} resources
|
|
476
|
-
* @method _prepareResources
|
|
477
477
|
*/
|
|
478
478
|
_prepareResources : function(serviceInstance, resources) {
|
|
479
479
|
for (var i = 0; i < resources.length; i++) {
|
|
@@ -494,41 +494,116 @@ Crisp.prototype = {
|
|
|
494
494
|
_prepareSocket : function(fnBindHook) {
|
|
495
495
|
var self = this;
|
|
496
496
|
|
|
497
|
-
|
|
497
|
+
return new Promise(function(resolve, reject) {
|
|
498
|
+
var rtmHostOverride = self._rtm.host;
|
|
499
|
+
|
|
500
|
+
// Append bind hook to pending stack
|
|
501
|
+
self._socketBindHooks.push(fnBindHook);
|
|
498
502
|
|
|
499
|
-
|
|
500
|
-
|
|
503
|
+
// Make sure to prepare socket once? (defer socket binding, waiting that \
|
|
504
|
+
// all listeners have been bound, that way we submit the list of \
|
|
505
|
+
// filtered events to the RTM API once, and never again in the future)
|
|
506
|
+
if (self._socketScheduler === null) {
|
|
507
|
+
// Socket is already set? We should not even have entered there.
|
|
508
|
+
if (self._socket) {
|
|
509
|
+
throw new Error(
|
|
510
|
+
"[Crisp] prepareSocket: illegal call to prepare socket (tie break)"
|
|
511
|
+
);
|
|
512
|
+
}
|
|
501
513
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
514
|
+
self._socketScheduler = setTimeout(function() {
|
|
515
|
+
// Connect to socket now
|
|
516
|
+
self._connectSocket(rtmHostOverride)
|
|
517
|
+
.then(resolve)
|
|
518
|
+
.catch(reject);
|
|
519
|
+
}, Crisp.DEFAULT_SOCKET_SCHEDULE);
|
|
520
|
+
} else {
|
|
521
|
+
// Pass-through
|
|
522
|
+
resolve();
|
|
509
523
|
}
|
|
524
|
+
});
|
|
525
|
+
},
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Connects socket, using preferred RTM API host
|
|
529
|
+
* @memberof Crisp
|
|
530
|
+
* @private
|
|
531
|
+
* @method _connectSocket
|
|
532
|
+
* @param {string} rtmHostOverride
|
|
533
|
+
*/
|
|
534
|
+
_connectSocket : function(rtmHostOverride) {
|
|
535
|
+
var self = this;
|
|
536
|
+
|
|
537
|
+
return Promise.resolve()
|
|
538
|
+
.then(function() {
|
|
539
|
+
// Any override RTM API host?
|
|
540
|
+
if (rtmHostOverride) {
|
|
541
|
+
return Promise.resolve({
|
|
542
|
+
socket : {
|
|
543
|
+
app : rtmHostOverride
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Acquire RTM API URL from remote
|
|
549
|
+
var restUrlSegments;
|
|
550
|
+
|
|
551
|
+
switch (self._tier) {
|
|
552
|
+
case "plugin": {
|
|
553
|
+
restUrlSegments = ["plugin", "connect", "endpoints"];
|
|
510
554
|
|
|
511
|
-
|
|
512
|
-
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
default: {
|
|
559
|
+
restUrlSegments = ["user", "connect", "endpoints"];
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return self.get(
|
|
564
|
+
self._prepareRestUrl(restUrlSegments)
|
|
565
|
+
)
|
|
566
|
+
.catch(function() {
|
|
567
|
+
// Void error (consider as empty response)
|
|
568
|
+
return Promise.resolve({});
|
|
569
|
+
});
|
|
570
|
+
})
|
|
571
|
+
.then(function(endpoints) {
|
|
572
|
+
var rtmHostAffinity = ((endpoints.socket || {}).app || null);
|
|
573
|
+
|
|
574
|
+
// No RTM API host acquired?
|
|
575
|
+
if (rtmHostAffinity === null) {
|
|
576
|
+
throw new Error(
|
|
577
|
+
"[Crisp] connectSocket: could not acquire target host to " +
|
|
578
|
+
"connect to, is your session valid for tier?"
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Parse target RTM API host as an URL object
|
|
583
|
+
var rtmHostUrl = new URL(rtmHostAffinity);
|
|
584
|
+
|
|
585
|
+
// Connect to socket
|
|
586
|
+
self._socket = require("socket.io-client")(rtmHostUrl.origin, {
|
|
587
|
+
path : (rtmHostUrl.pathname || "/"),
|
|
513
588
|
transports : ["websocket"],
|
|
514
589
|
timeout : Crisp.DEFAULT_SOCKET_TIMEOUT,
|
|
515
590
|
reconnection : true,
|
|
516
591
|
reconnectionDelay : Crisp.DEFAULT_SOCKET_RECONNECT_DELAY,
|
|
517
592
|
reconnectionDelayMax : Crisp.DEFAULT_SOCKET_RECONNECT_DELAY_MAX,
|
|
518
593
|
randomizationFactor : Crisp.DEFAULT_SOCKET_RECONNECT_FACTOR
|
|
519
|
-
|
|
520
594
|
});
|
|
521
595
|
|
|
522
596
|
self._emitAuthenticate();
|
|
523
597
|
|
|
524
598
|
// Setup base socket event listeners
|
|
525
|
-
self._socket.on("reconnect", function() {
|
|
599
|
+
self._socket.io.on("reconnect", function() {
|
|
526
600
|
self._emitAuthenticate();
|
|
527
601
|
});
|
|
528
602
|
|
|
529
603
|
self._socket.on("unauthorized", function() {
|
|
530
604
|
throw new Error(
|
|
531
|
-
"[Crisp] cannot listen for events as
|
|
605
|
+
"[Crisp] connectSocket: cannot listen for events as " +
|
|
606
|
+
"authentication is invalid"
|
|
532
607
|
);
|
|
533
608
|
});
|
|
534
609
|
|
|
@@ -538,8 +613,7 @@ Crisp.prototype = {
|
|
|
538
613
|
self._socket, self._emitter
|
|
539
614
|
);
|
|
540
615
|
}
|
|
541
|
-
}
|
|
542
|
-
}
|
|
616
|
+
});
|
|
543
617
|
},
|
|
544
618
|
|
|
545
619
|
/**
|
|
@@ -555,7 +629,7 @@ Crisp.prototype = {
|
|
|
555
629
|
* @param {function} reject
|
|
556
630
|
*/
|
|
557
631
|
_request : function(resource, method, query, body, resolve, reject) {
|
|
558
|
-
var
|
|
632
|
+
var requestParameters = {
|
|
559
633
|
json : true,
|
|
560
634
|
timeout : Crisp.DEFAULT_REQUEST_TIMEOUT,
|
|
561
635
|
|
|
@@ -567,21 +641,21 @@ Crisp.prototype = {
|
|
|
567
641
|
|
|
568
642
|
// Add authorization?
|
|
569
643
|
if (this.auth.token) {
|
|
570
|
-
|
|
644
|
+
requestParameters.headers.Authorization = ("Basic " + this.auth.token);
|
|
571
645
|
}
|
|
572
646
|
|
|
573
647
|
// Add body?
|
|
574
648
|
if (body) {
|
|
575
|
-
|
|
649
|
+
requestParameters.body = body;
|
|
576
650
|
}
|
|
577
651
|
|
|
578
652
|
// Add query?
|
|
579
653
|
if (query) {
|
|
580
|
-
|
|
654
|
+
requestParameters.query = query;
|
|
581
655
|
}
|
|
582
656
|
|
|
583
657
|
// Proceed request
|
|
584
|
-
got[method](resource,
|
|
658
|
+
got[method](resource, requestParameters)
|
|
585
659
|
.catch(function(error) {
|
|
586
660
|
return Promise.resolve(error);
|
|
587
661
|
})
|
|
@@ -644,17 +718,20 @@ Crisp.prototype = {
|
|
|
644
718
|
|
|
645
719
|
if (!this._socket) {
|
|
646
720
|
throw new Error(
|
|
647
|
-
"[Crisp] cannot listen for events as socket is
|
|
721
|
+
"[Crisp] emitAuthenticate: cannot listen for events as socket is " +
|
|
722
|
+
"not yet bound"
|
|
648
723
|
);
|
|
649
724
|
}
|
|
650
725
|
if (!auth.identifier || !auth.key) {
|
|
651
726
|
throw new Error(
|
|
652
|
-
"[Crisp] cannot listen for events as you did not
|
|
727
|
+
"[Crisp] emitAuthenticate: cannot listen for events as you did not " +
|
|
728
|
+
"authenticate"
|
|
653
729
|
);
|
|
654
730
|
}
|
|
655
731
|
if (this._boundEvents.length === 0) {
|
|
656
732
|
throw new Error(
|
|
657
|
-
"[Crisp] cannot listen for events as no event is
|
|
733
|
+
"[Crisp] emitAuthenticate: cannot listen for events as no event is " +
|
|
734
|
+
"being listened to"
|
|
658
735
|
);
|
|
659
736
|
}
|
|
660
737
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crisp-api",
|
|
3
3
|
"description": "Crisp API wrapper for Node - official, maintained by Crisp",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"homepage": "https://github.com/crisp-im/node-crisp-api",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"main": "./lib/crisp",
|
|
26
26
|
"types": "./types/crisp.d.ts",
|
|
27
27
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
28
|
+
"node": ">= 8.0.0"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"test": "check-build",
|
|
@@ -38,8 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"socket.io-client": "4.4.1",
|
|
40
40
|
"fbemitter": "3.0.0",
|
|
41
|
-
"got": "9.6.0"
|
|
42
|
-
"q": "2.0.3"
|
|
41
|
+
"got": "9.6.0"
|
|
43
42
|
},
|
|
44
43
|
"keywords": [
|
|
45
44
|
"crisp",
|
package/types/crisp.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare class Crisp {
|
|
|
48
48
|
_emitAuthenticate: () => void;
|
|
49
49
|
}
|
|
50
50
|
declare namespace Crisp {
|
|
51
|
-
export { DEFAULT_REQUEST_TIMEOUT, DEFAULT_SOCKET_TIMEOUT, DEFAULT_SOCKET_RECONNECT_DELAY, DEFAULT_SOCKET_RECONNECT_DELAY_MAX, DEFAULT_SOCKET_RECONNECT_FACTOR, DEFAULT_SOCKET_SCHEDULE, DEFAULT_USERAGENT_PREFIX, DEFAULT_REST_HOST, DEFAULT_REST_BASE_PATH,
|
|
51
|
+
export { DEFAULT_REQUEST_TIMEOUT, DEFAULT_SOCKET_TIMEOUT, DEFAULT_SOCKET_RECONNECT_DELAY, DEFAULT_SOCKET_RECONNECT_DELAY_MAX, DEFAULT_SOCKET_RECONNECT_FACTOR, DEFAULT_SOCKET_SCHEDULE, DEFAULT_USERAGENT_PREFIX, DEFAULT_REST_HOST, DEFAULT_REST_BASE_PATH, DEFAULT_RTM_EVENTS, Crisp };
|
|
52
52
|
}
|
|
53
53
|
declare var DEFAULT_REQUEST_TIMEOUT: number;
|
|
54
54
|
declare var DEFAULT_SOCKET_TIMEOUT: number;
|
|
@@ -59,5 +59,4 @@ declare var DEFAULT_SOCKET_SCHEDULE: number;
|
|
|
59
59
|
declare var DEFAULT_USERAGENT_PREFIX: string;
|
|
60
60
|
declare var DEFAULT_REST_HOST: string;
|
|
61
61
|
declare var DEFAULT_REST_BASE_PATH: string;
|
|
62
|
-
declare var DEFAULT_RTM_HOST: string;
|
|
63
62
|
declare var DEFAULT_RTM_EVENTS: string[];
|