@meetelise/chat 1.20.135 → 1.20.136
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 +1 -1
- package/public/dist/index.js +11 -11
- package/src/MyPubnub.ts +5 -82
- package/src/WebComponent/me-chat.ts +18 -3
- package/src/handleChatIds.ts +98 -0
package/src/MyPubnub.ts
CHANGED
|
@@ -3,14 +3,12 @@ import Pubnub, { ListenerParameters, MessageEvent } from "pubnub";
|
|
|
3
3
|
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import { Building } from "./fetchBuildingInfo";
|
|
6
|
-
import parseISO from "date-fns/parseISO";
|
|
7
|
-
import { v4 as uuid } from "uuid";
|
|
8
6
|
import addHours from "date-fns/addHours";
|
|
9
7
|
import isAfter from "date-fns/isAfter";
|
|
10
|
-
import formatISO from "date-fns/formatISO";
|
|
11
|
-
import isBefore from "date-fns/isBefore";
|
|
12
8
|
import { LogType, sendLoggingEvent } from "./analytics";
|
|
13
9
|
|
|
10
|
+
import { createChatStorageKey, getChatStorageKey } from "./handleChatIds";
|
|
11
|
+
|
|
14
12
|
interface TokenResponse {
|
|
15
13
|
auth: {
|
|
16
14
|
result: {
|
|
@@ -40,7 +38,7 @@ export interface ChatMessage {
|
|
|
40
38
|
timetoken: number;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
interface ChatInfo {
|
|
41
|
+
export interface ChatInfo {
|
|
44
42
|
leadId: string | null;
|
|
45
43
|
timestamp: Date | null;
|
|
46
44
|
buildingSlug: string | null;
|
|
@@ -116,7 +114,7 @@ class MyPubnub {
|
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
async initializePubnub(): Promise<Pubnub | undefined> {
|
|
119
|
-
const storedChatKeyValues = this.
|
|
117
|
+
const storedChatKeyValues = getChatStorageKey(true, this.buildingSlug);
|
|
120
118
|
if (!storedChatKeyValues.leadId) {
|
|
121
119
|
// eslint-disable-next-line no-console
|
|
122
120
|
sendLoggingEvent({
|
|
@@ -145,9 +143,8 @@ class MyPubnub {
|
|
|
145
143
|
addHours(new Date(), this.ttlHours)
|
|
146
144
|
)
|
|
147
145
|
) {
|
|
148
|
-
|
|
146
|
+
createChatStorageKey(this.buildingSlug, this.leadUserId);
|
|
149
147
|
}
|
|
150
|
-
|
|
151
148
|
const pubnubToken = await this.fetchToken(this.leadUserId, this.channel);
|
|
152
149
|
if (!pubnubToken) return;
|
|
153
150
|
|
|
@@ -382,80 +379,6 @@ class MyPubnub {
|
|
|
382
379
|
isLeadMessage = (message: ChatMessage): boolean =>
|
|
383
380
|
message.publisher.includes("lead_") &&
|
|
384
381
|
message.message.customType === "lead_message";
|
|
385
|
-
|
|
386
|
-
clearChatStorageKey = (): void =>
|
|
387
|
-
localStorage.removeItem("com.eliseai.webchat.slug=" + this.buildingSlug);
|
|
388
|
-
|
|
389
|
-
createChatStorageKey = (existingUserId?: string): ChatInfo => {
|
|
390
|
-
const storageTimestamp = formatISO(new Date());
|
|
391
|
-
const leadUserId = existingUserId ?? `lead_${uuid()}_${this.buildingSlug}`;
|
|
392
|
-
localStorage.setItem(
|
|
393
|
-
"com.eliseai.webchat.slug=" + this.buildingSlug,
|
|
394
|
-
JSON.stringify({
|
|
395
|
-
buildingSlug: this.buildingSlug,
|
|
396
|
-
leadId: leadUserId,
|
|
397
|
-
timestamp: storageTimestamp,
|
|
398
|
-
})
|
|
399
|
-
);
|
|
400
|
-
return {
|
|
401
|
-
leadId: leadUserId,
|
|
402
|
-
timestamp: parseISO(storageTimestamp),
|
|
403
|
-
buildingSlug: this.buildingSlug,
|
|
404
|
-
};
|
|
405
|
-
};
|
|
406
|
-
getChatStorageKey = (createNewIfNotExist = true): ChatInfo => {
|
|
407
|
-
const eliseaiLocalStorageValue = localStorage.getItem(
|
|
408
|
-
"com.eliseai.webchat.slug=" + this.buildingSlug
|
|
409
|
-
);
|
|
410
|
-
if (eliseaiLocalStorageValue) {
|
|
411
|
-
try {
|
|
412
|
-
const eliseaiLocalStorageValueParsed = JSON.parse(
|
|
413
|
-
eliseaiLocalStorageValue
|
|
414
|
-
);
|
|
415
|
-
const lsBuildingSlug = eliseaiLocalStorageValueParsed.buildingSlug;
|
|
416
|
-
const lsLeadId = eliseaiLocalStorageValueParsed.leadId;
|
|
417
|
-
const lsExpiration = new Date(eliseaiLocalStorageValueParsed.timestamp);
|
|
418
|
-
|
|
419
|
-
if (
|
|
420
|
-
this.isChatKeyValid({
|
|
421
|
-
leadId: lsLeadId,
|
|
422
|
-
timestamp: lsExpiration,
|
|
423
|
-
buildingSlug: lsBuildingSlug,
|
|
424
|
-
})
|
|
425
|
-
)
|
|
426
|
-
return {
|
|
427
|
-
leadId: lsLeadId,
|
|
428
|
-
timestamp: lsExpiration,
|
|
429
|
-
buildingSlug: lsBuildingSlug,
|
|
430
|
-
};
|
|
431
|
-
} catch (_) {
|
|
432
|
-
// eslint-disable-next-line no-console
|
|
433
|
-
console.warn("Error getting chat storage key");
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (createNewIfNotExist) return this.createChatStorageKey();
|
|
438
|
-
return {
|
|
439
|
-
leadId: null,
|
|
440
|
-
timestamp: null,
|
|
441
|
-
buildingSlug: null,
|
|
442
|
-
};
|
|
443
|
-
};
|
|
444
|
-
isChatKeyValid = (storageValueDeconstructed: ChatInfo): boolean => {
|
|
445
|
-
if (
|
|
446
|
-
storageValueDeconstructed.buildingSlug !== this.buildingSlug ||
|
|
447
|
-
!storageValueDeconstructed.leadId ||
|
|
448
|
-
!storageValueDeconstructed.timestamp
|
|
449
|
-
) {
|
|
450
|
-
return false;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const expirationDate = addHours(
|
|
454
|
-
storageValueDeconstructed.timestamp,
|
|
455
|
-
this.ttlHours
|
|
456
|
-
);
|
|
457
|
-
return !isBefore(expirationDate, Date.now());
|
|
458
|
-
};
|
|
459
382
|
}
|
|
460
383
|
|
|
461
384
|
export default MyPubnub;
|
|
@@ -40,6 +40,11 @@ import "./actions/minimize-expand-button";
|
|
|
40
40
|
import "./launcher/mobile-launcher";
|
|
41
41
|
import "./pubnub-chat";
|
|
42
42
|
import { getBuildingPhoneNumber } from "../getBuildingPhoneNumber";
|
|
43
|
+
import {
|
|
44
|
+
clearChatStorageKey,
|
|
45
|
+
getChatStorageKey,
|
|
46
|
+
isChatKeyValid,
|
|
47
|
+
} from "../handleChatIds";
|
|
43
48
|
|
|
44
49
|
@customElement("me-chat")
|
|
45
50
|
export class MEChat extends LitElement {
|
|
@@ -316,7 +321,13 @@ export class MEChat extends LitElement {
|
|
|
316
321
|
this.orgSlug,
|
|
317
322
|
this.currentLeadSource
|
|
318
323
|
);
|
|
319
|
-
if (
|
|
324
|
+
if (
|
|
325
|
+
// handle if we already have a valid session to open up to
|
|
326
|
+
isChatKeyValid(
|
|
327
|
+
getChatStorageKey(false, this.buildingSlug),
|
|
328
|
+
this.buildingSlug
|
|
329
|
+
)
|
|
330
|
+
) {
|
|
320
331
|
await this.myPubnub.initializePubnub();
|
|
321
332
|
}
|
|
322
333
|
this.attachOnClickToLauncher();
|
|
@@ -343,18 +354,22 @@ export class MEChat extends LitElement {
|
|
|
343
354
|
};
|
|
344
355
|
|
|
345
356
|
private async handleChatInitializeAnalytics(): Promise<void> {
|
|
357
|
+
// Although we may create the chat id here, we DO NOT create a channel here. We only create a channel when the user
|
|
358
|
+
// actually sends a message. This is to prevent unnecessary channels from being created.
|
|
346
359
|
this.analytics = new Analytics(
|
|
347
360
|
this.orgSlug,
|
|
348
361
|
this.buildingSlug,
|
|
349
|
-
this.
|
|
362
|
+
`webchat_lead_${getChatStorageKey(true, this.buildingSlug).leadId}`, // important to get unique visitors to the website
|
|
350
363
|
this.currentLeadSource
|
|
351
364
|
);
|
|
365
|
+
// ping both the load and the heartbeat events for legacy support
|
|
366
|
+
this.analytics.ping("load");
|
|
352
367
|
this.analytics.ping("webchat_heartbeat");
|
|
353
368
|
}
|
|
354
369
|
|
|
355
370
|
public async restartConversation(): Promise<void> {
|
|
356
371
|
this.myPubnub?.handleDisconnect();
|
|
357
|
-
this.
|
|
372
|
+
clearChatStorageKey(this.buildingSlug);
|
|
358
373
|
this.myPubnub = null;
|
|
359
374
|
this.displayPubnubChat = false;
|
|
360
375
|
await this.initializeChatVariables();
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import isBefore from "date-fns/isBefore";
|
|
2
|
+
import addHours from "date-fns/addHours";
|
|
3
|
+
import { ChatInfo } from "./MyPubnub";
|
|
4
|
+
|
|
5
|
+
import parseISO from "date-fns/parseISO";
|
|
6
|
+
import { v4 as uuid } from "uuid";
|
|
7
|
+
|
|
8
|
+
import formatISO from "date-fns/formatISO";
|
|
9
|
+
|
|
10
|
+
export const ttlHoursChat = 24;
|
|
11
|
+
|
|
12
|
+
export const isChatKeyValid = (
|
|
13
|
+
storageValueDeconstructed: ChatInfo,
|
|
14
|
+
buildingSlug: string
|
|
15
|
+
): boolean => {
|
|
16
|
+
if (
|
|
17
|
+
storageValueDeconstructed.buildingSlug !== buildingSlug ||
|
|
18
|
+
!storageValueDeconstructed.leadId ||
|
|
19
|
+
!storageValueDeconstructed.timestamp
|
|
20
|
+
) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const expirationDate = addHours(
|
|
25
|
+
storageValueDeconstructed.timestamp,
|
|
26
|
+
ttlHoursChat
|
|
27
|
+
);
|
|
28
|
+
return !isBefore(expirationDate, Date.now());
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const getChatStorageKey = (
|
|
32
|
+
createNewIfNotExist = true,
|
|
33
|
+
buildingSlug: string
|
|
34
|
+
): ChatInfo => {
|
|
35
|
+
const eliseaiLocalStorageValue = localStorage.getItem(
|
|
36
|
+
"com.eliseai.webchat.slug=" + buildingSlug
|
|
37
|
+
);
|
|
38
|
+
if (eliseaiLocalStorageValue) {
|
|
39
|
+
try {
|
|
40
|
+
const eliseaiLocalStorageValueParsed = JSON.parse(
|
|
41
|
+
eliseaiLocalStorageValue
|
|
42
|
+
);
|
|
43
|
+
const lsBuildingSlug = eliseaiLocalStorageValueParsed.buildingSlug;
|
|
44
|
+
const lsLeadId = eliseaiLocalStorageValueParsed.leadId;
|
|
45
|
+
const lsExpiration = new Date(eliseaiLocalStorageValueParsed.timestamp);
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
isChatKeyValid(
|
|
49
|
+
{
|
|
50
|
+
leadId: lsLeadId,
|
|
51
|
+
timestamp: lsExpiration,
|
|
52
|
+
buildingSlug: lsBuildingSlug,
|
|
53
|
+
},
|
|
54
|
+
buildingSlug
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
return {
|
|
58
|
+
leadId: lsLeadId,
|
|
59
|
+
timestamp: lsExpiration,
|
|
60
|
+
buildingSlug: lsBuildingSlug,
|
|
61
|
+
};
|
|
62
|
+
} catch (_) {
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
console.warn("Error getting chat storage key");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (createNewIfNotExist) return createChatStorageKey(buildingSlug);
|
|
69
|
+
return {
|
|
70
|
+
leadId: null,
|
|
71
|
+
timestamp: null,
|
|
72
|
+
buildingSlug: null,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const clearChatStorageKey = (buildingSlug: string): void =>
|
|
77
|
+
localStorage.removeItem("com.eliseai.webchat.slug=" + buildingSlug);
|
|
78
|
+
|
|
79
|
+
export const createChatStorageKey = (
|
|
80
|
+
buildingSlug: string,
|
|
81
|
+
existingUserId?: string
|
|
82
|
+
): ChatInfo => {
|
|
83
|
+
const storageTimestamp = formatISO(new Date());
|
|
84
|
+
const leadUserId = existingUserId ?? `lead_${uuid()}_${buildingSlug}`;
|
|
85
|
+
localStorage.setItem(
|
|
86
|
+
"com.eliseai.webchat.slug=" + buildingSlug,
|
|
87
|
+
JSON.stringify({
|
|
88
|
+
buildingSlug: buildingSlug,
|
|
89
|
+
leadId: leadUserId,
|
|
90
|
+
timestamp: storageTimestamp,
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
return {
|
|
94
|
+
leadId: leadUserId,
|
|
95
|
+
timestamp: parseISO(storageTimestamp),
|
|
96
|
+
buildingSlug: buildingSlug,
|
|
97
|
+
};
|
|
98
|
+
};
|