@meetelise/chat 1.51.14 → 1.52.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/dist/src/WebComponent/launcher/Launcher.d.ts +3 -1
- package/dist/src/WebComponent/me-chat.d.ts +1 -0
- package/dist/src/googleReserve.d.ts +17 -0
- package/package.json +1 -1
- package/public/dist/index.js +211 -201
- package/src/WebComponent/Scheduler/tour-scheduler.ts +4 -0
- package/src/WebComponent/actions/call-us-window.ts +17 -12
- package/src/WebComponent/launcher/Launcher.ts +13 -1
- package/src/WebComponent/me-chat.ts +19 -6
- package/src/disclaimers.ts +17 -8
- package/src/googleReserve.test.ts +60 -0
- package/src/googleReserve.ts +48 -0
|
@@ -63,6 +63,7 @@ import { getTimezoneAbbreviation } from "../../getTimezoneString";
|
|
|
63
63
|
import startOfDay from "date-fns/startOfDay";
|
|
64
64
|
import isSameDay from "date-fns/isSameDay";
|
|
65
65
|
import { LeadSourceMultitouchClient } from "../LeadSourceMultitouchClient";
|
|
66
|
+
import { readGoogleReserveReferral } from "../../googleReserve";
|
|
66
67
|
import fetchBuildingUnitsSummary, {
|
|
67
68
|
UnitSummary,
|
|
68
69
|
} from "../../fetchBuildingUnitsSummary";
|
|
@@ -742,6 +743,7 @@ export class TourScheduler extends LitElement {
|
|
|
742
743
|
unit: selectedUnit,
|
|
743
744
|
conversationTrackingId: this.leadSourceClient?.chatId ?? null,
|
|
744
745
|
});
|
|
746
|
+
const googleReferral = readGoogleReserveReferral();
|
|
745
747
|
const data = {
|
|
746
748
|
referrer: document.referrer,
|
|
747
749
|
email_address: this.email,
|
|
@@ -774,6 +776,8 @@ export class TourScheduler extends LitElement {
|
|
|
774
776
|
}
|
|
775
777
|
) ?? []
|
|
776
778
|
).map((source) => snakify({ ...source })),
|
|
779
|
+
google_rwg_token: googleReferral?.rwgToken,
|
|
780
|
+
google_referral_building_id: googleReferral?.buildingId,
|
|
777
781
|
};
|
|
778
782
|
|
|
779
783
|
const url = `https://app.meetelise.com/platformApi/state/create/v2/scheduleMe`;
|
|
@@ -325,7 +325,8 @@ export class CallUsWindow extends LitElement {
|
|
|
325
325
|
? html`By providing your number and clicking send, you consent to
|
|
326
326
|
receive recurring commercial electronic messages from or on behalf
|
|
327
327
|
of ${this.orgLegalName} at this number. Messages may be AI or
|
|
328
|
-
human generated. Msg & Data rates may apply. You
|
|
328
|
+
human generated. Msg freq varies. Msg & Data rates may apply. You
|
|
329
|
+
consent to this
|
|
329
330
|
<a
|
|
330
331
|
target="_blank"
|
|
331
332
|
rel="noopener noreferrer"
|
|
@@ -334,28 +335,30 @@ export class CallUsWindow extends LitElement {
|
|
|
334
335
|
>, including having your number and communications recorded and
|
|
335
336
|
used by our service provider to generate responses and improve
|
|
336
337
|
their services. You may withdraw your consent at any time by
|
|
337
|
-
unsubscribing or contacting us
|
|
338
|
+
unsubscribing or contacting us. Text STOP to opt-out of messages.
|
|
339
|
+
Text HELP for assistance.`
|
|
338
340
|
: this.buildingId === 196098 // Liss Lawndale Apartments
|
|
339
341
|
? html`By providing your number and clicking send, you consent to
|
|
340
|
-
receive recurring marketing
|
|
342
|
+
receive recurring marketing text and voice messages and calls from
|
|
341
343
|
or on behalf of ${this.orgLegalName} at this number using
|
|
342
344
|
artificial voice or an autodialer system. Messages may be AI or
|
|
343
345
|
human generated. This consent is not required to lease at this
|
|
344
|
-
property.
|
|
345
|
-
|
|
346
|
+
property. Msg freq varies. Msg & Data rates may apply. Text STOP
|
|
347
|
+
to opt-out of messages. Text HELP for assistance. You consent to
|
|
348
|
+
this
|
|
346
349
|
<a target="_blank" href="http://bit.ly/me_privacy_policy"
|
|
347
350
|
>privacy policy</a
|
|
348
351
|
>, including having your number and communications recorded and
|
|
349
352
|
used by a third party.`
|
|
350
353
|
: this.orgSlug === "greystar"
|
|
351
354
|
? html`By providing your phone number and clicking send, you consent
|
|
352
|
-
to receive recurring marketing
|
|
355
|
+
to receive recurring marketing text and voice messages and calls
|
|
353
356
|
from Greystar or on its behalf at this number using artificial
|
|
354
357
|
voice and/or an autodialer. Messages may be AI or human-generated.
|
|
355
358
|
Your phone number and communications are shared with and recorded
|
|
356
359
|
and used by EliseAI. You are not required to provide your phone
|
|
357
|
-
number or consent to these terms to lease at this property. Msg
|
|
358
|
-
Data rates may apply. You consent to
|
|
360
|
+
number or consent to these terms to lease at this property. Msg
|
|
361
|
+
freq varies. Msg & Data rates may apply. You consent to
|
|
359
362
|
<a
|
|
360
363
|
href="https://www.greystar.com/privacy"
|
|
361
364
|
target="_blank"
|
|
@@ -368,13 +371,14 @@ export class CallUsWindow extends LitElement {
|
|
|
368
371
|
target="_blank"
|
|
369
372
|
rel="noopener noreferrer"
|
|
370
373
|
>EliseAI's Privacy Policy</a
|
|
371
|
-
|
|
374
|
+
>. Text STOP to opt-out of messages. Text HELP for assistance.`
|
|
372
375
|
: html`By providing your number and clicking send, you consent to
|
|
373
|
-
receive recurring marketing
|
|
376
|
+
receive recurring marketing text and voice messages and calls from
|
|
374
377
|
or on behalf of ${this.orgLegalName} at this number using
|
|
375
378
|
artificial voice or an autodialer system. Messages may be AI or
|
|
376
379
|
human generated. This consent is not required to lease at this
|
|
377
|
-
property. Msg & Data rates may apply. You consent
|
|
380
|
+
property. Msg freq varies. Msg & Data rates may apply. You consent
|
|
381
|
+
to this
|
|
378
382
|
<a target="_blank" href="http://bit.ly/me_privacy_policy"
|
|
379
383
|
>privacy policy</a
|
|
380
384
|
>
|
|
@@ -382,7 +386,8 @@ export class CallUsWindow extends LitElement {
|
|
|
382
386
|
<a target="_blank" href="https://eliseai.com/msgterms"
|
|
383
387
|
>terms and conditions</a
|
|
384
388
|
>, including having your number and communications recorded and
|
|
385
|
-
used by a third party
|
|
389
|
+
used by a third party. Text STOP to opt-out of messages. Text HELP
|
|
390
|
+
for assistance.`}
|
|
386
391
|
</div>
|
|
387
392
|
</div>`;
|
|
388
393
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { html, LitElement, TemplateResult, css } from "lit";
|
|
1
|
+
import { html, LitElement, PropertyValues, TemplateResult, css } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
3
|
import { createRef, ref, Ref } from "lit/directives/ref.js";
|
|
4
4
|
import { launcherStyles } from "./launcherStyles";
|
|
@@ -65,6 +65,9 @@ export class Launcher extends LitElement {
|
|
|
65
65
|
@property({ type: Boolean })
|
|
66
66
|
isFirstMount = false;
|
|
67
67
|
|
|
68
|
+
@property({ attribute: false })
|
|
69
|
+
openSSTWindowOnLoad = false;
|
|
70
|
+
|
|
68
71
|
@property({ attribute: false })
|
|
69
72
|
autoOpenChatWidget = false;
|
|
70
73
|
|
|
@@ -283,6 +286,15 @@ export class Launcher extends LitElement {
|
|
|
283
286
|
tourSchedulerRef: Ref<TourScheduler> = createRef();
|
|
284
287
|
calculatorWindowRef: Ref<FeeCalculator> = createRef();
|
|
285
288
|
|
|
289
|
+
willUpdate(changedProperties: PropertyValues<this>): void {
|
|
290
|
+
if (
|
|
291
|
+
changedProperties.has("openSSTWindowOnLoad") &&
|
|
292
|
+
this.openSSTWindowOnLoad
|
|
293
|
+
) {
|
|
294
|
+
this.isSSTWindowOpen = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
286
298
|
updated = async (): Promise<void> => {
|
|
287
299
|
this.attachOnClickToEmailUsWindow();
|
|
288
300
|
this.attachOnClickToSSTWindow();
|
|
@@ -71,6 +71,10 @@ import {
|
|
|
71
71
|
|
|
72
72
|
import "./chat-additional-actions";
|
|
73
73
|
import { LeadSourceMultitouchClient } from "./LeadSourceMultitouchClient";
|
|
74
|
+
import {
|
|
75
|
+
shouldOpenTourSchedulerFromUrl,
|
|
76
|
+
storeGoogleReserveReferral,
|
|
77
|
+
} from "../googleReserve";
|
|
74
78
|
|
|
75
79
|
@customElement("me-chat")
|
|
76
80
|
export class MEChat extends LitElement {
|
|
@@ -187,6 +191,9 @@ export class MEChat extends LitElement {
|
|
|
187
191
|
@state()
|
|
188
192
|
private showTourNextToChat = false;
|
|
189
193
|
|
|
194
|
+
@state()
|
|
195
|
+
private openTourSchedulerOnLoad = false;
|
|
196
|
+
|
|
190
197
|
@state()
|
|
191
198
|
private displayPubnubChat = false;
|
|
192
199
|
|
|
@@ -321,19 +328,24 @@ export class MEChat extends LitElement {
|
|
|
321
328
|
|
|
322
329
|
this.attachOnClickToLauncher();
|
|
323
330
|
|
|
324
|
-
|
|
331
|
+
storeGoogleReserveReferral(this.buildingWebchatView?.id ?? 0);
|
|
332
|
+
|
|
333
|
+
if (
|
|
334
|
+
shouldOpenTourSchedulerFromUrl() &&
|
|
335
|
+
(this.enabledChatWidgets.sstDesktop || this.enabledChatWidgets.sstMobile)
|
|
336
|
+
) {
|
|
337
|
+
this.openTourSchedulerOnLoad = true;
|
|
338
|
+
} else if (this.shouldAutoOpenChat(this.webchatConfigHasAutoOpenChat)) {
|
|
325
339
|
this.displayPubnubChat = true;
|
|
326
340
|
this.hideLauncher = true;
|
|
327
341
|
this.hasMounted = true;
|
|
328
342
|
this.updateAlreadyAutoOpenedTimestamp();
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
this.isLoading = false;
|
|
332
|
-
|
|
333
|
-
if (localStorage.getItem("isChatOpen") === "true") {
|
|
343
|
+
} else if (localStorage.getItem("isChatOpen") === "true") {
|
|
334
344
|
this.hideLauncher = true;
|
|
335
345
|
this.displayPubnubChat = true;
|
|
336
346
|
}
|
|
347
|
+
|
|
348
|
+
this.isLoading = false;
|
|
337
349
|
};
|
|
338
350
|
|
|
339
351
|
// The general info for the buildingg
|
|
@@ -1080,6 +1092,7 @@ export class MEChat extends LitElement {
|
|
|
1080
1092
|
virtualToursTypeOffered="${this.buildingWebchatView
|
|
1081
1093
|
.virtualToursTypeOffered ?? ""}"
|
|
1082
1094
|
.showTourNextToChat="${this.showTourNextToChat ?? ""}"
|
|
1095
|
+
.openSSTWindowOnLoad=${this.openTourSchedulerOnLoad}
|
|
1083
1096
|
@closeShowTourNextToChat=${() => {
|
|
1084
1097
|
this.showTourNextToChat = false;
|
|
1085
1098
|
this.hideLauncher = true;
|
package/src/disclaimers.ts
CHANGED
|
@@ -63,6 +63,10 @@ const formDisclaimer = ({
|
|
|
63
63
|
recorded and used by our service provider EliseAI to generate responses
|
|
64
64
|
and improve their services. You may withdraw your consent at any time by
|
|
65
65
|
unsubscribing or contacting us.
|
|
66
|
+
${phoneNumberInput
|
|
67
|
+
? html`Msg freq varies. Text STOP to opt-out of messages. Text HELP
|
|
68
|
+
for assistance.`
|
|
69
|
+
: ""}
|
|
66
70
|
</div>`;
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -81,19 +85,23 @@ const formDisclaimer = ({
|
|
|
81
85
|
recorded and used by our service provider EliseAI to generate responses
|
|
82
86
|
and improve their services. You may withdraw your consent at any time by
|
|
83
87
|
unsubscribing or contacting us.
|
|
88
|
+
${phoneNumberInput
|
|
89
|
+
? html`Msg freq varies. Text STOP to opt-out of messages. Text HELP for
|
|
90
|
+
assistance.`
|
|
91
|
+
: ""}
|
|
84
92
|
</div>`;
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
if (phoneNumberInput && orgSlug === "greystar") {
|
|
88
96
|
return html`<div style=${styleMap(disclaimerStyles.container)}>
|
|
89
97
|
By providing your phone number and clicking ${clickingButtonText}, you
|
|
90
|
-
consent to receive recurring marketing
|
|
98
|
+
consent to receive recurring marketing text and voice messages and calls
|
|
91
99
|
from Greystar or on its behalf at this number using artificial voice
|
|
92
100
|
and/or an autodialer. Messages may be AI or human-generated. Your phone
|
|
93
101
|
number and communications are shared with and recorded and used by
|
|
94
102
|
EliseAI. You are not required to provide your phone number or consent to
|
|
95
|
-
these terms to lease at this property. Msg & Data rates
|
|
96
|
-
consent to
|
|
103
|
+
these terms to lease at this property. Msg freq varies. Msg & Data rates
|
|
104
|
+
may apply. You consent to
|
|
97
105
|
<a
|
|
98
106
|
style=${styleMap(disclaimerStyles.link)}
|
|
99
107
|
href="https://www.greystar.com/privacy"
|
|
@@ -108,17 +116,17 @@ const formDisclaimer = ({
|
|
|
108
116
|
target="_blank"
|
|
109
117
|
rel="noopener noreferrer"
|
|
110
118
|
>EliseAI’s Privacy Policy</a
|
|
111
|
-
>.
|
|
119
|
+
>. Text STOP to opt-out of messages. Text HELP for assistance.
|
|
112
120
|
</div>`;
|
|
113
121
|
}
|
|
114
122
|
if (phoneNumberInput) {
|
|
115
123
|
return html` <div style=${styleMap(disclaimerStyles.container)}>
|
|
116
124
|
By providing your number and clicking ${clickingButtonText}, you consent
|
|
117
|
-
to receive recurring marketing
|
|
125
|
+
to receive recurring marketing text and voice messages and calls from or
|
|
118
126
|
on behalf of ${orgLegalName} at this number using artificial voice or an
|
|
119
127
|
autodialer system. Messages may be AI or human generated. This consent is
|
|
120
|
-
not required to lease at this property. Msg & Data rates
|
|
121
|
-
consent to this
|
|
128
|
+
not required to lease at this property. Msg freq varies. Msg & Data rates
|
|
129
|
+
may apply. You consent to this
|
|
122
130
|
<a
|
|
123
131
|
style=${styleMap(disclaimerStyles.link)}
|
|
124
132
|
href=${policyUrl}
|
|
@@ -126,7 +134,7 @@ const formDisclaimer = ({
|
|
|
126
134
|
rel="noopener noreferrer"
|
|
127
135
|
>privacy policy</a
|
|
128
136
|
>, including having your number and communications recorded and used by a
|
|
129
|
-
third party.
|
|
137
|
+
third party. Text STOP to opt-out of messages. Text HELP for assistance.
|
|
130
138
|
</div>`;
|
|
131
139
|
}
|
|
132
140
|
if (emailInput) {
|
|
@@ -394,6 +402,7 @@ export const inChatThreadDisclaimer = ({
|
|
|
394
402
|
</li>
|
|
395
403
|
`;
|
|
396
404
|
}
|
|
405
|
+
|
|
397
406
|
return html``;
|
|
398
407
|
};
|
|
399
408
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { expect } from "@esm-bundle/chai";
|
|
2
|
+
import {
|
|
3
|
+
readGoogleReserveReferral,
|
|
4
|
+
shouldOpenTourSchedulerFromUrl,
|
|
5
|
+
storeGoogleReserveReferral,
|
|
6
|
+
} from "./googleReserve";
|
|
7
|
+
|
|
8
|
+
const STORAGE_KEY = "com.eliseai.webchat.googlereserve.referral";
|
|
9
|
+
|
|
10
|
+
const visit = (search: string): void =>
|
|
11
|
+
history.replaceState(null, "", `${location.pathname}${search}`);
|
|
12
|
+
|
|
13
|
+
describe("Google Reserve", () => {
|
|
14
|
+
const originalSearch = location.search;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
22
|
+
visit(originalSearch);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("remembers a click from a Google listing, keeping the token intact", () => {
|
|
26
|
+
visit("?elise_open=tour&rwg_token=AFd1x%3D%3D");
|
|
27
|
+
storeGoogleReserveReferral(7);
|
|
28
|
+
visit("");
|
|
29
|
+
|
|
30
|
+
expect(readGoogleReserveReferral()).to.include({
|
|
31
|
+
rwgToken: "AFd1x==",
|
|
32
|
+
buildingId: 7,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("has no referral without a token or once it has expired", () => {
|
|
37
|
+
visit("?utm_source=website");
|
|
38
|
+
storeGoogleReserveReferral(7);
|
|
39
|
+
expect(readGoogleReserveReferral()).to.equal(null);
|
|
40
|
+
|
|
41
|
+
localStorage.setItem(
|
|
42
|
+
STORAGE_KEY,
|
|
43
|
+
JSON.stringify({
|
|
44
|
+
rwgToken: "AFd1x==",
|
|
45
|
+
buildingId: 7,
|
|
46
|
+
expiresAt: Date.now() - 1,
|
|
47
|
+
})
|
|
48
|
+
);
|
|
49
|
+
expect(readGoogleReserveReferral()).to.equal(null);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("opens the tour scheduler only when the URL asks for it", () => {
|
|
53
|
+
visit("?elise_open=tour");
|
|
54
|
+
expect(shouldOpenTourSchedulerFromUrl()).to.equal(true);
|
|
55
|
+
visit("?elise_open=chat");
|
|
56
|
+
expect(shouldOpenTourSchedulerFromUrl()).to.equal(false);
|
|
57
|
+
visit("");
|
|
58
|
+
expect(shouldOpenTourSchedulerFromUrl()).to.equal(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Google requires the referral token kept for 30 days after the click.
|
|
2
|
+
const REFERRAL_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
3
|
+
const REFERRAL_STORAGE_KEY = "com.eliseai.webchat.googlereserve.referral";
|
|
4
|
+
// Google "Book" links to a customer's page add this so the widget opens the tour scheduler.
|
|
5
|
+
const OPEN_PARAM = "elise_open";
|
|
6
|
+
|
|
7
|
+
type GoogleReserveReferral = {
|
|
8
|
+
rwgToken: string;
|
|
9
|
+
buildingId: number;
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const shouldOpenTourSchedulerFromUrl = (): boolean =>
|
|
14
|
+
new URLSearchParams(window.location.search).get(OPEN_PARAM) === "tour";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Remembers a click from a building's Google listing, which arrives with an
|
|
18
|
+
* `rwg_token` query param, so a booking within 30 days can be reported back.
|
|
19
|
+
*/
|
|
20
|
+
export const storeGoogleReserveReferral = (buildingId: number): void => {
|
|
21
|
+
const rwgToken = new URLSearchParams(window.location.search).get("rwg_token");
|
|
22
|
+
if (!rwgToken || !buildingId) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const referral: GoogleReserveReferral = {
|
|
26
|
+
rwgToken,
|
|
27
|
+
buildingId,
|
|
28
|
+
expiresAt: Date.now() + REFERRAL_TTL_MS,
|
|
29
|
+
};
|
|
30
|
+
localStorage.setItem(REFERRAL_STORAGE_KEY, JSON.stringify(referral));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The visitor's click from a building's Google listing within the last 30 days,
|
|
35
|
+
* sent with a booking so the backend can report it to Google.
|
|
36
|
+
*/
|
|
37
|
+
export const readGoogleReserveReferral = (): GoogleReserveReferral | null => {
|
|
38
|
+
try {
|
|
39
|
+
const referral: GoogleReserveReferral | null = JSON.parse(
|
|
40
|
+
localStorage.getItem(REFERRAL_STORAGE_KEY) ?? "null"
|
|
41
|
+
);
|
|
42
|
+
return referral?.rwgToken && Date.now() < referral.expiresAt
|
|
43
|
+
? referral
|
|
44
|
+
: null;
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
};
|