@pocketping/sdk-node 1.2.0 → 1.4.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.cts CHANGED
@@ -1,5 +1,14 @@
1
1
  import { IncomingMessage, ServerResponse } from 'http';
2
2
 
3
+ /**
4
+ * Bridge message IDs for edit/delete sync.
5
+ * Stored when a message is sent to bridges.
6
+ */
7
+ interface BridgeMessageIds {
8
+ telegramMessageId?: number;
9
+ discordMessageId?: string;
10
+ slackMessageTs?: string;
11
+ }
3
12
  /**
4
13
  * Storage adapter interface.
5
14
  * Implement this interface to use any database with PocketPing.
@@ -13,9 +22,23 @@ interface Storage {
13
22
  saveMessage(message: Message): Promise<void>;
14
23
  getMessages(sessionId: string, after?: string, limit?: number): Promise<Message[]>;
15
24
  getMessage(messageId: string): Promise<Message | null>;
25
+ /** Update an existing message (for edit/delete) */
26
+ updateMessage?(message: Message): Promise<void>;
27
+ /** Save bridge message IDs for a message */
28
+ saveBridgeMessageIds?(messageId: string, bridgeIds: BridgeMessageIds): Promise<void>;
29
+ /** Get bridge message IDs for a message */
30
+ getBridgeMessageIds?(messageId: string): Promise<BridgeMessageIds | null>;
16
31
  cleanupOldSessions?(olderThan: Date): Promise<number>;
17
32
  }
18
33
 
34
+ /**
35
+ * Result from sending a message to a bridge.
36
+ * Contains the bridge-specific message ID for later edit/delete.
37
+ */
38
+ interface BridgeMessageResult {
39
+ /** Bridge-specific message ID */
40
+ messageId?: string | number;
41
+ }
19
42
  /**
20
43
  * Bridge interface for notification channels.
21
44
  * Implement this interface to add support for Telegram, Discord, Slack, etc.
@@ -27,14 +50,32 @@ interface Bridge {
27
50
  init?(pocketping: PocketPing): void | Promise<void>;
28
51
  /** Called when a new chat session is created */
29
52
  onNewSession?(session: Session): void | Promise<void>;
30
- /** Called when a visitor sends a message */
31
- onVisitorMessage?(message: Message, session: Session): void | Promise<void>;
53
+ /**
54
+ * Called when a visitor sends a message.
55
+ * Return the bridge message ID for edit/delete sync.
56
+ */
57
+ onVisitorMessage?(message: Message, session: Session): void | BridgeMessageResult | Promise<void | BridgeMessageResult>;
32
58
  /** Called when an operator sends a message (for cross-bridge sync) */
33
59
  onOperatorMessage?(message: Message, session: Session, sourceBridge?: string, operatorName?: string): void | Promise<void>;
34
60
  /** Called when visitor starts/stops typing */
35
61
  onTyping?(sessionId: string, isTyping: boolean): void | Promise<void>;
36
62
  /** Called when messages are marked as delivered/read */
37
63
  onMessageRead?(sessionId: string, messageIds: string[], status: MessageStatus, session: Session): void | Promise<void>;
64
+ /**
65
+ * Called when a visitor edits their message.
66
+ * @param messageId - The message ID in PocketPing
67
+ * @param newContent - The new message content
68
+ * @param bridgeMessageId - The bridge-specific message ID
69
+ * @returns true if edit succeeded, false otherwise
70
+ */
71
+ onMessageEdit?(messageId: string, newContent: string, bridgeMessageId: string | number): boolean | Promise<boolean>;
72
+ /**
73
+ * Called when a visitor deletes their message.
74
+ * @param messageId - The message ID in PocketPing
75
+ * @param bridgeMessageId - The bridge-specific message ID
76
+ * @returns true if delete succeeded, false otherwise
77
+ */
78
+ onMessageDelete?(messageId: string, bridgeMessageId: string | number): boolean | Promise<boolean>;
38
79
  /** Called when a custom event is triggered from the widget */
39
80
  onCustomEvent?(event: CustomEvent, session: Session): void | Promise<void>;
40
81
  /** Called when a user identifies themselves via PocketPing.identify() */
