crisp-api 5.3.0 → 6.2.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/lib/crisp.js CHANGED
@@ -10,15 +10,12 @@
10
10
 
11
11
 
12
12
  // Imports
13
- var pkg = require('../package.json');
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",
@@ -73,6 +68,7 @@ Crisp.DEFAULT_RTM_EVENTS = [
73
68
  "message:updated",
74
69
  "message:send",
75
70
  "message:received",
71
+ "message:removed",
76
72
  "message:compose:send",
77
73
  "message:compose:receive",
78
74
  "message:acknowledge:read:send",
@@ -165,7 +161,7 @@ function Crisp() {
165
161
 
166
162
  /** @private */
167
163
  this._rtm = {
168
- host : Crisp.DEFAULT_RTM_HOST
164
+ host : null
169
165
  };
170
166
 
171
167
  /** @private */
@@ -270,7 +266,7 @@ Crisp.prototype = {
270
266
  head : function(resource, query, body) {
271
267
  var self = this;
272
268
 
273
- return new __Promise(function(resolve, reject) {
269
+ return new Promise(function(resolve, reject) {
274
270
  self._request(
275
271
  resource, "head", (query || {}), null, resolve, reject
276
272
  );
@@ -288,7 +284,7 @@ Crisp.prototype = {
288
284
  get : function(resource, query) {
289
285
  var self = this;
290
286
 
291
- return new __Promise(function(resolve, reject) {
287
+ return new Promise(function(resolve, reject) {
292
288
  self._request(
293
289
  resource, "get", (query || {}), null, resolve, reject
294
290
  );
@@ -306,7 +302,7 @@ Crisp.prototype = {
306
302
  post : function(resource, query, body) {
307
303
  var self = this;
308
304
 
309
- return new __Promise(function(resolve, reject) {
305
+ return new Promise(function(resolve, reject) {
310
306
  self._request(
311
307
  resource, "post", (query || {}), (body || {}), resolve, reject
312
308
  );
@@ -324,7 +320,7 @@ Crisp.prototype = {
324
320
  patch : function(resource, query, body) {
325
321
  var self = this;
326
322
 
327
- return new __Promise(function(resolve, reject) {
323
+ return new Promise(function(resolve, reject) {
328
324
  self._request(
329
325
  resource, "patch", (query || {}), (body || {}), resolve, reject
330
326
  );
@@ -342,7 +338,7 @@ Crisp.prototype = {
342
338
  put : function(resource, query, body) {
343
339
  var self = this;
344
340
 
345
- return new __Promise(function(resolve, reject) {
341
+ return new Promise(function(resolve, reject) {
346
342
  self._request(
347
343
  resource, "put", (query || {}), (body || {}), resolve, reject
348
344
  );
@@ -360,7 +356,7 @@ Crisp.prototype = {
360
356
  delete : function(resource, query, body) {
361
357
  var self = this;
362
358
 
363
- return new __Promise(function(resolve, reject) {
359
+ return new Promise(function(resolve, reject) {
364
360
  self._request(
365
361
  resource, "delete", (query || {}), (body || null), resolve, reject
366
362
  );
@@ -409,7 +405,7 @@ Crisp.prototype = {
409
405
  this._boundEvents.push(event);
410
406
 
411
407
  // Socket not connected? Connect now.
412
- this._prepareSocket(
408
+ return this._prepareSocket(
413
409
  function(socket, emitter) {
414
410
  // Listen for event (once socket is bound)
415
411
  socket.on(event, function(data) {
@@ -418,6 +414,8 @@ Crisp.prototype = {
418
414
  }
419
415
  );
420
416
  }
417
+
418
+ return Promise.resolve();
421
419
  },
422
420
 
423
421
  /**
@@ -455,7 +453,10 @@ Crisp.prototype = {
455
453
  // No resources defined in service?
456
454
  if (!serviceInstance._resources ||
457
455
  serviceInstance._resources.length === 0) {
458
- throw new Error("Service '" + name + "' has no resources defined");
456
+ throw new Error(
457
+ "[Crisp] prepareServices: service '" + name + "' has no resources " +
458
+ "defined"
459
+ );
459
460
  }
460
461
 
461
462
  // Prepare all resources (for service)
@@ -471,9 +472,9 @@ Crisp.prototype = {
471
472
  * Binds resources to the service object
472
473
  * @memberof Crisp
473
474
  * @private
475
+ * @method _prepareResources
474
476
  * @param {object} serviceInstance
475
477
  * @param {Array} resources
476
- * @method _prepareResources
477
478
  */
478
479
  _prepareResources : function(serviceInstance, resources) {
479
480
  for (var i = 0; i < resources.length; i++) {
@@ -494,41 +495,116 @@ Crisp.prototype = {
494
495
  _prepareSocket : function(fnBindHook) {
495
496
  var self = this;
496
497
 
497
- var rtmHost = this._rtm.host;
498
+ return new Promise(function(resolve, reject) {
499
+ var rtmHostOverride = self._rtm.host;
500
+
501
+ // Append bind hook to pending stack
502
+ self._socketBindHooks.push(fnBindHook);
498
503
 
499
- // Append bind hook to pending stack
500
- this._socketBindHooks.push(fnBindHook);
504
+ // Make sure to prepare socket once? (defer socket binding, waiting that \
505
+ // all listeners have been bound, that way we submit the list of \
506
+ // filtered events to the RTM API once, and never again in the future)
507
+ if (self._socketScheduler === null) {
508
+ // Socket is already set? We should not even have entered there.
509
+ if (self._socket) {
510
+ throw new Error(
511
+ "[Crisp] prepareSocket: illegal call to prepare socket (tie break)"
512
+ );
513
+ }
501
514
 
502
- // Make sure to prepare socket once? (defer socket binding, waiting that \
503
- // all listeners have been bound, that way we submit the list of \
504
- // filtered events to the RTM API once, and never again in the future)
505
- if (this._socketScheduler === null) {
506
- // Socket is already set? We should not even have entered there.
507
- if (this._socket) {
508
- throw new Error("[Crisp] illegal call to prepare socket (tie break)");
515
+ self._socketScheduler = setTimeout(function() {
516
+ // Connect to socket now
517
+ self._connectSocket(rtmHostOverride)
518
+ .then(resolve)
519
+ .catch(reject);
520
+ }, Crisp.DEFAULT_SOCKET_SCHEDULE);
521
+ } else {
522
+ // Pass-through
523
+ resolve();
509
524
  }
525
+ });
526
+ },
527
+
528
+ /**
529
+ * Connects socket, using preferred RTM API host
530
+ * @memberof Crisp
531
+ * @private
532
+ * @method _connectSocket
533
+ * @param {string} rtmHostOverride
534
+ */
535
+ _connectSocket : function(rtmHostOverride) {
536
+ var self = this;
537
+
538
+ return Promise.resolve()
539
+ .then(function() {
540
+ // Any override RTM API host?
541
+ if (rtmHostOverride) {
542
+ return Promise.resolve({
543
+ socket : {
544
+ app : rtmHostOverride
545
+ }
546
+ });
547
+ }
548
+
549
+ // Acquire RTM API URL from remote
550
+ var restUrlSegments;
551
+
552
+ switch (self._tier) {
553
+ case "plugin": {
554
+ restUrlSegments = ["plugin", "connect", "endpoints"];
510
555
 
511
- this._socketScheduler = setTimeout(function() {
512
- self._socket = require('socket.io-client')(rtmHost, {
556
+ break;
557
+ }
558
+
559
+ default: {
560
+ restUrlSegments = ["user", "connect", "endpoints"];
561
+ }
562
+ }
563
+
564
+ return self.get(
565
+ self._prepareRestUrl(restUrlSegments)
566
+ )
567
+ .catch(function() {
568
+ // Void error (consider as empty response)
569
+ return Promise.resolve({});
570
+ });
571
+ })
572
+ .then(function(endpoints) {
573
+ var rtmHostAffinity = ((endpoints.socket || {}).app || null);
574
+
575
+ // No RTM API host acquired?
576
+ if (rtmHostAffinity === null) {
577
+ throw new Error(
578
+ "[Crisp] connectSocket: could not acquire target host to " +
579
+ "connect to, is your session valid for tier?"
580
+ );
581
+ }
582
+
583
+ // Parse target RTM API host as an URL object
584
+ var rtmHostUrl = new URL(rtmHostAffinity);
585
+
586
+ // Connect to socket
587
+ self._socket = require("socket.io-client")(rtmHostUrl.origin, {
588
+ path : (rtmHostUrl.pathname || "/"),
513
589
  transports : ["websocket"],
514
590
  timeout : Crisp.DEFAULT_SOCKET_TIMEOUT,
515
591
  reconnection : true,
516
592
  reconnectionDelay : Crisp.DEFAULT_SOCKET_RECONNECT_DELAY,
517
593
  reconnectionDelayMax : Crisp.DEFAULT_SOCKET_RECONNECT_DELAY_MAX,
518
594
  randomizationFactor : Crisp.DEFAULT_SOCKET_RECONNECT_FACTOR
519
-
520
595
  });
521
596
 
522
597
  self._emitAuthenticate();
523
598
 
524
599
  // Setup base socket event listeners
525
- self._socket.on("reconnect", function() {
600
+ self._socket.io.on("reconnect", function() {
526
601
  self._emitAuthenticate();
527
602
  });
528
603
 
529
604
  self._socket.on("unauthorized", function() {
530
605
  throw new Error(
531
- "[Crisp] cannot listen for events as authentication is invalid"
606
+ "[Crisp] connectSocket: cannot listen for events as " +
607
+ "authentication is invalid"
532
608
  );
533
609
  });
534
610
 
@@ -538,8 +614,7 @@ Crisp.prototype = {
538
614
  self._socket, self._emitter
539
615
  );
540
616
  }
541
- }, Crisp.DEFAULT_SOCKET_SCHEDULE);
542
- }
617
+ });
543
618
  },
544
619
 
545
620
  /**
@@ -555,7 +630,7 @@ Crisp.prototype = {
555
630
  * @param {function} reject
556
631
  */
557
632
  _request : function(resource, method, query, body, resolve, reject) {
558
- var _parameters = {
633
+ var requestParameters = {
559
634
  json : true,
560
635
  timeout : Crisp.DEFAULT_REQUEST_TIMEOUT,
561
636
 
@@ -567,21 +642,21 @@ Crisp.prototype = {
567
642
 
568
643
  // Add authorization?
569
644
  if (this.auth.token) {
570
- _parameters.headers.Authorization = ("Basic " + this.auth.token);
645
+ requestParameters.headers.Authorization = ("Basic " + this.auth.token);
571
646
  }
572
647
 
573
648
  // Add body?
574
649
  if (body) {
575
- _parameters.body = body;
650
+ requestParameters.body = body;
576
651
  }
577
652
 
578
653
  // Add query?
579
654
  if (query) {
580
- _parameters.query = query;
655
+ requestParameters.query = query;
581
656
  }
582
657
 
583
658
  // Proceed request
584
- got[method](resource, _parameters)
659
+ got[method](resource, requestParameters)
585
660
  .catch(function(error) {
586
661
  return Promise.resolve(error);
587
662
  })
@@ -644,17 +719,20 @@ Crisp.prototype = {
644
719
 
645
720
  if (!this._socket) {
646
721
  throw new Error(
647
- "[Crisp] cannot listen for events as socket is not yet bound"
722
+ "[Crisp] emitAuthenticate: cannot listen for events as socket is " +
723
+ "not yet bound"
648
724
  );
649
725
  }
650
726
  if (!auth.identifier || !auth.key) {
651
727
  throw new Error(
652
- "[Crisp] cannot listen for events as you did not authenticate"
728
+ "[Crisp] emitAuthenticate: cannot listen for events as you did not " +
729
+ "authenticate"
653
730
  );
654
731
  }
655
732
  if (this._boundEvents.length === 0) {
656
733
  throw new Error(
657
- "[Crisp] cannot listen for events as no event is being listened to"
734
+ "[Crisp] emitAuthenticate: cannot listen for events as no event is " +
735
+ "being listened to"
658
736
  );
659
737
  }
660
738
 
@@ -238,6 +238,22 @@ function WebsiteConversation(service, crisp) {
238
238
  );
239
239
  };
240
240
 
241
+ /**
242
+ * Remove A Message In Conversation
243
+ * @memberof WebsiteConversation
244
+ * @method removeMessageInConversation
245
+ * @return Promise
246
+ */
247
+ service.removeMessageInConversation = function(
248
+ websiteID, sessionID, fingerprint
249
+ ) {
250
+ return crisp.delete(
251
+ crisp._prepareRestUrl([
252
+ "website", websiteID, "conversation", sessionID, "message", fingerprint
253
+ ])
254
+ );
255
+ };
256
+
241
257
  /**
242
258
  * Compose A Message In Conversation
243
259
  * @memberof WebsiteConversation
@@ -518,6 +534,42 @@ function WebsiteConversation(service, crisp) {
518
534
  );
519
535
  };
520
536
 
537
+ /**
538
+ * Get Verify Status For Conversation
539
+ * @memberof WebsiteConversation
540
+ * @method getVerifyStatusForConversation
541
+ * @return Promise
542
+ */
543
+ service.getVerifyStatusForConversation = function(websiteID, sessionID) {
544
+ return crisp.get(
545
+ crisp._prepareRestUrl([
546
+ "website", websiteID, "conversation", sessionID, "verify"
547
+ ])
548
+ );
549
+ };
550
+
551
+ /**
552
+ * Update Verify Status For Conversation
553
+ * @memberof WebsiteConversation
554
+ * @method updateVerifyStatusForConversation
555
+ * @return Promise
556
+ */
557
+ service.updateVerifyStatusForConversation = function(
558
+ websiteID, sessionID, verified
559
+ ) {
560
+ return crisp.patch(
561
+ crisp._prepareRestUrl([
562
+ "website", websiteID, "conversation", sessionID, "verify"
563
+ ]),
564
+
565
+ null,
566
+
567
+ {
568
+ verified : (verified || false)
569
+ }
570
+ );
571
+ };
572
+
521
573
  /**
522
574
  * Request Email Transcript For Conversation
523
575
  * @memberof WebsiteConversation
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": "5.3.0",
4
+ "version": "6.2.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": ">= 6.0.0"
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, DEFAULT_RTM_HOST, DEFAULT_RTM_EVENTS, 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, 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[];