releasebird-javascript-sdk 1.0.91 → 1.0.93
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/build/index.js +1 -1
- package/package.json +1 -1
- package/published/1.0.91/index.js +1 -1
- package/published/1.0.92/index.js +1 -0
- package/published/1.0.93/index.js +1 -0
- package/published/latest/index.js +1 -1
- package/src/RbirdAutomationManager.js +24 -4
- package/src/RbirdBookingManager.js +255 -0
- package/src/index.js +21 -0
|
@@ -36,7 +36,10 @@ export class RbirdAutomationManager {
|
|
|
36
36
|
// Register event handlers
|
|
37
37
|
this.registerEventHandlers();
|
|
38
38
|
|
|
39
|
-
//
|
|
39
|
+
// Listen for WebSocket notifications from widget iframe
|
|
40
|
+
this.setupWebSocketListener();
|
|
41
|
+
|
|
42
|
+
// Start command polling (reduced frequency - WebSocket is primary)
|
|
40
43
|
this.startCommandPolling();
|
|
41
44
|
|
|
42
45
|
// Send first_seen event
|
|
@@ -47,6 +50,21 @@ export class RbirdAutomationManager {
|
|
|
47
50
|
console.log('[Rbird] Automation manager initialized');
|
|
48
51
|
}
|
|
49
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Setup listener for WebSocket notifications from widget iframe.
|
|
55
|
+
* This allows instant command execution when the backend pushes a notification.
|
|
56
|
+
*/
|
|
57
|
+
setupWebSocketListener() {
|
|
58
|
+
window.addEventListener('message', (event) => {
|
|
59
|
+
// Handle automation command notification from widget
|
|
60
|
+
if (event.data === 'automationCommand') {
|
|
61
|
+
console.log('[Rbird] Received WebSocket automation notification');
|
|
62
|
+
// Immediately fetch and execute pending commands
|
|
63
|
+
this.pollCommands();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
50
68
|
/**
|
|
51
69
|
* Get or set the first_seen timestamp
|
|
52
70
|
*/
|
|
@@ -177,7 +195,9 @@ export class RbirdAutomationManager {
|
|
|
177
195
|
}
|
|
178
196
|
|
|
179
197
|
/**
|
|
180
|
-
* Start polling for pending commands
|
|
198
|
+
* Start polling for pending commands.
|
|
199
|
+
* Polling is now a fallback mechanism - WebSocket is the primary delivery method.
|
|
200
|
+
* The interval is set to 60 seconds to catch any missed commands.
|
|
181
201
|
*/
|
|
182
202
|
startCommandPolling() {
|
|
183
203
|
if (this.pollingInterval) {
|
|
@@ -187,8 +207,8 @@ export class RbirdAutomationManager {
|
|
|
187
207
|
// Poll immediately once
|
|
188
208
|
this.pollCommands();
|
|
189
209
|
|
|
190
|
-
//
|
|
191
|
-
this.pollingInterval = setInterval(() => this.pollCommands(),
|
|
210
|
+
// Poll every 60 seconds as fallback (WebSocket handles instant delivery)
|
|
211
|
+
this.pollingInterval = setInterval(() => this.pollCommands(), 60000);
|
|
192
212
|
}
|
|
193
213
|
|
|
194
214
|
/**
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import RbirdSessionManager from './RbirdSessionManager';
|
|
2
|
+
|
|
3
|
+
// CONTENT_URL is defined globally via webpack.DefinePlugin
|
|
4
|
+
/* global CONTENT_URL */
|
|
5
|
+
|
|
6
|
+
export class RbirdBookingManager {
|
|
7
|
+
static instance;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
this.apiKey = null;
|
|
11
|
+
this.isOpen = false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static getInstance() {
|
|
15
|
+
if (!RbirdBookingManager.instance) {
|
|
16
|
+
RbirdBookingManager.instance = new RbirdBookingManager();
|
|
17
|
+
}
|
|
18
|
+
return RbirdBookingManager.instance;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
init(apiKey) {
|
|
22
|
+
if (typeof window === 'undefined') return;
|
|
23
|
+
this.apiKey = apiKey;
|
|
24
|
+
this.injectStyles();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Show the booking modal
|
|
29
|
+
* @param {Object} options - Optional configuration
|
|
30
|
+
* @param {string} options.appointmentTypeId - Pre-select a specific appointment type
|
|
31
|
+
* @param {Function} options.onSuccess - Callback when booking is completed
|
|
32
|
+
* @param {Function} options.onClose - Callback when modal is closed
|
|
33
|
+
*/
|
|
34
|
+
showBooking(options = {}) {
|
|
35
|
+
if (typeof window === 'undefined') return;
|
|
36
|
+
if (!this.apiKey) {
|
|
37
|
+
console.error('[RbirdBookingManager] SDK not initialized. Call Rbird.initialize() first.');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (this.isOpen) {
|
|
41
|
+
console.warn('[RbirdBookingManager] Booking modal is already open.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const sessionManager = RbirdSessionManager.getInstance();
|
|
46
|
+
const state = sessionManager.getState();
|
|
47
|
+
|
|
48
|
+
// Build iframe URL
|
|
49
|
+
let iframeUrl = `${CONTENT_URL}/widget?apiKey=${this.apiKey}&view=BOOKING`;
|
|
50
|
+
|
|
51
|
+
if (state?.identify?.people) {
|
|
52
|
+
iframeUrl += `&people=${state.identify.people}`;
|
|
53
|
+
}
|
|
54
|
+
if (state?.identify?.hash) {
|
|
55
|
+
iframeUrl += `&hash=${state.identify.hash}`;
|
|
56
|
+
}
|
|
57
|
+
if (sessionManager.anonymousIdentifier) {
|
|
58
|
+
iframeUrl += `&ai=${sessionManager.anonymousIdentifier}`;
|
|
59
|
+
}
|
|
60
|
+
if (options.appointmentTypeId) {
|
|
61
|
+
iframeUrl += `&appointmentTypeId=${encodeURIComponent(options.appointmentTypeId)}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.createModal(iframeUrl, options);
|
|
65
|
+
this.isOpen = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
createModal(iframeUrl, options) {
|
|
69
|
+
// Create overlay
|
|
70
|
+
const overlay = document.createElement('div');
|
|
71
|
+
overlay.className = 'rbird-booking-overlay';
|
|
72
|
+
overlay.id = 'rbird-booking-overlay';
|
|
73
|
+
|
|
74
|
+
// Create modal container
|
|
75
|
+
const modal = document.createElement('div');
|
|
76
|
+
modal.className = 'rbird-booking-modal';
|
|
77
|
+
modal.id = 'rbird-booking-modal';
|
|
78
|
+
|
|
79
|
+
// Create close button
|
|
80
|
+
const closeButton = document.createElement('button');
|
|
81
|
+
closeButton.className = 'rbird-booking-close';
|
|
82
|
+
closeButton.innerHTML = '×';
|
|
83
|
+
closeButton.onclick = () => this.closeBooking(options.onClose);
|
|
84
|
+
|
|
85
|
+
// Create iframe
|
|
86
|
+
const iframe = document.createElement('iframe');
|
|
87
|
+
iframe.className = 'rbird-booking-iframe';
|
|
88
|
+
iframe.src = iframeUrl;
|
|
89
|
+
iframe.id = 'rbird-booking-iframe';
|
|
90
|
+
iframe.allow = 'clipboard-write';
|
|
91
|
+
|
|
92
|
+
modal.appendChild(closeButton);
|
|
93
|
+
modal.appendChild(iframe);
|
|
94
|
+
overlay.appendChild(modal);
|
|
95
|
+
|
|
96
|
+
// Close on overlay click
|
|
97
|
+
overlay.addEventListener('click', (e) => {
|
|
98
|
+
if (e.target === overlay) {
|
|
99
|
+
this.closeBooking(options.onClose);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Handle messages from iframe
|
|
104
|
+
this.messageHandler = (e) => {
|
|
105
|
+
if (e.data === 'close' || e.data === 'closeWidget') {
|
|
106
|
+
this.closeBooking(options.onClose);
|
|
107
|
+
}
|
|
108
|
+
if (e.data === 'bookingSuccess') {
|
|
109
|
+
if (options.onSuccess) {
|
|
110
|
+
options.onSuccess();
|
|
111
|
+
}
|
|
112
|
+
this.closeBooking(options.onClose);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
window.addEventListener('message', this.messageHandler);
|
|
116
|
+
|
|
117
|
+
// Handle escape key
|
|
118
|
+
this.keyHandler = (e) => {
|
|
119
|
+
if (e.key === 'Escape') {
|
|
120
|
+
this.closeBooking(options.onClose);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
window.addEventListener('keydown', this.keyHandler);
|
|
124
|
+
|
|
125
|
+
document.body.appendChild(overlay);
|
|
126
|
+
|
|
127
|
+
// Animate in
|
|
128
|
+
requestAnimationFrame(() => {
|
|
129
|
+
overlay.classList.add('rbird-booking-overlay-visible');
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
closeBooking(onClose) {
|
|
134
|
+
const overlay = document.getElementById('rbird-booking-overlay');
|
|
135
|
+
if (overlay) {
|
|
136
|
+
overlay.classList.remove('rbird-booking-overlay-visible');
|
|
137
|
+
setTimeout(() => {
|
|
138
|
+
overlay.remove();
|
|
139
|
+
}, 300);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Clean up event listeners
|
|
143
|
+
if (this.messageHandler) {
|
|
144
|
+
window.removeEventListener('message', this.messageHandler);
|
|
145
|
+
}
|
|
146
|
+
if (this.keyHandler) {
|
|
147
|
+
window.removeEventListener('keydown', this.keyHandler);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
this.isOpen = false;
|
|
151
|
+
|
|
152
|
+
if (onClose) {
|
|
153
|
+
onClose();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
injectStyles() {
|
|
158
|
+
if (typeof window === 'undefined' || document.getElementById('rbird-booking-styles')) return;
|
|
159
|
+
|
|
160
|
+
const style = document.createElement('style');
|
|
161
|
+
style.id = 'rbird-booking-styles';
|
|
162
|
+
style.textContent = `
|
|
163
|
+
.rbird-booking-overlay {
|
|
164
|
+
position: fixed !important;
|
|
165
|
+
top: 0 !important;
|
|
166
|
+
left: 0 !important;
|
|
167
|
+
right: 0 !important;
|
|
168
|
+
bottom: 0 !important;
|
|
169
|
+
background-color: rgba(0, 0, 0, 0) !important;
|
|
170
|
+
display: flex !important;
|
|
171
|
+
align-items: center !important;
|
|
172
|
+
justify-content: center !important;
|
|
173
|
+
z-index: 10001 !important;
|
|
174
|
+
padding: 20px !important;
|
|
175
|
+
opacity: 0;
|
|
176
|
+
transition: background-color 0.3s, opacity 0.3s;
|
|
177
|
+
box-sizing: border-box !important;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.rbird-booking-overlay-visible {
|
|
181
|
+
background-color: rgba(0, 0, 0, 0.5) !important;
|
|
182
|
+
opacity: 1 !important;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.rbird-booking-modal {
|
|
186
|
+
position: relative !important;
|
|
187
|
+
background: #ffffff !important;
|
|
188
|
+
border-radius: 16px !important;
|
|
189
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
|
|
190
|
+
width: 100% !important;
|
|
191
|
+
max-width: 420px !important;
|
|
192
|
+
height: 80vh !important;
|
|
193
|
+
max-height: 700px !important;
|
|
194
|
+
overflow: hidden !important;
|
|
195
|
+
animation: rbirdBookingSlideIn 0.3s ease-out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.rbird-booking-close {
|
|
199
|
+
position: absolute !important;
|
|
200
|
+
top: 8px !important;
|
|
201
|
+
right: 8px !important;
|
|
202
|
+
background: rgba(0, 0, 0, 0.1) !important;
|
|
203
|
+
border: none !important;
|
|
204
|
+
width: 32px !important;
|
|
205
|
+
height: 32px !important;
|
|
206
|
+
border-radius: 50% !important;
|
|
207
|
+
font-size: 20px !important;
|
|
208
|
+
line-height: 1 !important;
|
|
209
|
+
cursor: pointer !important;
|
|
210
|
+
color: #374151 !important;
|
|
211
|
+
display: flex !important;
|
|
212
|
+
align-items: center !important;
|
|
213
|
+
justify-content: center !important;
|
|
214
|
+
transition: background-color 0.2s, color 0.2s !important;
|
|
215
|
+
z-index: 10 !important;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.rbird-booking-close:hover {
|
|
219
|
+
background: rgba(0, 0, 0, 0.2) !important;
|
|
220
|
+
color: #1f2937 !important;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.rbird-booking-iframe {
|
|
224
|
+
width: 100% !important;
|
|
225
|
+
height: 100% !important;
|
|
226
|
+
border: none !important;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@keyframes rbirdBookingSlideIn {
|
|
230
|
+
from {
|
|
231
|
+
opacity: 0;
|
|
232
|
+
transform: translateY(-20px) scale(0.95);
|
|
233
|
+
}
|
|
234
|
+
to {
|
|
235
|
+
opacity: 1;
|
|
236
|
+
transform: translateY(0) scale(1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@media (max-width: 480px) {
|
|
241
|
+
.rbird-booking-overlay {
|
|
242
|
+
padding: 0 !important;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.rbird-booking-modal {
|
|
246
|
+
max-width: 100% !important;
|
|
247
|
+
height: 100% !important;
|
|
248
|
+
max-height: 100% !important;
|
|
249
|
+
border-radius: 0 !important;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
document.head.appendChild(style);
|
|
254
|
+
}
|
|
255
|
+
}
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { RbirdBannerManager } from "./RbirdBannerManager";
|
|
|
6
6
|
import { RbirdFormManager } from "./RbirdFormManager";
|
|
7
7
|
import { RbirdSurveyManager } from "./RbirdSurveyManager";
|
|
8
8
|
import { RbirdAutomationManager } from "./RbirdAutomationManager";
|
|
9
|
+
import { RbirdBookingManager } from "./RbirdBookingManager";
|
|
9
10
|
|
|
10
11
|
class Rbird {
|
|
11
12
|
|
|
@@ -104,6 +105,10 @@ class Rbird {
|
|
|
104
105
|
const automationManager = RbirdAutomationManager.getInstance();
|
|
105
106
|
automationManager.init(apiKey);
|
|
106
107
|
|
|
108
|
+
// Initialize booking manager
|
|
109
|
+
const bookingManager = RbirdBookingManager.getInstance();
|
|
110
|
+
bookingManager.init(apiKey);
|
|
111
|
+
|
|
107
112
|
resolve();
|
|
108
113
|
});
|
|
109
114
|
});
|
|
@@ -203,6 +208,22 @@ class Rbird {
|
|
|
203
208
|
}
|
|
204
209
|
}
|
|
205
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Show the booking modal
|
|
213
|
+
* @param {Object} options - Optional configuration
|
|
214
|
+
* @param {string} options.appointmentTypeId - Pre-select a specific appointment type
|
|
215
|
+
* @param {Function} options.onSuccess - Callback when booking is completed
|
|
216
|
+
* @param {Function} options.onClose - Callback when modal is closed
|
|
217
|
+
*/
|
|
218
|
+
static showBooking(options = {}) {
|
|
219
|
+
if (typeof window === 'undefined') return;
|
|
220
|
+
try {
|
|
221
|
+
RbirdBookingManager.getInstance().showBooking(options);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
console.error(e);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
206
227
|
}
|
|
207
228
|
|
|
208
229
|
export const runFunctionWhenDomIsReady = (callback) => {
|