@@ -184,6 +225,29 @@ interface SessionMetadata {
184
225
  [key: string]: unknown;
185
226
  }
186
227
  type MessageStatus = 'sending' | 'sent' | 'delivered' | 'read';
228
+ type AttachmentStatus = 'pending' | 'uploading' | 'ready' | 'failed';
229
+ type UploadSource = 'widget' | 'telegram' | 'discord' | 'slack' | 'api';
230
+ /** File attachment in a message */
231
+ interface Attachment {
232
+ /** Unique attachment ID */
233
+ id: string;
234
+ /** Original filename */
235
+ filename: string;
236
+ /** MIME type (e.g., 'image/jpeg', 'application/pdf') */
237
+ mimeType: string;
238
+ /** File size in bytes */
239
+ size: number;
240
+ /** URL to access the file */
241
+ url: string;
242
+ /** Thumbnail URL (for images/videos) */
243
+ thumbnailUrl?: string;
244
+ /** Upload status */
245
+ status: AttachmentStatus;
246
+ /** Source of the upload */
247
+ uploadedFrom?: UploadSource;
248
+ /** External file ID (from Telegram/Discord/Slack) */
249
+ bridgeFileId?: string;
250
+ }
187
251
  interface Message {
188
252
  id: string;
189
253
  sessionId: string;
@@ -192,9 +256,38 @@ interface Message {
192
256
  timestamp: Date;
193
257
  replyTo?: string;
194
258
  metadata?: Record<string, unknown>;
259
+ /** File attachments in this message */
260
+ attachments?: Attachment[];
195
261
  status?: MessageStatus;
196
262
  deliveredAt?: Date;
197
263
  readAt?: Date;
264
+ /** Timestamp when message was edited */
265
+ editedAt?: Date;
266
+ /** Timestamp when message was soft-deleted */
267
+ deletedAt?: Date;
268
+ }
269
+ /** Request to edit a message */
270
+ interface EditMessageRequest {
271
+ sessionId: string;
272
+ messageId: string;
273
+ content: string;
274
+ }
275
+ /** Response after editing a message */
276
+ interface EditMessageResponse {
277
+ message: {
278
+ id: string;
279
+ content: string;
280
+ editedAt: string;
281
+ };
282
+ }
283
+ /** Request to delete a message */
284
+ interface DeleteMessageRequest {
285
+ sessionId: string;
286
+ messageId: string;
287
+ }
288
+ /** Response after deleting a message */
289
+ interface DeleteMessageResponse {
290
+ deleted: boolean;
198
291
  }
199
292
  interface ConnectRequest {
200
293
  visitorId: string;
@@ -235,6 +328,10 @@ interface SendMessageRequest {
235
328
  content: string;
236
329
  sender: 'visitor' | 'operator';
237
330
  replyTo?: string;
331
+ /** Attachment IDs to include with the message */
332
+ attachmentIds?: string[];
333
+ /** Inline attachments (for operator messages from bridges) */
334
+ attachments?: Attachment[];
238
335
  }
239
336
  interface SendMessageResponse {
240
337
  messageId: string;
@@ -351,6 +448,16 @@ declare class PocketPing {
351
448
  * Get a session by ID
352
449
  */
353
450
  getSession(sessionId: string): Promise<Session | null>;
451
+ /**
452
+ * Handle message edit from widget
453
+ * Only the message sender can edit their own messages
454
+ */
455
+ handleEditMessage(request: EditMessageRequest): Promise<EditMessageResponse>;
456
+ /**
457
+ * Handle message delete from widget
458
+ * Only the message sender can delete their own messages
459
+ */
460
+ handleDeleteMessage(request: DeleteMessageRequest): Promise<DeleteMessageResponse>;
354
461
  sendOperatorMessage(sessionId: string, content: string): Promise<Message>;
355
462
  setOperatorOnline(online: boolean): void;
356
463
  /**
@@ -419,6 +526,14 @@ declare class PocketPing {
419
526
  private notifyBridgesRead;
420
527
  private notifyBridgesEvent;
421
528
  private notifyBridgesIdentity;
529
+ /**
530
+ * Sync message edit to all bridges that support it
531
+ */
532
+ private syncEditToBridges;
533
+ /**
534
+ * Sync message delete to all bridges that support it
535
+ */
536
+ private syncDeleteToBridges;
422
537
  /**
423
538
  * Forward custom event to configured webhook URL (non-blocking)
424
539
  * Used for integrations with Zapier, Make, n8n, or custom backends
@@ -455,6 +570,7 @@ declare class MemoryStorage implements Storage {
455
570
  private sessions;
456
571
  private messages;
457
572
  private messageById;
573
+ private bridgeMessageIds;
458
574
  createSession(session: Session): Promise<void>;
459
575
  getSession(sessionId: string): Promise<Session | null>;
460
576
  getSessionByVisitorId(visitorId: string): Promise<Session | null>;
@@ -463,7 +579,379 @@ declare class MemoryStorage implements Storage {
463
579
  saveMessage(message: Message): Promise<void>;
464
580
  getMessages(sessionId: string, after?: string, limit?: number): Promise<Message[]>;
465
581
  getMessage(messageId: string): Promise<Message | null>;
582
+ updateMessage(message: Message): Promise<void>;
583
+ saveBridgeMessageIds(messageId: string, bridgeIds: BridgeMessageIds): Promise<void>;
584
+ getBridgeMessageIds(messageId: string): Promise<BridgeMessageIds | null>;
466
585
  cleanupOldSessions(olderThan: Date): Promise<number>;
467
586
  }
468
587
 
469
- 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 };
588
+ /** Attachment from an operator message */
589
+ interface OperatorAttachment {
590
+ filename: string;
591
+ mimeType: string;
592
+ size: number;
593
+ data: Buffer;
594
+ bridgeFileId?: string;
595
+ }
596
+ /** Callback when operator sends a message from a bridge */
597
+ type OperatorMessageCallback = (sessionId: string, content: string, operatorName: string, sourceBridge: 'telegram' | 'discord' | 'slack', attachments: OperatorAttachment[], replyToBridgeMessageId?: number | null, bridgeMessageId?: number | string | null) => void | Promise<void>;
598
+ type OperatorMessageEditCallback = (sessionId: string, bridgeMessageId: number | string, content: string, sourceBridge: 'telegram' | 'discord' | 'slack', editedAt?: string) => void | Promise<void>;
599
+ type OperatorMessageDeleteCallback = (sessionId: string, bridgeMessageId: number | string, sourceBridge: 'telegram' | 'discord' | 'slack', deletedAt?: string) => void | Promise<void>;
600
+ /** Webhook handler configuration */
601
+ interface WebhookConfig {
602
+ telegramBotToken?: string;
603
+ slackBotToken?: string;
604
+ discordBotToken?: string;
605
+ allowedBotIds?: string[];
606
+ onOperatorMessage: OperatorMessageCallback;
607
+ onOperatorMessageEdit?: OperatorMessageEditCallback;
608
+ onOperatorMessageDelete?: OperatorMessageDeleteCallback;
609
+ }
610
+ declare class WebhookHandler {
611
+ private config;
612
+ constructor(config: WebhookConfig);
613
+ /**
614
+ * Create an Express/Connect middleware for handling Telegram webhooks
615
+ */
616
+ handleTelegramWebhook(): (req: IncomingMessage & {
617
+ body?: unknown;
618
+ }, res: ServerResponse) => Promise<void>;
619
+ /**
620
+ * Create an Express/Connect middleware for handling Slack webhooks
621
+ */
622
+ handleSlackWebhook(): (req: IncomingMessage & {
623
+ body?: unknown;
624
+ }, res: ServerResponse) => Promise<void>;
625
+ /**
626
+ * Create an Express/Connect middleware for handling Discord webhooks
627
+ */
628
+ handleDiscordWebhook(): (req: IncomingMessage & {
629
+ body?: unknown;
630
+ }, res: ServerResponse) => Promise<void>;
631
+ private parseBody;
632
+ private writeOK;
633
+ private downloadTelegramFile;
634
+ private downloadSlackFile;
635
+ private getSlackUserName;
636
+ }
637
+
638
+ /**
639
+ * Options for TelegramBridge
640
+ */
641
+ interface TelegramBridgeOptions {
642
+ /** Parse mode for message formatting */
643
+ parseMode?: 'HTML' | 'Markdown';
644
+ /** Disable notification sound */
645
+ disableNotification?: boolean;
646
+ }
647
+ /**
648
+ * Telegram Bridge for PocketPing.
649
+ * Sends visitor messages to a Telegram chat using the Bot API.
650
+ *
651
+ * @example
652
+ * ```ts
653
+ * const telegram = new TelegramBridge(
654
+ * 'BOT_TOKEN',
655
+ * '-1001234567890',
656
+ * { parseMode: 'HTML' }
657
+ * );
658
+ * const pocketping = new PocketPing({ bridges: [telegram] });
659
+ * ```
660
+ */
661
+ declare class TelegramBridge implements Bridge {
662
+ readonly name = "telegram";
663
+ private pocketping?;
664
+ private readonly botToken;
665
+ private readonly chatId;
666
+ private readonly parseMode;
667
+ private readonly disableNotification;
668
+ private readonly baseUrl;
669
+ constructor(botToken: string, chatId: string | number, options?: TelegramBridgeOptions);
670
+ /**
671
+ * Initialize the bridge (optional setup)
672
+ */
673
+ init(pocketping: PocketPing): Promise<void>;
674
+ /**
675
+ * Called when a new chat session is created
676
+ */
677
+ onNewSession(session: Session): Promise<void>;
678
+ /**
679
+ * Called when a visitor sends a message.
680
+ * Returns the Telegram message ID for edit/delete sync.
681
+ */
682
+ onVisitorMessage(message: Message, session: Session): Promise<BridgeMessageResult>;
683
+ /**
684
+ * Called when an operator sends a message (for cross-bridge sync)
685
+ */
686
+ onOperatorMessage(message: Message, _session: Session, sourceBridge?: string, operatorName?: string): Promise<void>;
687
+ /**
688
+ * Called when visitor starts/stops typing
689
+ */
690
+ onTyping(sessionId: string, isTyping: boolean): Promise<void>;
691
+ /**
692
+ * Called when a visitor edits their message.
693
+ * @returns true if edit succeeded, false otherwise
694
+ */
695
+ onMessageEdit(_messageId: string, newContent: string, bridgeMessageId: string | number): Promise<boolean>;
696
+ /**
697
+ * Called when a visitor deletes their message.
698
+ * @returns true if delete succeeded, false otherwise
699
+ */
700
+ onMessageDelete(_messageId: string, bridgeMessageId: string | number): Promise<boolean>;
701
+ /**
702
+ * Called when a custom event is triggered from the widget
703
+ */
704
+ onCustomEvent(event: {
705
+ name: string;
706
+ data?: Record<string, unknown>;
707
+ }, session: Session): Promise<void>;
708
+ /**
709
+ * Called when a user identifies themselves via PocketPing.identify()
710
+ */
711
+ onIdentityUpdate(session: Session): Promise<void>;
712
+ /**
713
+ * Send a message to the Telegram chat
714
+ */
715
+ private sendMessage;
716
+ /**
717
+ * Send a chat action (e.g., "typing")
718
+ */
719
+ private sendChatAction;
720
+ /**
721
+ * Format new session notification
722
+ */
723
+ private formatNewSession;
724
+ /**
725
+ * Format visitor message
726
+ */
727
+ private formatVisitorMessage;
728
+ /**
729
+ * Escape HTML special characters
730
+ */
731
+ private escapeHtml;
732
+ /**
733
+ * Escape Markdown special characters
734
+ */
735
+ private escapeMarkdown;
736
+ }
737
+
738
+ /**
739
+ * Options for Discord webhook mode
740
+ */
741
+ interface DiscordWebhookOptions {
742
+ /** Custom username for webhook messages */
743
+ username?: string;
744
+ /** Custom avatar URL for webhook messages */
745
+ avatarUrl?: string;
746
+ }
747
+ /**
748
+ * Options for Discord bot mode
749
+ */
750
+ interface DiscordBotOptions {
751
+ /** Custom username displayed in embeds */
752
+ username?: string;
753
+ /** Custom avatar URL for embeds */
754
+ avatarUrl?: string;
755
+ }
756
+ /**
757
+ * Discord Bridge for PocketPing.
758
+ * Sends visitor messages to a Discord channel using webhooks or bot API.
759
+ *
760
+ * @example Webhook mode
761
+ * ```ts
762
+ * const discord = DiscordBridge.webhook(
763
+ * 'https://discord.com/api/webhooks/123/abc',
764
+ * { username: 'PocketPing' }
765
+ * );
766
+ * ```
767
+ *
768
+ * @example Bot mode
769
+ * ```ts
770
+ * const discord = DiscordBridge.bot(
771
+ * 'BOT_TOKEN',
772
+ * 'CHANNEL_ID',
773
+ * { username: 'PocketPing' }
774
+ * );
775
+ * ```
776
+ */
777
+ declare class DiscordBridge implements Bridge {
778
+ readonly name = "discord";
779
+ private pocketping?;
780
+ private readonly mode;
781
+ private readonly webhookUrl?;
782
+ private readonly botToken?;
783
+ private readonly channelId?;
784
+ private readonly username?;
785
+ private readonly avatarUrl?;
786
+ private constructor();
787
+ /**
788
+ * Create a Discord bridge using a webhook URL
789
+ */
790
+ static webhook(webhookUrl: string, options?: DiscordWebhookOptions): DiscordBridge;
791
+ /**
792
+ * Create a Discord bridge using a bot token
793
+ */
794
+ static bot(botToken: string, channelId: string, options?: DiscordBotOptions): DiscordBridge;
795
+ /**
796
+ * Initialize the bridge (optional setup)
797
+ */
798
+ init(pocketping: PocketPing): Promise<void>;
799
+ /**
800
+ * Called when a new chat session is created
801
+ */
802
+ onNewSession(session: Session): Promise<void>;
803
+ /**
804
+ * Called when a visitor sends a message.
805
+ * Returns the Discord message ID for edit/delete sync.
806
+ */
807
+ onVisitorMessage(message: Message, session: Session): Promise<BridgeMessageResult>;
808
+ /**
809
+ * Called when an operator sends a message (for cross-bridge sync)
810
+ */
811
+ onOperatorMessage(message: Message, _session: Session, sourceBridge?: string, operatorName?: string): Promise<void>;
812
+ /**
813
+ * Called when visitor starts/stops typing
814
+ */
815
+ onTyping(_sessionId: string, isTyping: boolean): Promise<void>;
816
+ /**
817
+ * Called when a visitor edits their message.
818
+ * @returns true if edit succeeded, false otherwise
819
+ */
820
+ onMessageEdit(_messageId: string, newContent: string, bridgeMessageId: string | number): Promise<boolean>;
821
+ /**
822
+ * Called when a visitor deletes their message.
823
+ * @returns true if delete succeeded, false otherwise
824
+ */
825
+ onMessageDelete(_messageId: string, bridgeMessageId: string | number): Promise<boolean>;
826
+ /**
827
+ * Called when a custom event is triggered from the widget
828
+ */
829
+ onCustomEvent(event: {
830
+ name: string;
831
+ data?: Record<string, unknown>;
832
+ }, session: Session): Promise<void>;
833
+ /**
834
+ * Called when a user identifies themselves via PocketPing.identify()
835
+ */
836
+ onIdentityUpdate(session: Session): Promise<void>;
837
+ /**
838
+ * Send an embed to Discord
839
+ */
840
+ private sendEmbed;
841
+ }
842
+
843
+ /**
844
+ * Options for Slack webhook mode
845
+ */
846
+ interface SlackWebhookOptions {
847
+ /** Custom username for webhook messages */
848
+ username?: string;
849
+ /** Custom emoji icon (e.g., ':robot_face:') */
850
+ iconEmoji?: string;
851
+ /** Custom icon URL (overrides iconEmoji) */
852
+ iconUrl?: string;
853
+ }
854
+ /**
855
+ * Options for Slack bot mode
856
+ */
857
+ interface SlackBotOptions {
858
+ /** Custom username for bot messages */
859
+ username?: string;
860
+ /** Custom emoji icon (e.g., ':robot_face:') */
861
+ iconEmoji?: string;
862
+ /** Custom icon URL (overrides iconEmoji) */
863
+ iconUrl?: string;
864
+ }
865
+ /**
866
+ * Slack Bridge for PocketPing.
867
+ * Sends visitor messages to a Slack channel using webhooks or bot API.
868
+ *
869
+ * @example Webhook mode
870
+ * ```ts
871
+ * const slack = SlackBridge.webhook(
872
+ * 'https://hooks.slack.com/services/T.../B.../xxx',
873
+ * { username: 'PocketPing', iconEmoji: ':speech_balloon:' }
874
+ * );
875
+ * ```
876
+ *
877
+ * @example Bot mode
878
+ * ```ts
879
+ * const slack = SlackBridge.bot(
880
+ * 'xoxb-YOUR-BOT-TOKEN',
881
+ * 'C1234567890',
882
+ * { username: 'PocketPing' }
883
+ * );
884
+ * ```
885
+ */
886
+ declare class SlackBridge implements Bridge {
887
+ readonly name = "slack";
888
+ private pocketping?;
889
+ private readonly mode;
890
+ private readonly webhookUrl?;
891
+ private readonly botToken?;
892
+ private readonly channelId?;
893
+ private readonly username?;
894
+ private readonly iconEmoji?;
895
+ private readonly iconUrl?;
896
+ private constructor();
897
+ /**
898
+ * Create a Slack bridge using a webhook URL
899
+ */
900
+ static webhook(webhookUrl: string, options?: SlackWebhookOptions): SlackBridge;
901
+ /**
902
+ * Create a Slack bridge using a bot token
903
+ */
904
+ static bot(botToken: string, channelId: string, options?: SlackBotOptions): SlackBridge;
905
+ /**
906
+ * Initialize the bridge (optional setup)
907
+ */
908
+ init(pocketping: PocketPing): Promise<void>;
909
+ /**
910
+ * Called when a new chat session is created
911
+ */
912
+ onNewSession(session: Session): Promise<void>;
913
+ /**
914
+ * Called when a visitor sends a message.
915
+ * Returns the Slack message timestamp for edit/delete sync.
916
+ */
917
+ onVisitorMessage(message: Message, session: Session): Promise<BridgeMessageResult>;
918
+ /**
919
+ * Called when an operator sends a message (for cross-bridge sync)
920
+ */
921
+ onOperatorMessage(message: Message, _session: Session, sourceBridge?: string, operatorName?: string): Promise<void>;
922
+ /**
923
+ * Called when visitor starts/stops typing
924
+ */
925
+ onTyping(_sessionId: string, _isTyping: boolean): Promise<void>;
926
+ /**
927
+ * Called when a visitor edits their message.
928
+ * @returns true if edit succeeded, false otherwise
929
+ */
930
+ onMessageEdit(_messageId: string, newContent: string, bridgeMessageId: string | number): Promise<boolean>;
931
+ /**
932
+ * Called when a visitor deletes their message.
933
+ * @returns true if delete succeeded, false otherwise
934
+ */
935
+ onMessageDelete(_messageId: string, bridgeMessageId: string | number): Promise<boolean>;
936
+ /**
937
+ * Called when a custom event is triggered from the widget
938
+ */
939
+ onCustomEvent(event: {
940
+ name: string;
941
+ data?: Record<string, unknown>;
942
+ }, session: Session): Promise<void>;
943
+ /**
944
+ * Called when a user identifies themselves via PocketPing.identify()
945
+ */
946
+ onIdentityUpdate(session: Session): Promise<void>;
947
+ /**
948
+ * Send blocks to Slack
949
+ */
950
+ private sendBlocks;
951
+ /**
952
+ * Escape special characters for Slack mrkdwn
953
+ */
954
+ private escapeSlack;
955
+ }
956
+
957
+ export { type AIProvider, type Bridge, type BridgeMessageIds, type BridgeMessageResult, type ConnectRequest, type ConnectResponse, type CustomEvent, type CustomEventHandler, type DeleteMessageRequest, type DeleteMessageResponse, type DiscordBotOptions, DiscordBridge, type DiscordWebhookOptions, type EditMessageRequest, type EditMessageResponse, 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 WebhookConfig, WebhookHandler, type WebhookPayload };