@pocketping/sdk-node 0.1.0 → 1.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/dist/index.d.ts CHANGED
@@ -28,11 +28,17 @@ interface Bridge {
28
28
  /** Called when a new chat session is created */
29
29
  onNewSession?(session: Session): void | Promise<void>;
30
30
  /** Called when a visitor sends a message */
31
- onMessage?(message: Message, session: Session): void | Promise<void>;
31
+ onVisitorMessage?(message: Message, session: Session): void | Promise<void>;
32
+ /** Called when an operator sends a message (for cross-bridge sync) */
33
+ onOperatorMessage?(message: Message, session: Session, sourceBridge?: string, operatorName?: string): void | Promise<void>;
32
34
  /** Called when visitor starts/stops typing */
33
35
  onTyping?(sessionId: string, isTyping: boolean): void | Promise<void>;
34
36
  /** Called when messages are marked as delivered/read */
35
- onMessageRead?(sessionId: string, messageIds: string[], status: MessageStatus): void | Promise<void>;
37
+ onMessageRead?(sessionId: string, messageIds: string[], status: MessageStatus, session: Session): void | Promise<void>;
38
+ /** Called when a custom event is triggered from the widget */
39
+ onCustomEvent?(event: CustomEvent, session: Session): void | Promise<void>;
40
+ /** Called when a user identifies themselves via PocketPing.identify() */
41
+ onIdentityUpdate?(session: Session): void | Promise<void>;
36
42
  /** Cleanup when bridge is removed */
37
43
  destroy?(): void | Promise<void>;
38
44
  }
@@ -65,6 +71,24 @@ interface PocketPingConfig {
65
71
  onNewSession?: (session: Session) => void | Promise<void>;
66
72
  /** Callback when a message is received */
67
73
  onMessage?: (message: Message, session: Session) => void | Promise<void>;
74
+ /** Callback when a custom event is received from widget */
75
+ onEvent?: (event: CustomEvent, session: Session) => void | Promise<void>;
76
+ /** Callback when a user identifies themselves */
77
+ onIdentify?: (session: Session) => void | Promise<void>;
78
+ /** Webhook URL to forward custom events (Zapier, Make, n8n, etc.) */
79
+ webhookUrl?: string;
80
+ /** Secret key for HMAC-SHA256 signature (X-PocketPing-Signature header) */
81
+ webhookSecret?: string;
82
+ /** Webhook request timeout in milliseconds (default: 5000) */
83
+ webhookTimeout?: number;
84
+ /** Minimum supported widget version (e.g., "0.2.0") */
85
+ minWidgetVersion?: string;
86
+ /** Latest available widget version (e.g., "0.3.0") */
87
+ latestWidgetVersion?: string;
88
+ /** Custom message for version warnings */
89
+ versionWarningMessage?: string;
90
+ /** URL to upgrade instructions */
91
+ versionUpgradeUrl?: string;
68
92
  }
