@pocketping/sdk-node 1.6.0 → 1.7.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/README.md +58 -0
- package/dist/index.cjs +2714 -2448
- package/dist/index.d.cts +429 -334
- package/dist/index.d.ts +429 -334
- package/dist/index.js +2708 -2449
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Bridge message IDs for edit/delete sync.
|
|
@@ -31,6 +31,156 @@ interface Storage {
|
|
|
31
31
|
cleanupOldSessions?(olderThan: Date): Promise<number>;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
declare class PocketPing {
|
|
35
|
+
private storage;
|
|
36
|
+
private bridges;
|
|
37
|
+
private config;
|
|
38
|
+
private wss;
|
|
39
|
+
private sessionSockets;
|
|
40
|
+
private operatorOnline;
|
|
41
|
+
private eventHandlers;
|
|
42
|
+
constructor(config?: PocketPingConfig);
|
|
43
|
+
private initStorage;
|
|
44
|
+
middleware(): (req: IncomingMessage & {
|
|
45
|
+
body?: unknown;
|
|
46
|
+
query?: Record<string, string>;
|
|
47
|
+
}, res: ServerResponse, next?: () => void) => void;
|
|
48
|
+
private parseBody;
|
|
49
|
+
attachWebSocket(server: any): void;
|
|
50
|
+
private handleWebSocketMessage;
|
|
51
|
+
private handleCustomEvent;
|
|
52
|
+
private broadcastToSession;
|
|
53
|
+
handleConnect(request: ConnectRequest): Promise<ConnectResponse>;
|
|
54
|
+
handleMessage(request: SendMessageRequest): Promise<SendMessageResponse>;
|
|
55
|
+
handleGetMessages(request: GetMessagesRequest): Promise<GetMessagesResponse>;
|
|
56
|
+
handleTyping(request: TypingRequest): Promise<{
|
|
57
|
+
ok: boolean;
|
|
58
|
+
}>;
|
|
59
|
+
handlePresence(): Promise<PresenceResponse>;
|
|
60
|
+
handleRead(request: ReadRequest): Promise<ReadResponse>;
|
|
61
|
+
/**
|
|
62
|
+
* Handle user identification from widget
|
|
63
|
+
* Called when visitor calls PocketPing.identify()
|
|
64
|
+
*/
|
|
65
|
+
handleIdentify(request: IdentifyRequest): Promise<IdentifyResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Get a session by ID
|
|
68
|
+
*/
|
|
69
|
+
getSession(sessionId: string): Promise<Session | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Handle message edit from widget
|
|
72
|
+
* Only the message sender can edit their own messages
|
|
73
|
+
*/
|
|
74
|
+
handleEditMessage(request: EditMessageRequest): Promise<EditMessageResponse>;
|
|
75
|
+
/**
|
|
76
|
+
* Handle message delete from widget
|
|
77
|
+
* Only the message sender can delete their own messages
|
|
78
|
+
*/
|
|
79
|
+
handleDeleteMessage(request: DeleteMessageRequest): Promise<DeleteMessageResponse>;
|
|
80
|
+
sendOperatorMessage(sessionId: string, content: string): Promise<Message>;
|
|
81
|
+
setOperatorOnline(online: boolean): void;
|
|
82
|
+
/**
|
|
83
|
+
* Subscribe to custom events from widgets
|
|
84
|
+
* @param eventName - The name of the event to listen for, or '*' for all events
|
|
85
|
+
* @param handler - Callback function when event is received
|
|
86
|
+
* @returns Unsubscribe function
|
|
87
|
+
* @example
|
|
88
|
+
* // Listen for specific event
|
|
89
|
+
* pp.onEvent('clicked_pricing', async (event, session) => {
|
|
90
|
+
* console.log(`User ${session.visitorId} clicked pricing: ${event.data?.plan}`)
|
|
91
|
+
* })
|
|
92
|
+
*
|
|
93
|
+
* // Listen for all events
|
|
94
|
+
* pp.onEvent('*', async (event, session) => {
|
|
95
|
+
* console.log(`Event: ${event.name}`, event.data)
|
|
96
|
+
* })
|
|
97
|
+
*/
|
|
98
|
+
onEvent(eventName: string, handler: CustomEventHandler): () => void;
|
|
99
|
+
/**
|
|
100
|
+
* Unsubscribe from a custom event
|
|
101
|
+
* @param eventName - The name of the event
|
|
102
|
+
* @param handler - The handler to remove
|
|
103
|
+
*/
|
|
104
|
+
offEvent(eventName: string, handler: CustomEventHandler): void;
|
|
105
|
+
/**
|
|
106
|
+
* Send a custom event to a specific widget/session
|
|
107
|
+
* @param sessionId - The session ID to send the event to
|
|
108
|
+
* @param eventName - The name of the event
|
|
109
|
+
* @param data - Optional payload to send with the event
|
|
110
|
+
* @example
|
|
111
|
+
* // Send a promotion offer to a specific user
|
|
112
|
+
* pp.emitEvent('session-123', 'show_offer', {
|
|
113
|
+
* discount: 20,
|
|
114
|
+
* code: 'SAVE20',
|
|
115
|
+
* message: 'Special offer just for you!'
|
|
116
|
+
* })
|
|
117
|
+
*/
|
|
118
|
+
emitEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): void;
|
|
119
|
+
/**
|
|
120
|
+
* Broadcast a custom event to all connected widgets
|
|
121
|
+
* @param eventName - The name of the event
|
|
122
|
+
* @param data - Optional payload to send with the event
|
|
123
|
+
* @example
|
|
124
|
+
* // Notify all users about maintenance
|
|
125
|
+
* pp.broadcastEvent('maintenance_warning', {
|
|
126
|
+
* message: 'Site will be down for maintenance in 5 minutes'
|
|
127
|
+
* })
|
|
128
|
+
*/
|
|
129
|
+
broadcastEvent(eventName: string, data?: Record<string, unknown>): void;
|
|
130
|
+
/**
|
|
131
|
+
* Process a custom event server-side (runs handlers, bridges, webhooks)
|
|
132
|
+
* Useful for server-side automation or triggering events programmatically
|
|
133
|
+
* @param sessionId - The session ID to associate with the event
|
|
134
|
+
* @param eventName - The name of the event
|
|
135
|
+
* @param data - Optional payload for the event
|
|
136
|
+
* @example
|
|
137
|
+
* // Trigger event from backend logic (e.g., after purchase)
|
|
138
|
+
* await pp.triggerEvent('session-123', 'purchase_completed', {
|
|
139
|
+
* orderId: 'order-456',
|
|
140
|
+
* amount: 99.99
|
|
141
|
+
* })
|
|
142
|
+
*/
|
|
143
|
+
triggerEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): Promise<void>;
|
|
144
|
+
private notifyBridges;
|
|
145
|
+
private notifyBridgesRead;
|
|
146
|
+
private notifyBridgesEvent;
|
|
147
|
+
private notifyBridgesIdentity;
|
|
148
|
+
/**
|
|
149
|
+
* Sync message edit to all bridges that support it
|
|
150
|
+
*/
|
|
151
|
+
private syncEditToBridges;
|
|
152
|
+
/**
|
|
153
|
+
* Sync message delete to all bridges that support it
|
|
154
|
+
*/
|
|
155
|
+
private syncDeleteToBridges;
|
|
156
|
+
/**
|
|
157
|
+
* Forward custom event to configured webhook URL (non-blocking)
|
|
158
|
+
* Used for integrations with Zapier, Make, n8n, or custom backends
|
|
159
|
+
*/
|
|
160
|
+
private forwardToWebhook;
|
|
161
|
+
/**
|
|
162
|
+
* Forward identity update to webhook as a special event
|
|
163
|
+
*/
|
|
164
|
+
private forwardIdentityToWebhook;
|
|
165
|
+
addBridge(bridge: Bridge): void;
|
|
166
|
+
private generateId;
|
|
167
|
+
getStorage(): Storage;
|
|
168
|
+
/**
|
|
169
|
+
* Check widget version against configured min/latest versions
|
|
170
|
+
* @param widgetVersion - Version from X-PocketPing-Version header
|
|
171
|
+
* @returns Version check result with status and headers to set
|
|
172
|
+
*/
|
|
173
|
+
checkWidgetVersion(widgetVersion: string | undefined): VersionCheckResult;
|
|
174
|
+
/**
|
|
175
|
+
* Set version warning headers on HTTP response
|
|
176
|
+
*/
|
|
177
|
+
private setVersionHeaders;
|
|
178
|
+
/**
|
|
179
|
+
* Send version warning via WebSocket to a session
|
|
180
|
+
*/
|
|
181
|
+
sendVersionWarning(sessionId: string, versionCheck: VersionCheckResult): void;
|
|
182
|
+
}
|
|
183
|
+
|
|
34
184
|
/**
|
|
35
185
|
* Result from sending a message to a bridge.
|
|
36
186
|
* Contains the bridge-specific message ID for later edit/delete.
|
|
@@ -84,19 +234,6 @@ interface Bridge {
|
|
|
84
234
|
destroy?(): void | Promise<void>;
|
|
85
235
|
}
|
|
86
236
|
|
|
87
|
-
/**
|
|
88
|
-
* AI provider interface.
|
|
89
|
-
* Implement this to add support for OpenAI, Gemini, Claude, or local models.
|
|
90
|
-
*/
|
|
91
|
-
interface AIProvider {
|
|
92
|
-
/** Provider name */
|
|
93
|
-
name: string;
|
|
94
|
-
/** Generate a response to the conversation */
|
|
95
|
-
generateResponse(messages: Message[], systemPrompt?: string): Promise<string>;
|
|
96
|
-
/** Check if the provider is available */
|
|
97
|
-
isAvailable(): Promise<boolean>;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
237
|
/**
|
|
101
238
|
* IP Filtering utilities for PocketPing SDK
|
|
102
239
|
* Supports CIDR notation and individual IP addresses
|
|
@@ -134,6 +271,10 @@ interface IpFilterLogEvent {
|
|
|
134
271
|
timestamp: Date;
|
|
135
272
|
sessionId?: string;
|
|
136
273
|
}
|
|
274
|
+
interface IpFilterResult {
|
|
275
|
+
allowed: boolean;
|
|
276
|
+
reason: 'allowlist' | 'blocklist' | 'custom' | 'not_in_allowlist' | 'default';
|
|
277
|
+
}
|
|
137
278
|
/**
|
|
138
279
|
* Custom IP filter callback
|
|
139
280
|
* Return true to allow, false to block, undefined to defer to list-based filtering
|
|
@@ -142,6 +283,95 @@ type IpFilterCallback = (ip: string, request: {
|
|
|
142
283
|
path: string;
|
|
143
284
|
sessionId?: string;
|
|
144
285
|
}) => boolean | undefined | Promise<boolean | undefined>;
|
|
286
|
+
/**
|
|
287
|
+
* Check if an IP matches a CIDR range or exact IP
|
|
288
|
+
*/
|
|
289
|
+
declare function ipMatchesCidr(ip: string, cidr: string): boolean;
|
|
290
|
+
/**
|
|
291
|
+
* Check if IP matches any entry in a list of IPs/CIDRs
|
|
292
|
+
*/
|
|
293
|
+
declare function ipMatchesAny(ip: string, list: string[]): boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Check IP filter with support for custom filter callback
|
|
296
|
+
*/
|
|
297
|
+
declare function checkIpFilter(ip: string, config: IpFilterConfig, requestInfo: {
|
|
298
|
+
path: string;
|
|
299
|
+
sessionId?: string;
|
|
300
|
+
}): Promise<IpFilterResult>;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* User-Agent Filtering utilities for PocketPing SDK
|
|
304
|
+
* Blocks bots and unwanted user agents to prevent spam sessions
|
|
305
|
+
*/
|
|
306
|
+
type UaFilterMode = 'allowlist' | 'blocklist' | 'both';
|
|
307
|
+
type UaFilterReason = 'allowlist' | 'blocklist' | 'default_bot' | 'custom' | 'not_in_allowlist' | 'default';
|
|
308
|
+
interface UaFilterConfig {
|
|
309
|
+
/** Enable/disable UA filtering (default: false) */
|
|
310
|
+
enabled?: boolean;
|
|
311
|
+
/** Filter mode (default: 'blocklist') */
|
|
312
|
+
mode?: UaFilterMode;
|
|
313
|
+
/** UA patterns to allow (case-insensitive substring match) */
|
|
314
|
+
allowlist?: string[];
|
|
315
|
+
/** UA patterns to block (case-insensitive substring match) */
|
|
316
|
+
blocklist?: string[];
|
|
317
|
+
/** Include default bot patterns in blocklist (default: true) */
|
|
318
|
+
useDefaultBots?: boolean;
|
|
319
|
+
/** Custom filter callback for advanced logic */
|
|
320
|
+
customFilter?: UaFilterCallback;
|
|
321
|
+
/** Log blocked requests for security auditing (default: true) */
|
|
322
|
+
logBlocked?: boolean;
|
|
323
|
+
/** Custom logger function */
|
|
324
|
+
logger?: (event: UaFilterLogEvent) => void;
|
|
325
|
+
/** HTTP status code for blocked requests (default: 403) */
|
|
326
|
+
blockedStatusCode?: number;
|
|
327
|
+
/** Response message for blocked requests (default: 'Forbidden') */
|
|
328
|
+
blockedMessage?: string;
|
|
329
|
+
}
|
|
330
|
+
interface UaFilterLogEvent {
|
|
331
|
+
type: 'blocked' | 'allowed';
|
|
332
|
+
userAgent: string;
|
|
333
|
+
reason: UaFilterReason;
|
|
334
|
+
matchedPattern?: string;
|
|
335
|
+
path: string;
|
|
336
|
+
timestamp: Date;
|
|
337
|
+
sessionId?: string;
|
|
338
|
+
}
|
|
339
|
+
interface UaFilterResult {
|
|
340
|
+
allowed: boolean;
|
|
341
|
+
reason: UaFilterReason;
|
|
342
|
+
matchedPattern?: string;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Custom UA filter callback
|
|
346
|
+
* Return true to allow, false to block, undefined to defer to list-based filtering
|
|
347
|
+
*/
|
|
348
|
+
type UaFilterCallback = (userAgent: string, request: {
|
|
349
|
+
path: string;
|
|
350
|
+
sessionId?: string;
|
|
351
|
+
}) => boolean | undefined | Promise<boolean | undefined>;
|
|
352
|
+
/**
|
|
353
|
+
* Default bot patterns to block
|
|
354
|
+
* These are known bots, crawlers, and automated tools that shouldn't create chat sessions
|
|
355
|
+
*/
|
|
356
|
+
declare const DEFAULT_BOT_PATTERNS: string[];
|
|
357
|
+
/**
|
|
358
|
+
* Check if a user-agent matches any pattern in the list
|
|
359
|
+
* Supports both substring matching and regex patterns (e.g., /bot-\d+/)
|
|
360
|
+
* Returns the matched pattern or undefined
|
|
361
|
+
*/
|
|
362
|
+
declare function matchesAnyPattern(userAgent: string, patterns: string[]): string | undefined;
|
|
363
|
+
/**
|
|
364
|
+
* Check UA filter with support for custom filter callback
|
|
365
|
+
*/
|
|
366
|
+
declare function checkUaFilter(userAgent: string | undefined, config: UaFilterConfig, requestInfo: {
|
|
367
|
+
path: string;
|
|
368
|
+
sessionId?: string;
|
|
369
|
+
}): Promise<UaFilterResult>;
|
|
370
|
+
/**
|
|
371
|
+
* Check if a user-agent looks like a bot based on default patterns
|
|
372
|
+
* Utility function for quick bot detection
|
|
373
|
+
*/
|
|
374
|
+
declare function isBot(userAgent: string): boolean;
|
|
145
375
|
|
|
146
376
|
interface PocketPingConfig {
|
|
147
377
|
/** Storage adapter for sessions and messages */
|
|
@@ -178,6 +408,8 @@ interface PocketPingConfig {
|
|
|
178
408
|
versionUpgradeUrl?: string;
|
|
179
409
|
/** IP filtering configuration (allowlist/blocklist) */
|
|
180
410
|
ipFilter?: IpFilterConfig;
|
|
411
|
+
/** User-Agent filtering configuration (block bots/crawlers) */
|
|
412
|
+
uaFilter?: UaFilterConfig;
|
|
181
413
|
}
|
|
182
414
|
interface AIConfig {
|
|
183
415
|
provider: AIProvider | 'openai' | 'gemini' | 'anthropic';
|
|
@@ -416,327 +648,17 @@ interface WebhookPayload {
|
|
|
416
648
|
sentAt: string;
|
|
417
649
|
}
|
|
418
650
|
|
|
419
|
-
declare class PocketPing {
|
|
420
|
-
private storage;
|
|
421
|
-
private bridges;
|
|
422
|
-
private config;
|
|
423
|
-
private wss;
|
|
424
|
-
private sessionSockets;
|
|
425
|
-
private operatorOnline;
|
|
426
|
-
private eventHandlers;
|
|
427
|
-
constructor(config?: PocketPingConfig);
|
|
428
|
-
private initStorage;
|
|
429
|
-
middleware(): (req: IncomingMessage & {
|
|
430
|
-
body?: unknown;
|
|
431
|
-
query?: Record<string, string>;
|
|
432
|
-
}, res: ServerResponse, next?: () => void) => void;
|
|
433
|
-
private parseBody;
|
|
434
|
-
attachWebSocket(server: any): void;
|
|
435
|
-
private handleWebSocketMessage;
|
|
436
|
-
private handleCustomEvent;
|
|
437
|
-
private broadcastToSession;
|
|
438
|
-
handleConnect(request: ConnectRequest): Promise<ConnectResponse>;
|
|
439
|
-
handleMessage(request: SendMessageRequest): Promise<SendMessageResponse>;
|
|
440
|
-
handleGetMessages(request: GetMessagesRequest): Promise<GetMessagesResponse>;
|
|
441
|
-
handleTyping(request: TypingRequest): Promise<{
|
|
442
|
-
ok: boolean;
|
|
443
|
-
}>;
|
|
444
|
-
handlePresence(): Promise<PresenceResponse>;
|
|
445
|
-
handleRead(request: ReadRequest): Promise<ReadResponse>;
|
|
446
|
-
/**
|
|
447
|
-
* Handle user identification from widget
|
|
448
|
-
* Called when visitor calls PocketPing.identify()
|
|
449
|
-
*/
|
|
450
|
-
handleIdentify(request: IdentifyRequest): Promise<IdentifyResponse>;
|
|
451
|
-
/**
|
|
452
|
-
* Get a session by ID
|
|
453
|
-
*/
|
|
454
|
-
getSession(sessionId: string): Promise<Session | null>;
|
|
455
|
-
/**
|
|
456
|
-
* Handle message edit from widget
|
|
457
|
-
* Only the message sender can edit their own messages
|
|
458
|
-
*/
|
|
459
|
-
handleEditMessage(request: EditMessageRequest): Promise<EditMessageResponse>;
|
|
460
|
-
/**
|
|
461
|
-
* Handle message delete from widget
|
|
462
|
-
* Only the message sender can delete their own messages
|
|
463
|
-
*/
|
|
464
|
-
handleDeleteMessage(request: DeleteMessageRequest): Promise<DeleteMessageResponse>;
|
|
465
|
-
sendOperatorMessage(sessionId: string, content: string): Promise<Message>;
|
|
466
|
-
setOperatorOnline(online: boolean): void;
|
|
467
|
-
/**
|
|
468
|
-
* Subscribe to custom events from widgets
|
|
469
|
-
* @param eventName - The name of the event to listen for, or '*' for all events
|
|
470
|
-
* @param handler - Callback function when event is received
|
|
471
|
-
* @returns Unsubscribe function
|
|
472
|
-
* @example
|
|
473
|
-
* // Listen for specific event
|
|
474
|
-
* pp.onEvent('clicked_pricing', async (event, session) => {
|
|
475
|
-
* console.log(`User ${session.visitorId} clicked pricing: ${event.data?.plan}`)
|
|
476
|
-
* })
|
|
477
|
-
*
|
|
478
|
-
* // Listen for all events
|
|
479
|
-
* pp.onEvent('*', async (event, session) => {
|
|
480
|
-
* console.log(`Event: ${event.name}`, event.data)
|
|
481
|
-
* })
|
|
482
|
-
*/
|
|
483
|
-
onEvent(eventName: string, handler: CustomEventHandler): () => void;
|
|
484
|
-
/**
|
|
485
|
-
* Unsubscribe from a custom event
|
|
486
|
-
* @param eventName - The name of the event
|
|
487
|
-
* @param handler - The handler to remove
|
|
488
|
-
*/
|
|
489
|
-
offEvent(eventName: string, handler: CustomEventHandler): void;
|
|
490
|
-
/**
|
|
491
|
-
* Send a custom event to a specific widget/session
|
|
492
|
-
* @param sessionId - The session ID to send the event to
|
|
493
|
-
* @param eventName - The name of the event
|
|
494
|
-
* @param data - Optional payload to send with the event
|
|
495
|
-
* @example
|
|
496
|
-
* // Send a promotion offer to a specific user
|
|
497
|
-
* pp.emitEvent('session-123', 'show_offer', {
|
|
498
|
-
* discount: 20,
|
|
499
|
-
* code: 'SAVE20',
|
|
500
|
-
* message: 'Special offer just for you!'
|
|
501
|
-
* })
|
|
502
|
-
*/
|
|
503
|
-
emitEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): void;
|
|
504
|
-
/**
|
|
505
|
-
* Broadcast a custom event to all connected widgets
|
|
506
|
-
* @param eventName - The name of the event
|
|
507
|
-
* @param data - Optional payload to send with the event
|
|
508
|
-
* @example
|
|
509
|
-
* // Notify all users about maintenance
|
|
510
|
-
* pp.broadcastEvent('maintenance_warning', {
|
|
511
|
-
* message: 'Site will be down for maintenance in 5 minutes'
|
|
512
|
-
* })
|
|
513
|
-
*/
|
|
514
|
-
broadcastEvent(eventName: string, data?: Record<string, unknown>): void;
|
|
515
|
-
/**
|
|
516
|
-
* Process a custom event server-side (runs handlers, bridges, webhooks)
|
|
517
|
-
* Useful for server-side automation or triggering events programmatically
|
|
518
|
-
* @param sessionId - The session ID to associate with the event
|
|
519
|
-
* @param eventName - The name of the event
|
|
520
|
-
* @param data - Optional payload for the event
|
|
521
|
-
* @example
|
|
522
|
-
* // Trigger event from backend logic (e.g., after purchase)
|
|
523
|
-
* await pp.triggerEvent('session-123', 'purchase_completed', {
|
|
524
|
-
* orderId: 'order-456',
|
|
525
|
-
* amount: 99.99
|
|
526
|
-
* })
|
|
527
|
-
*/
|
|
528
|
-
triggerEvent(sessionId: string, eventName: string, data?: Record<string, unknown>): Promise<void>;
|
|
529
|
-
private notifyBridges;
|
|
530
|
-
private notifyBridgesRead;
|
|
531
|
-
private notifyBridgesEvent;
|
|
532
|
-
private notifyBridgesIdentity;
|
|
533
|
-
/**
|
|
534
|
-
* Sync message edit to all bridges that support it
|
|
535
|
-
*/
|
|
536
|
-
private syncEditToBridges;
|
|
537
|
-
/**
|
|
538
|
-
* Sync message delete to all bridges that support it
|
|
539
|
-
*/
|
|
540
|
-
private syncDeleteToBridges;
|
|
541
|
-
/**
|
|
542
|
-
* Forward custom event to configured webhook URL (non-blocking)
|
|
543
|
-
* Used for integrations with Zapier, Make, n8n, or custom backends
|
|
544
|
-
*/
|
|
545
|
-
private forwardToWebhook;
|
|
546
|
-
/**
|
|
547
|
-
* Forward identity update to webhook as a special event
|
|
548
|
-
*/
|
|
549
|
-
private forwardIdentityToWebhook;
|
|
550
|
-
addBridge(bridge: Bridge): void;
|
|
551
|
-
private generateId;
|
|
552
|
-
getStorage(): Storage;
|
|
553
|
-
/**
|
|
554
|
-
* Check widget version against configured min/latest versions
|
|
555
|
-
* @param widgetVersion - Version from X-PocketPing-Version header
|
|
556
|
-
* @returns Version check result with status and headers to set
|
|
557
|
-
*/
|
|
558
|
-
checkWidgetVersion(widgetVersion: string | undefined): VersionCheckResult;
|
|
559
|
-
/**
|
|
560
|
-
* Set version warning headers on HTTP response
|
|
561
|
-
*/
|
|
562
|
-
private setVersionHeaders;
|
|
563
|
-
/**
|
|
564
|
-
* Send version warning via WebSocket to a session
|
|
565
|
-
*/
|
|
566
|
-
sendVersionWarning(sessionId: string, versionCheck: VersionCheckResult): void;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* In-memory storage adapter.
|
|
571
|
-
* Useful for development and testing. Data is lost on restart.
|
|
572
|
-
*/
|
|
573
|
-
declare class MemoryStorage implements Storage {
|
|
574
|
-
private sessions;
|
|
575
|
-
private messages;
|
|
576
|
-
private messageById;
|
|
577
|
-
private bridgeMessageIds;
|
|
578
|
-
createSession(session: Session): Promise<void>;
|
|
579
|
-
getSession(sessionId: string): Promise<Session | null>;
|
|
580
|
-
getSessionByVisitorId(visitorId: string): Promise<Session | null>;
|
|
581
|
-
updateSession(session: Session): Promise<void>;
|
|
582
|
-
deleteSession(sessionId: string): Promise<void>;
|
|
583
|
-
saveMessage(message: Message): Promise<void>;
|
|
584
|
-
getMessages(sessionId: string, after?: string, limit?: number): Promise<Message[]>;
|
|
585
|
-
getMessage(messageId: string): Promise<Message | null>;
|
|
586
|
-
updateMessage(message: Message): Promise<void>;
|
|
587
|
-
saveBridgeMessageIds(messageId: string, bridgeIds: BridgeMessageIds): Promise<void>;
|
|
588
|
-
getBridgeMessageIds(messageId: string): Promise<BridgeMessageIds | null>;
|
|
589
|
-
cleanupOldSessions(olderThan: Date): Promise<number>;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
/** Attachment from an operator message */
|
|
593
|
-
interface OperatorAttachment {
|
|
594
|
-
filename: string;
|
|
595
|
-
mimeType: string;
|
|
596
|
-
size: number;
|
|
597
|
-
data: Buffer;
|
|
598
|
-
bridgeFileId?: string;
|
|
599
|
-
}
|
|
600
|
-
/** Callback when operator sends a message from a bridge */
|
|
601
|
-
type OperatorMessageCallback = (sessionId: string, content: string, operatorName: string, sourceBridge: 'telegram' | 'discord' | 'slack', attachments: OperatorAttachment[], replyToBridgeMessageId?: number | null, bridgeMessageId?: number | string | null) => void | Promise<void>;
|
|
602
|
-
type OperatorMessageEditCallback = (sessionId: string, bridgeMessageId: number | string, content: string, sourceBridge: 'telegram' | 'discord' | 'slack', editedAt?: string) => void | Promise<void>;
|
|
603
|
-
type OperatorMessageDeleteCallback = (sessionId: string, bridgeMessageId: number | string, sourceBridge: 'telegram' | 'discord' | 'slack', deletedAt?: string) => void | Promise<void>;
|
|
604
|
-
/** Webhook handler configuration */
|
|
605
|
-
interface WebhookConfig {
|
|
606
|
-
telegramBotToken?: string;
|
|
607
|
-
slackBotToken?: string;
|
|
608
|
-
discordBotToken?: string;
|
|
609
|
-
allowedBotIds?: string[];
|
|
610
|
-
onOperatorMessage: OperatorMessageCallback;
|
|
611
|
-
onOperatorMessageEdit?: OperatorMessageEditCallback;
|
|
612
|
-
onOperatorMessageDelete?: OperatorMessageDeleteCallback;
|
|
613
|
-
}
|
|
614
|
-
declare class WebhookHandler {
|
|
615
|
-
private config;
|
|
616
|
-
constructor(config: WebhookConfig);
|
|
617
|
-
/**
|
|
618
|
-
* Create an Express/Connect middleware for handling Telegram webhooks
|
|
619
|
-
*/
|
|
620
|
-
handleTelegramWebhook(): (req: IncomingMessage & {
|
|
621
|
-
body?: unknown;
|
|
622
|
-
}, res: ServerResponse) => Promise<void>;
|
|
623
|
-
/**
|
|
624
|
-
* Create an Express/Connect middleware for handling Slack webhooks
|
|
625
|
-
*/
|
|
626
|
-
handleSlackWebhook(): (req: IncomingMessage & {
|
|
627
|
-
body?: unknown;
|
|
628
|
-
}, res: ServerResponse) => Promise<void>;
|
|
629
|
-
/**
|
|
630
|
-
* Create an Express/Connect middleware for handling Discord webhooks
|
|
631
|
-
*/
|
|
632
|
-
handleDiscordWebhook(): (req: IncomingMessage & {
|
|
633
|
-
body?: unknown;
|
|
634
|
-
}, res: ServerResponse) => Promise<void>;
|
|
635
|
-
private parseBody;
|
|
636
|
-
private writeOK;
|
|
637
|
-
private downloadTelegramFile;
|
|
638
|
-
private downloadSlackFile;
|
|
639
|
-
private getSlackUserName;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
651
|
/**
|
|
643
|
-
*
|
|
644
|
-
|
|
645
|
-
interface TelegramBridgeOptions {
|
|
646
|
-
/** Parse mode for message formatting */
|
|
647
|
-
parseMode?: 'HTML' | 'Markdown';
|
|
648
|
-
/** Disable notification sound */
|
|
649
|
-
disableNotification?: boolean;
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Telegram Bridge for PocketPing.
|
|
653
|
-
* Sends visitor messages to a Telegram chat using the Bot API.
|
|
654
|
-
*
|
|
655
|
-
* @example
|
|
656
|
-
* ```ts
|
|
657
|
-
* const telegram = new TelegramBridge(
|
|
658
|
-
* 'BOT_TOKEN',
|
|
659
|
-
* '-1001234567890',
|
|
660
|
-
* { parseMode: 'HTML' }
|
|
661
|
-
* );
|
|
662
|
-
* const pocketping = new PocketPing({ bridges: [telegram] });
|
|
663
|
-
* ```
|
|
652
|
+
* AI provider interface.
|
|
653
|
+
* Implement this to add support for OpenAI, Gemini, Claude, or local models.
|
|
664
654
|
*/
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
private readonly baseUrl;
|
|
673
|
-
constructor(botToken: string, chatId: string | number, options?: TelegramBridgeOptions);
|
|
674
|
-
/**
|
|
675
|
-
* Initialize the bridge (optional setup)
|
|
676
|
-
*/
|
|
677
|
-
init(pocketping: PocketPing): Promise<void>;
|
|
678
|
-
/**
|
|
679
|
-
* Called when a new chat session is created
|
|
680
|
-
*/
|
|
681
|
-
onNewSession(session: Session): Promise<void>;
|
|
682
|
-
/**
|
|
683
|
-
* Called when a visitor sends a message.
|
|
684
|
-
* Returns the Telegram message ID for edit/delete sync.
|
|
685
|
-
*/
|
|
686
|
-
onVisitorMessage(message: Message, session: Session): Promise<BridgeMessageResult>;
|
|
687
|
-
/**
|
|
688
|
-
* Called when an operator sends a message (for cross-bridge sync)
|
|
689
|
-
*/
|
|
690
|
-
onOperatorMessage(message: Message, _session: Session, sourceBridge?: string, operatorName?: string): Promise<void>;
|
|
691
|
-
/**
|
|
692
|
-
* Called when visitor starts/stops typing
|
|
693
|
-
*/
|
|
694
|
-
onTyping(sessionId: string, isTyping: boolean): Promise<void>;
|
|
695
|
-
/**
|
|
696
|
-
* Called when a visitor edits their message.
|
|
697
|
-
* @returns true if edit succeeded, false otherwise
|
|
698
|
-
*/
|
|
699
|
-
onMessageEdit(_messageId: string, newContent: string, bridgeMessageId: string | number): Promise<boolean>;
|
|
700
|
-
/**
|
|
701
|
-
* Called when a visitor deletes their message.
|
|
702
|
-
* @returns true if delete succeeded, false otherwise
|
|
703
|
-
*/
|
|
704
|
-
onMessageDelete(_messageId: string, bridgeMessageId: string | number): Promise<boolean>;
|
|
705
|
-
/**
|
|
706
|
-
* Called when a custom event is triggered from the widget
|
|
707
|
-
*/
|
|
708
|
-
onCustomEvent(event: {
|
|
709
|
-
name: string;
|
|
710
|
-
data?: Record<string, unknown>;
|
|
711
|
-
}, session: Session): Promise<void>;
|
|
712
|
-
/**
|
|
713
|
-
* Called when a user identifies themselves via PocketPing.identify()
|
|
714
|
-
*/
|
|
715
|
-
onIdentityUpdate(session: Session): Promise<void>;
|
|
716
|
-
/**
|
|
717
|
-
* Send a message to the Telegram chat
|
|
718
|
-
*/
|
|
719
|
-
private sendMessage;
|
|
720
|
-
/**
|
|
721
|
-
* Send a chat action (e.g., "typing")
|
|
722
|
-
*/
|
|
723
|
-
private sendChatAction;
|
|
724
|
-
/**
|
|
725
|
-
* Format new session notification
|
|
726
|
-
*/
|
|
727
|
-
private formatNewSession;
|
|
728
|
-
/**
|
|
729
|
-
* Format visitor message
|
|
730
|
-
*/
|
|
731
|
-
private formatVisitorMessage;
|
|
732
|
-
/**
|
|
733
|
-
* Escape HTML special characters
|
|
734
|
-
*/
|
|
735
|
-
private escapeHtml;
|
|
736
|
-
/**
|
|
737
|
-
* Escape Markdown special characters
|
|
738
|
-
*/
|
|
739
|
-
private escapeMarkdown;
|
|
655
|
+
interface AIProvider {
|
|
656
|
+
/** Provider name */
|
|
657
|
+
name: string;
|
|
658
|
+
/** Generate a response to the conversation */
|
|
659
|
+
generateResponse(messages: Message[], systemPrompt?: string): Promise<string>;
|
|
660
|
+
/** Check if the provider is available */
|
|
661
|
+
isAvailable(): Promise<boolean>;
|
|
740
662
|
}
|
|
741
663
|
|
|
742
664
|
/**
|
|
@@ -958,4 +880,177 @@ declare class SlackBridge implements Bridge {
|
|
|
958
880
|
private escapeSlack;
|
|
959
881
|
}
|
|
960
882
|
|
|
961
|
-
|
|
883
|
+
/**
|
|
884
|
+
* Options for TelegramBridge
|
|
885
|
+
*/
|
|
886
|
+
interface TelegramBridgeOptions {
|
|
887
|
+
/** Parse mode for message formatting */
|
|
888
|
+
parseMode?: 'HTML' | 'Markdown';
|
|
889
|
+
/** Disable notification sound */
|
|
890
|
+
disableNotification?: boolean;
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Telegram Bridge for PocketPing.
|
|
894
|
+
* Sends visitor messages to a Telegram chat using the Bot API.
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* ```ts
|
|
898
|
+
* const telegram = new TelegramBridge(
|
|
899
|
+
* 'BOT_TOKEN',
|
|
900
|
+
* '-1001234567890',
|
|
901
|
+
* { parseMode: 'HTML' }
|
|
902
|
+
* );
|
|
903
|
+
* const pocketping = new PocketPing({ bridges: [telegram] });
|
|
904
|
+
* ```
|
|
905
|
+
*/
|
|
906
|
+
declare class TelegramBridge implements Bridge {
|
|
907
|
+
readonly name = "telegram";
|
|
908
|
+
private pocketping?;
|
|
909
|
+
private readonly botToken;
|
|
910
|
+
private readonly chatId;
|
|
911
|
+
private readonly parseMode;
|
|
912
|
+
private readonly disableNotification;
|
|
913
|
+
private readonly baseUrl;
|
|
914
|
+
constructor(botToken: string, chatId: string | number, options?: TelegramBridgeOptions);
|
|
915
|
+
/**
|
|
916
|
+
* Initialize the bridge (optional setup)
|
|
917
|
+
*/
|
|
918
|
+
init(pocketping: PocketPing): Promise<void>;
|
|
919
|
+
/**
|
|
920
|
+
* Called when a new chat session is created
|
|
921
|
+
*/
|
|
922
|
+
onNewSession(session: Session): Promise<void>;
|
|
923
|
+
/**
|
|
924
|
+
* Called when a visitor sends a message.
|
|
925
|
+
* Returns the Telegram message ID for edit/delete sync.
|
|
926
|
+
*/
|
|
927
|
+
onVisitorMessage(message: Message, session: Session): Promise<BridgeMessageResult>;
|
|
928
|
+
/**
|
|
929
|
+
* Called when an operator sends a message (for cross-bridge sync)
|
|
930
|
+
*/
|
|
931
|
+
onOperatorMessage(message: Message, _session: Session, sourceBridge?: string, operatorName?: string): Promise<void>;
|
|
932
|
+
/**
|
|
933
|
+
* Called when visitor starts/stops typing
|
|
934
|
+
*/
|
|
935
|
+
onTyping(_sessionId: string, isTyping: boolean): Promise<void>;
|
|
936
|
+
/**
|
|
937
|
+
* Called when a visitor edits their message.
|
|
938
|
+
* @returns true if edit succeeded, false otherwise
|
|
939
|
+
*/
|
|
940
|
+
onMessageEdit(_messageId: string, newContent: string, bridgeMessageId: string | number): Promise<boolean>;
|
|
941
|
+
/**
|
|
942
|
+
* Called when a visitor deletes their message.
|
|
943
|
+
* @returns true if delete succeeded, false otherwise
|
|
944
|
+
*/
|
|
945
|
+
onMessageDelete(_messageId: string, bridgeMessageId: string | number): Promise<boolean>;
|
|
946
|
+
/**
|
|
947
|
+
* Called when a custom event is triggered from the widget
|
|
948
|
+
*/
|
|
949
|
+
onCustomEvent(event: {
|
|
950
|
+
name: string;
|
|
951
|
+
data?: Record<string, unknown>;
|
|
952
|
+
}, session: Session): Promise<void>;
|
|
953
|
+
/**
|
|
954
|
+
* Called when a user identifies themselves via PocketPing.identify()
|
|
955
|
+
*/
|
|
956
|
+
onIdentityUpdate(session: Session): Promise<void>;
|
|
957
|
+
/**
|
|
958
|
+
* Send a message to the Telegram chat
|
|
959
|
+
*/
|
|
960
|
+
private sendMessage;
|
|
961
|
+
/**
|
|
962
|
+
* Send a chat action (e.g., "typing")
|
|
963
|
+
*/
|
|
964
|
+
private sendChatAction;
|
|
965
|
+
/**
|
|
966
|
+
* Format new session notification
|
|
967
|
+
*/
|
|
968
|
+
private formatNewSession;
|
|
969
|
+
/**
|
|
970
|
+
* Format visitor message
|
|
971
|
+
*/
|
|
972
|
+
private formatVisitorMessage;
|
|
973
|
+
/**
|
|
974
|
+
* Escape HTML special characters
|
|
975
|
+
*/
|
|
976
|
+
private escapeHtml;
|
|
977
|
+
/**
|
|
978
|
+
* Escape Markdown special characters
|
|
979
|
+
*/
|
|
980
|
+
private escapeMarkdown;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* In-memory storage adapter.
|
|
985
|
+
* Useful for development and testing. Data is lost on restart.
|
|
986
|
+
*/
|
|
987
|
+
declare class MemoryStorage implements Storage {
|
|
988
|
+
private sessions;
|
|
989
|
+
private messages;
|
|
990
|
+
private messageById;
|
|
991
|
+
private bridgeMessageIds;
|
|
992
|
+
createSession(session: Session): Promise<void>;
|
|
993
|
+
getSession(sessionId: string): Promise<Session | null>;
|
|
994
|
+
getSessionByVisitorId(visitorId: string): Promise<Session | null>;
|
|
995
|
+
updateSession(session: Session): Promise<void>;
|
|
996
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
997
|
+
saveMessage(message: Message): Promise<void>;
|
|
998
|
+
getMessages(sessionId: string, after?: string, limit?: number): Promise<Message[]>;
|
|
999
|
+
getMessage(messageId: string): Promise<Message | null>;
|
|
1000
|
+
updateMessage(message: Message): Promise<void>;
|
|
1001
|
+
saveBridgeMessageIds(messageId: string, bridgeIds: BridgeMessageIds): Promise<void>;
|
|
1002
|
+
getBridgeMessageIds(messageId: string): Promise<BridgeMessageIds | null>;
|
|
1003
|
+
cleanupOldSessions(olderThan: Date): Promise<number>;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/** Attachment from an operator message */
|
|
1007
|
+
interface OperatorAttachment {
|
|
1008
|
+
filename: string;
|
|
1009
|
+
mimeType: string;
|
|
1010
|
+
size: number;
|
|
1011
|
+
data: Buffer;
|
|
1012
|
+
bridgeFileId?: string;
|
|
1013
|
+
}
|
|
1014
|
+
/** Callback when operator sends a message from a bridge */
|
|
1015
|
+
type OperatorMessageCallback = (sessionId: string, content: string, operatorName: string, sourceBridge: 'telegram' | 'discord' | 'slack', attachments: OperatorAttachment[], replyToBridgeMessageId?: number | null, bridgeMessageId?: number | string | null) => void | Promise<void>;
|
|
1016
|
+
type OperatorMessageEditCallback = (sessionId: string, bridgeMessageId: number | string, content: string, sourceBridge: 'telegram' | 'discord' | 'slack', editedAt?: string) => void | Promise<void>;
|
|
1017
|
+
type OperatorMessageDeleteCallback = (sessionId: string, bridgeMessageId: number | string, sourceBridge: 'telegram' | 'discord' | 'slack', deletedAt?: string) => void | Promise<void>;
|
|
1018
|
+
/** Webhook handler configuration */
|
|
1019
|
+
interface WebhookConfig {
|
|
1020
|
+
telegramBotToken?: string;
|
|
1021
|
+
slackBotToken?: string;
|
|
1022
|
+
discordBotToken?: string;
|
|
1023
|
+
allowedBotIds?: string[];
|
|
1024
|
+
onOperatorMessage: OperatorMessageCallback;
|
|
1025
|
+
onOperatorMessageEdit?: OperatorMessageEditCallback;
|
|
1026
|
+
onOperatorMessageDelete?: OperatorMessageDeleteCallback;
|
|
1027
|
+
}
|
|
1028
|
+
declare class WebhookHandler {
|
|
1029
|
+
private config;
|
|
1030
|
+
constructor(config: WebhookConfig);
|
|
1031
|
+
/**
|
|
1032
|
+
* Create an Express/Connect middleware for handling Telegram webhooks
|
|
1033
|
+
*/
|
|
1034
|
+
handleTelegramWebhook(): (req: IncomingMessage & {
|
|
1035
|
+
body?: unknown;
|
|
1036
|
+
}, res: ServerResponse) => Promise<void>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Create an Express/Connect middleware for handling Slack webhooks
|
|
1039
|
+
*/
|
|
1040
|
+
handleSlackWebhook(): (req: IncomingMessage & {
|
|
1041
|
+
body?: unknown;
|
|
1042
|
+
}, res: ServerResponse) => Promise<void>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Create an Express/Connect middleware for handling Discord webhooks
|
|
1045
|
+
*/
|
|
1046
|
+
handleDiscordWebhook(): (req: IncomingMessage & {
|
|
1047
|
+
body?: unknown;
|
|
1048
|
+
}, res: ServerResponse) => Promise<void>;
|
|
1049
|
+
private parseBody;
|
|
1050
|
+
private writeOK;
|
|
1051
|
+
private downloadTelegramFile;
|
|
1052
|
+
private downloadSlackFile;
|
|
1053
|
+
private getSlackUserName;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
export { type AIProvider, type Bridge, type BridgeMessageIds, type BridgeMessageResult, type ConnectRequest, type ConnectResponse, type CustomEvent, type CustomEventHandler, DEFAULT_BOT_PATTERNS, type DeleteMessageRequest, type DeleteMessageResponse, type DiscordBotOptions, DiscordBridge, type DiscordWebhookOptions, type EditMessageRequest, type EditMessageResponse, type IpFilterConfig, type IpFilterLogEvent, type IpFilterMode, MemoryStorage, type Message, type OperatorAttachment, type OperatorMessageCallback, type OperatorMessageDeleteCallback, type OperatorMessageEditCallback, PocketPing, type PocketPingConfig, type PresenceResponse, type SendMessageRequest, type SendMessageResponse, type Session, type SlackBotOptions, SlackBridge, type SlackWebhookOptions, type Storage, TelegramBridge, type TelegramBridgeOptions, type TrackedElement, type TriggerOptions, type UaFilterConfig, type UaFilterLogEvent, type UaFilterMode, type UaFilterReason, type UaFilterResult, type WebhookConfig, WebhookHandler, type WebhookPayload, checkIpFilter, checkUaFilter, ipMatchesAny, ipMatchesCidr, isBot, matchesAnyPattern };
|