@pocketping/sdk-node 1.8.0 → 1.9.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.cjs +58 -0
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +58 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1897,6 +1897,12 @@ var PocketPing = class {
|
|
|
1897
1897
|
case "delete":
|
|
1898
1898
|
result = await this.handleDeleteMessage(body);
|
|
1899
1899
|
break;
|
|
1900
|
+
case "disconnect":
|
|
1901
|
+
result = await this.handleDisconnect(body);
|
|
1902
|
+
break;
|
|
1903
|
+
case "visibility":
|
|
1904
|
+
result = await this.handleVisibility(body);
|
|
1905
|
+
break;
|
|
1900
1906
|
default:
|
|
1901
1907
|
if (next) {
|
|
1902
1908
|
next();
|
|
@@ -2217,6 +2223,58 @@ var PocketPing = class {
|
|
|
2217
2223
|
this.forwardIdentityToWebhook(session);
|
|
2218
2224
|
return { ok: true };
|
|
2219
2225
|
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Handle visitor disconnect (page unload or inactivity)
|
|
2228
|
+
* Notifies bridges and triggers callback
|
|
2229
|
+
*/
|
|
2230
|
+
async handleDisconnect(request) {
|
|
2231
|
+
const session = await this.storage.getSession(request.sessionId);
|
|
2232
|
+
if (!session) {
|
|
2233
|
+
throw new Error("Session not found");
|
|
2234
|
+
}
|
|
2235
|
+
const formatDuration = (seconds) => {
|
|
2236
|
+
if (seconds < 60) return `${seconds}s`;
|
|
2237
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)} min`;
|
|
2238
|
+
const hours = Math.floor(seconds / 3600);
|
|
2239
|
+
const mins = Math.floor(seconds % 3600 / 60);
|
|
2240
|
+
return mins > 0 ? `${hours}h ${mins}min` : `${hours}h`;
|
|
2241
|
+
};
|
|
2242
|
+
const visitorName = session.identity?.name || session.identity?.email?.split("@")[0] || "Visitor";
|
|
2243
|
+
const durationText = formatDuration(request.duration);
|
|
2244
|
+
const message = `\u{1F44B} ${visitorName} left (was here for ${durationText})`;
|
|
2245
|
+
await this.notifyBridgesDisconnect(session, message);
|
|
2246
|
+
await this.config.onVisitorDisconnect?.(session, request.duration);
|
|
2247
|
+
return { ok: true };
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Handle visibility change (tab focus/blur)
|
|
2251
|
+
* Used for inactivity tracking
|
|
2252
|
+
*/
|
|
2253
|
+
async handleVisibility(request) {
|
|
2254
|
+
const session = await this.storage.getSession(request.sessionId);
|
|
2255
|
+
if (!session) {
|
|
2256
|
+
throw new Error("Session not found");
|
|
2257
|
+
}
|
|
2258
|
+
if (request.state === "visible") {
|
|
2259
|
+
session.lastActivity = /* @__PURE__ */ new Date();
|
|
2260
|
+
await this.storage.updateSession(session);
|
|
2261
|
+
}
|
|
2262
|
+
return { ok: true };
|
|
2263
|
+
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Notify all bridges when visitor disconnects
|
|
2266
|
+
*/
|
|
2267
|
+
async notifyBridgesDisconnect(session, message) {
|
|
2268
|
+
for (const bridge of this.bridges) {
|
|
2269
|
+
try {
|
|
2270
|
+
if ("notifyDisconnect" in bridge && typeof bridge.notifyDisconnect === "function") {
|
|
2271
|
+
await bridge.notifyDisconnect(session, message);
|
|
2272
|
+
}
|
|
2273
|
+
} catch (error) {
|
|
2274
|
+
console.error(`[PocketPing] Bridge disconnect notification failed:`, error);
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2220
2278
|
/**
|
|
2221
2279
|
* Get a session by ID
|
|
2222
2280
|
*/
|
package/dist/index.d.cts
CHANGED
|
@@ -63,6 +63,20 @@ declare class PocketPing {
|
|
|
63
63
|
* Called when visitor calls PocketPing.identify()
|
|
64
64
|
*/
|
|
65
65
|
handleIdentify(request: IdentifyRequest): Promise<IdentifyResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Handle visitor disconnect (page unload or inactivity)
|
|
68
|
+
* Notifies bridges and triggers callback
|
|
69
|
+
*/
|
|
70
|
+
handleDisconnect(request: DisconnectRequest): Promise<DisconnectResponse>;
|
|
71
|
+
/**
|
|
72
|
+
* Handle visibility change (tab focus/blur)
|
|
73
|
+
* Used for inactivity tracking
|
|
74
|
+
*/
|
|
75
|
+
handleVisibility(request: VisibilityRequest): Promise<VisibilityResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Notify all bridges when visitor disconnects
|
|
78
|
+
*/
|
|
79
|
+
private notifyBridgesDisconnect;
|
|
66
80
|
/**
|
|
67
81
|
* Get a session by ID
|
|
68
82
|
*/
|
|
@@ -384,6 +398,8 @@ interface PocketPingConfig {
|
|
|
384
398
|
welcomeMessage?: string;
|
|
385
399
|
/** Seconds of inactivity before AI takes over (default: 300) */
|
|
386
400
|
aiTakeoverDelay?: number;
|
|
401
|
+
/** Seconds of visitor inactivity before notifying bridges (0 = disabled) */
|
|
402
|
+
visitorInactivityTimeout?: number;
|
|
387
403
|
/** Callback when a new session is created */
|
|
388
404
|
onNewSession?: (session: Session) => void | Promise<void>;
|
|
389
405
|
/** Callback when a message is received */
|
|
@@ -392,6 +408,8 @@ interface PocketPingConfig {
|
|
|
392
408
|
onEvent?: (event: CustomEvent, session: Session) => void | Promise<void>;
|
|
393
409
|
/** Callback when a user identifies themselves */
|
|
394
410
|
onIdentify?: (session: Session) => void | Promise<void>;
|
|
411
|
+
/** Callback when a visitor disconnects (leaves the page or goes inactive) */
|
|
412
|
+
onVisitorDisconnect?: (session: Session, duration: number) => void | Promise<void>;
|
|
395
413
|
/** Webhook URL to forward custom events (Zapier, Make, n8n, etc.) */
|
|
396
414
|
webhookUrl?: string;
|
|
397
415
|
/** Secret key for HMAC-SHA256 signature (X-PocketPing-Signature header) */
|
|
@@ -602,6 +620,22 @@ interface IdentifyRequest {
|
|
|
602
620
|
interface IdentifyResponse {
|
|
603
621
|
ok: boolean;
|
|
604
622
|
}
|
|
623
|
+
interface DisconnectRequest {
|
|
624
|
+
sessionId: string;
|
|
625
|
+
duration: number;
|
|
626
|
+
reason: 'page_unload' | 'inactivity' | 'manual';
|
|
627
|
+
}
|
|
628
|
+
interface DisconnectResponse {
|
|
629
|
+
ok: boolean;
|
|
630
|
+
}
|
|
631
|
+
interface VisibilityRequest {
|
|
632
|
+
sessionId: string;
|
|
633
|
+
state: 'hidden' | 'visible';
|
|
634
|
+
timestamp: number;
|
|
635
|
+
}
|
|
636
|
+
interface VisibilityResponse {
|
|
637
|
+
ok: boolean;
|
|
638
|
+
}
|
|
605
639
|
interface PresenceResponse {
|
|
606
640
|
online: boolean;
|
|
607
641
|
operators?: Array<{
|
|
@@ -1065,4 +1099,4 @@ declare class WebhookHandler {
|
|
|
1065
1099
|
private getSlackUserName;
|
|
1066
1100
|
}
|
|
1067
1101
|
|
|
1068
|
-
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 };
|
|
1102
|
+
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 DisconnectRequest, type DisconnectResponse, 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 VisibilityRequest, type VisibilityResponse, type WebhookConfig, WebhookHandler, type WebhookPayload, checkIpFilter, checkUaFilter, ipMatchesAny, ipMatchesCidr, isBot, matchesAnyPattern };
|
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,20 @@ declare class PocketPing {
|
|
|
63
63
|
* Called when visitor calls PocketPing.identify()
|
|
64
64
|
*/
|
|
65
65
|
handleIdentify(request: IdentifyRequest): Promise<IdentifyResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Handle visitor disconnect (page unload or inactivity)
|
|
68
|
+
* Notifies bridges and triggers callback
|
|
69
|
+
*/
|
|
70
|
+
handleDisconnect(request: DisconnectRequest): Promise<DisconnectResponse>;
|
|
71
|
+
/**
|
|
72
|
+
* Handle visibility change (tab focus/blur)
|
|
73
|
+
* Used for inactivity tracking
|
|
74
|
+
*/
|
|
75
|
+
handleVisibility(request: VisibilityRequest): Promise<VisibilityResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Notify all bridges when visitor disconnects
|
|
78
|
+
*/
|
|
79
|
+
private notifyBridgesDisconnect;
|
|
66
80
|
/**
|
|
67
81
|
* Get a session by ID
|
|
68
82
|
*/
|
|
@@ -384,6 +398,8 @@ interface PocketPingConfig {
|
|
|
384
398
|
welcomeMessage?: string;
|
|
385
399
|
/** Seconds of inactivity before AI takes over (default: 300) */
|
|
386
400
|
aiTakeoverDelay?: number;
|
|
401
|
+
/** Seconds of visitor inactivity before notifying bridges (0 = disabled) */
|
|
402
|
+
visitorInactivityTimeout?: number;
|
|
387
403
|
/** Callback when a new session is created */
|
|
388
404
|
onNewSession?: (session: Session) => void | Promise<void>;
|
|
389
405
|
/** Callback when a message is received */
|
|
@@ -392,6 +408,8 @@ interface PocketPingConfig {
|
|
|
392
408
|
onEvent?: (event: CustomEvent, session: Session) => void | Promise<void>;
|
|
393
409
|
/** Callback when a user identifies themselves */
|
|
394
410
|
onIdentify?: (session: Session) => void | Promise<void>;
|
|
411
|
+
/** Callback when a visitor disconnects (leaves the page or goes inactive) */
|
|
412
|
+
onVisitorDisconnect?: (session: Session, duration: number) => void | Promise<void>;
|
|
395
413
|
/** Webhook URL to forward custom events (Zapier, Make, n8n, etc.) */
|
|
396
414
|
webhookUrl?: string;
|
|
397
415
|
/** Secret key for HMAC-SHA256 signature (X-PocketPing-Signature header) */
|
|
@@ -602,6 +620,22 @@ interface IdentifyRequest {
|
|
|
602
620
|
interface IdentifyResponse {
|
|
603
621
|
ok: boolean;
|
|
604
622
|
}
|
|
623
|
+
interface DisconnectRequest {
|
|
624
|
+
sessionId: string;
|
|
625
|
+
duration: number;
|
|
626
|
+
reason: 'page_unload' | 'inactivity' | 'manual';
|
|
627
|
+
}
|
|
628
|
+
interface DisconnectResponse {
|
|
629
|
+
ok: boolean;
|
|
630
|
+
}
|
|
631
|
+
interface VisibilityRequest {
|
|
632
|
+
sessionId: string;
|
|
633
|
+
state: 'hidden' | 'visible';
|
|
634
|
+
timestamp: number;
|
|
635
|
+
}
|
|
636
|
+
interface VisibilityResponse {
|
|
637
|
+
ok: boolean;
|
|
638
|
+
}
|
|
605
639
|
interface PresenceResponse {
|
|
606
640
|
online: boolean;
|
|
607
641
|
operators?: Array<{
|
|
@@ -1065,4 +1099,4 @@ declare class WebhookHandler {
|
|
|
1065
1099
|
private getSlackUserName;
|
|
1066
1100
|
}
|
|
1067
1101
|
|
|
1068
|
-
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 };
|
|
1102
|
+
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 DisconnectRequest, type DisconnectResponse, 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 VisibilityRequest, type VisibilityResponse, type WebhookConfig, WebhookHandler, type WebhookPayload, checkIpFilter, checkUaFilter, ipMatchesAny, ipMatchesCidr, isBot, matchesAnyPattern };
|
package/dist/index.js
CHANGED
|
@@ -1859,6 +1859,12 @@ var PocketPing = class {
|
|
|
1859
1859
|
case "delete":
|
|
1860
1860
|
result = await this.handleDeleteMessage(body);
|
|
1861
1861
|
break;
|
|
1862
|
+
case "disconnect":
|
|
1863
|
+
result = await this.handleDisconnect(body);
|
|
1864
|
+
break;
|
|
1865
|
+
case "visibility":
|
|
1866
|
+
result = await this.handleVisibility(body);
|
|
1867
|
+
break;
|
|
1862
1868
|
default:
|
|
1863
1869
|
if (next) {
|
|
1864
1870
|
next();
|
|
@@ -2179,6 +2185,58 @@ var PocketPing = class {
|
|
|
2179
2185
|
this.forwardIdentityToWebhook(session);
|
|
2180
2186
|
return { ok: true };
|
|
2181
2187
|
}
|
|
2188
|
+
/**
|
|
2189
|
+
* Handle visitor disconnect (page unload or inactivity)
|
|
2190
|
+
* Notifies bridges and triggers callback
|
|
2191
|
+
*/
|
|
2192
|
+
async handleDisconnect(request) {
|
|
2193
|
+
const session = await this.storage.getSession(request.sessionId);
|
|
2194
|
+
if (!session) {
|
|
2195
|
+
throw new Error("Session not found");
|
|
2196
|
+
}
|
|
2197
|
+
const formatDuration = (seconds) => {
|
|
2198
|
+
if (seconds < 60) return `${seconds}s`;
|
|
2199
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)} min`;
|
|
2200
|
+
const hours = Math.floor(seconds / 3600);
|
|
2201
|
+
const mins = Math.floor(seconds % 3600 / 60);
|
|
2202
|
+
return mins > 0 ? `${hours}h ${mins}min` : `${hours}h`;
|
|
2203
|
+
};
|
|
2204
|
+
const visitorName = session.identity?.name || session.identity?.email?.split("@")[0] || "Visitor";
|
|
2205
|
+
const durationText = formatDuration(request.duration);
|
|
2206
|
+
const message = `\u{1F44B} ${visitorName} left (was here for ${durationText})`;
|
|
2207
|
+
await this.notifyBridgesDisconnect(session, message);
|
|
2208
|
+
await this.config.onVisitorDisconnect?.(session, request.duration);
|
|
2209
|
+
return { ok: true };
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Handle visibility change (tab focus/blur)
|
|
2213
|
+
* Used for inactivity tracking
|
|
2214
|
+
*/
|
|
2215
|
+
async handleVisibility(request) {
|
|
2216
|
+
const session = await this.storage.getSession(request.sessionId);
|
|
2217
|
+
if (!session) {
|
|
2218
|
+
throw new Error("Session not found");
|
|
2219
|
+
}
|
|
2220
|
+
if (request.state === "visible") {
|
|
2221
|
+
session.lastActivity = /* @__PURE__ */ new Date();
|
|
2222
|
+
await this.storage.updateSession(session);
|
|
2223
|
+
}
|
|
2224
|
+
return { ok: true };
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Notify all bridges when visitor disconnects
|
|
2228
|
+
*/
|
|
2229
|
+
async notifyBridgesDisconnect(session, message) {
|
|
2230
|
+
for (const bridge of this.bridges) {
|
|
2231
|
+
try {
|
|
2232
|
+
if ("notifyDisconnect" in bridge && typeof bridge.notifyDisconnect === "function") {
|
|
2233
|
+
await bridge.notifyDisconnect(session, message);
|
|
2234
|
+
}
|
|
2235
|
+
} catch (error) {
|
|
2236
|
+
console.error(`[PocketPing] Bridge disconnect notification failed:`, error);
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2182
2240
|
/**
|
|
2183
2241
|
* Get a session by ID
|
|
2184
2242
|
*/
|