69
93
  interface AIConfig {
70
94
  provider: AIProvider | 'openai' | 'gemini' | 'anthropic';
@@ -73,6 +97,17 @@ interface AIConfig {
73
97
  systemPrompt?: string;
74
98
  fallbackAfter?: number;
75
99
  }
100
+ /** User identity data from PocketPing.identify() */
101
+ interface UserIdentity {
102
+ /** Required unique user identifier */
103
+ id: string;
104
+ /** User's email address */
105
+ email?: string;
106
+ /** User's display name */
107
+ name?: string;
108
+ /** Any custom fields (plan, company, etc.) */
109
+ [key: string]: unknown;
110
+ }
76
111
  interface Session {
77
112
  id: string;
78
113
  visitorId: string;
@@ -81,6 +116,8 @@ interface Session {
81
116
  operatorOnline: boolean;
82
117
  aiActive: boolean;
83
118
  metadata?: SessionMetadata;
119
+ /** User identity if identified via PocketPing.identify() */
120
+ identity?: UserIdentity;
84
121
  }
85
122
  interface SessionMetadata {
86
123
  url?: string;
@@ -115,6 +152,26 @@ interface ConnectRequest {
115
152
  visitorId: string;
116
153
  sessionId?: string;
117
154
  metadata?: SessionMetadata;
155
+ /** User identity if already identified */
156
+ identity?: UserIdentity;
157
+ }
158
+ /** Tracked element configuration (for SaaS auto-tracking) */
159
+ interface TrackedElement {
160
+ /** CSS selector for the element(s) to track */
161
+ selector: string;
162
+ /** DOM event to listen for (default: 'click') */
163
+ event?: 'click' | 'submit' | 'focus' | 'change' | 'mouseenter';
164
+ /** Event name sent to backend */
165
+ name: string;
166
+ /** If provided, opens widget with this message when triggered */
167
+ widgetMessage?: string;
168
+ /** Additional data to send with the event */
169
+ data?: Record<string, unknown>;
170
+ }
171
+ /** Options for trigger() method */
172
+ interface TriggerOptions {
173
+ /** If provided, opens the widget and shows this message */
174
+ widgetMessage?: string;
118
175
  }
119
176
  interface ConnectResponse {
120
177
  sessionId: string;
@@ -122,6 +179,8 @@ interface ConnectResponse {
122
179
  operatorOnline: boolean;
123
180
  welcomeMessage?: string;
124
181
  messages: Message[];
182
+ /** Tracked elements configuration (for SaaS auto-tracking) */
183
+ trackedElements?: TrackedElement[];
125
184
  }
126
185
  interface SendMessageRequest {
127
186
  sessionId: string;
@@ -155,6 +214,13 @@ interface ReadRequest {
155
214
  interface ReadResponse {
156
215
  updated: number;
157
216
  }
217
+ interface IdentifyRequest {
218
+ sessionId: string;
219
+ identity: UserIdentity;
220
+ }
221
+ interface IdentifyResponse {
222
+ ok: boolean;
223
+ }
158
224
  interface PresenceResponse {
159
225
  online: boolean;
160
226
  operators?: Array<{
@@ -165,6 +231,41 @@ interface PresenceResponse {
165
231
  aiEnabled: boolean;
166
232
  aiActiveAfter?: number;
167
233
  }
234
+ /** Custom event sent from widget to backend or vice versa */
235
+ interface CustomEvent {
236
+ /** Event name (e.g., 'clicked_pricing', 'show_offer') */
237
+ name: string;
238
+ /** Event payload */
239
+ data?: Record<string, unknown>;
240
+ /** Timestamp of the event */
241
+ timestamp: string;
242
+ /** Session ID (populated by SDK when event comes from widget) */
243
+ sessionId?: string;
244
+ }
245
+ /** Handler for custom events */
246
+ type CustomEventHandler = (event: CustomEvent, session: Session) => void | Promise<void>;
247
+ type VersionStatus = 'ok' | 'outdated' | 'deprecated' | 'unsupported';
248
+ interface VersionCheckResult {
249
+ status: VersionStatus;
250
+ message?: string;
251
+ minVersion?: string;
252
+ latestVersion?: string;
253
+ canContinue: boolean;
254
+ }
255
+ /** Payload sent to webhook URL */
256
+ interface WebhookPayload {
257
+ /** The custom event */
258
+ event: CustomEvent;
259
+ /** Session information */
260
+ session: {
261
+ id: string;
262
+ visitorId: string;
263
+ metadata?: SessionMetadata;
264
+ identity?: UserIdentity;
265
+ };
266
+ /** Timestamp when webhook was sent */
267
+ sentAt: string;
268
+ }
168
269
 
169
270
  declare class PocketPing {
170
271
  private storage;
@@ -173,6 +274,7 @@ declare class PocketPing {
173
274
  private wss;
174
275
  private sessionSockets;
175
276
  private operatorOnline;
277
+ private eventHandlers;
176
278
  constructor(config?: PocketPingConfig);
177
279
  private initStorage;
178
280
  middleware(): (req: IncomingMessage & {
@@ -182,6 +284,7 @@ declare class PocketPing {
182
284
  private parseBody;
183
285
  attachWebSocket(server: any): void;
184
286
  private handleWebSocketMessage;
287
+ private handleCustomEvent;
185
288
  private broadcastToSession;
186
289
  handleConnect(request: ConnectRequest): Promise<ConnectResponse>;
187
290
  handleMessage(request: SendMessageRequest): Promise<SendMessageResponse>;
@@ -191,13 +294,109 @@ declare class PocketPing {
191
294
  }>;
192
295
  handlePresence(): Promise<PresenceResponse>;
193
296
  handleRead(request: ReadRequest): Promise<ReadResponse>;
297
+ /**
298
+ * Handle user identification from widget
299
+ * Called when visitor calls PocketPing.identify()
300
+ */
301
+ handleIdentify(request: IdentifyRequest): Promise<IdentifyResponse>;
302
+ /**
303
+ * Get a session by ID
304
+ */
305
+ getSession(sessionId: string): Promise<Session | null>;
194
306
  sendOperatorMessage(sessionId: string, content: string): Promise<Message>;
195
307
  setOperatorOnline(online: boolean): void;
308
+ /**
309
+ * Subscribe to custom events from widgets
310
+ * @param eventName - The name of the event to listen for, or '*' for all events
311
+ * @param handler - Callback function when event is received
312
+ * @returns Unsubscribe function
313
+ * @example
314
+ * // Listen for specific event
315
+ * pp.onEvent('clicked_pricing', async (event, session) => {
316
+ * console.log(`User ${session.visitorId} clicked pricing: ${event.data?.plan}`)
317
+ * })
318
+ *
319
+ * // Listen for all events
320
+ * pp.onEvent('*', async (event, session) => {
321
+ * console.log(`Event: ${event.name}`, event.data)
322
+ * })
323
+ */
324
+ onEvent(eventName: string, handler: CustomEventHandler): () => void;
325
+ /**
326
+ * Unsubscribe from a custom event
327
+ * @param eventName - The name of the event
328
+ * @param handler - The handler to remove
329
+ */
330
+ offEvent(eventName: string, handler: CustomEventHandler): void;
331
+ /**
332
+ * Send a custom event to a specific widget/session
333
+ * @param sessionId - The session ID to send the event to
334
+ * @param eventName - The name of the event
335
+ * @param data - Optional payload to send with the event
336
+ * @example
337
+ * // Send a promotion offer to a specific user
338
+ * pp.emitEvent('session-123', 'show_offer', {
339
+ * discount: 20,
340
+ * code: 'SAVE20',
341
+ * message: 'Special offer just for you!'
342
+ * })
343
+ */
344
+ emitEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): void;
345
+ /**
346
+ * Broadcast a custom event to all connected widgets
347
+ * @param eventName - The name of the event
348
+ * @param data - Optional payload to send with the event
349
+ * @example
350
+ * // Notify all users about maintenance
351
+ * pp.broadcastEvent('maintenance_warning', {
352
+ * message: 'Site will be down for maintenance in 5 minutes'
353
+ * })
354
+ */
355
+ broadcastEvent(eventName: string, data?: Record<string, unknown>): void;
356
+ /**
357
+ * Process a custom event server-side (runs handlers, bridges, webhooks)
358
+ * Useful for server-side automation or triggering events programmatically
359
+ * @param sessionId - The session ID to associate with the event
360
+ * @param eventName - The name of the event
361
+ * @param data - Optional payload for the event
362
+ * @example
363
+ * // Trigger event from backend logic (e.g., after purchase)
364
+ * await pp.triggerEvent('session-123', 'purchase_completed', {
365
+ * orderId: 'order-456',
366
+ * amount: 99.99
367
+ * })
368
+ */
369
+ triggerEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): Promise<void>;
196
370
  private notifyBridges;
197
371
  private notifyBridgesRead;
372
+ private notifyBridgesEvent;
373
+ private notifyBridgesIdentity;
374
+ /**
375
+ * Forward custom event to configured webhook URL (non-blocking)
376
+ * Used for integrations with Zapier, Make, n8n, or custom backends
377
+ */
378
+ private forwardToWebhook;
379
+ /**
380
+ * Forward identity update to webhook as a special event
381
+ */
382
+ private forwardIdentityToWebhook;
198
383
  addBridge(bridge: Bridge): void;
199
384
  private generateId;
200
385
  getStorage(): Storage;
386
+ /**
387
+ * Check widget version against configured min/latest versions
388
+ * @param widgetVersion - Version from X-PocketPing-Version header
389
+ * @returns Version check result with status and headers to set
390
+ */
391
+ checkWidgetVersion(widgetVersion: string | undefined): VersionCheckResult;
392
+ /**
393
+ * Set version warning headers on HTTP response
394
+ */
395
+ private setVersionHeaders;
396
+ /**
397
+ * Send version warning via WebSocket to a session
398
+ */
399
+ sendVersionWarning(sessionId: string, versionCheck: VersionCheckResult): void;
201
400
  }
202
401
 
203
402
  /**
@@ -219,4 +418,4 @@ declare class MemoryStorage implements Storage {
219
418
  cleanupOldSessions(olderThan: Date): Promise<number>;
220
419
  }
221
420
 
222
- export { type AIProvider, type Bridge, type ConnectRequest, type ConnectResponse, MemoryStorage, type Message, PocketPing, type PocketPingConfig, type PresenceResponse, type SendMessageRequest, type SendMessageResponse, type Session, type Storage };
421
+ export { type AIProvider, type Bridge, type ConnectRequest, type ConnectResponse, type CustomEvent, type CustomEventHandler, MemoryStorage, type Message, PocketPing, type PocketPingConfig, type PresenceResponse, type SendMessageRequest, type SendMessageResponse, type Session, type Storage, type TrackedElement, type TriggerOptions, type WebhookPayload };