fb-messenger-e2ee 0.1.1 → 0.1.3

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.
Files changed (111) hide show
  1. package/DOCS.md +41 -3
  2. package/README.md +27 -2
  3. package/dist/index.cjs +9017 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +910 -0
  6. package/dist/index.d.ts +910 -0
  7. package/dist/index.js +9049 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +19 -4
  10. package/bun.lock +0 -1014
  11. package/examples/basic-usage.ts +0 -52
  12. package/jest.config.ts +0 -18
  13. package/src/config/env.ts +0 -15
  14. package/src/controllers/client.controller.ts +0 -805
  15. package/src/controllers/dgw-handler.ts +0 -171
  16. package/src/controllers/e2ee-handler.ts +0 -832
  17. package/src/controllers/event-mapper.ts +0 -327
  18. package/src/core/client.ts +0 -151
  19. package/src/e2ee/application/e2ee-client.ts +0 -376
  20. package/src/e2ee/application/fanout-planner.ts +0 -79
  21. package/src/e2ee/application/outbound-message-cache.ts +0 -58
  22. package/src/e2ee/application/prekey-maintenance.ts +0 -55
  23. package/src/e2ee/application/retry-manager.ts +0 -156
  24. package/src/e2ee/facebook/facebook-protocol-utils.ts +0 -230
  25. package/src/e2ee/facebook/icdc-payload.ts +0 -31
  26. package/src/e2ee/index.ts +0 -76
  27. package/src/e2ee/internal.ts +0 -27
  28. package/src/e2ee/media/media-crypto.ts +0 -147
  29. package/src/e2ee/media/media-upload.ts +0 -90
  30. package/src/e2ee/message/builders/client-payload.ts +0 -54
  31. package/src/e2ee/message/builders/consumer-application.ts +0 -362
  32. package/src/e2ee/message/builders/message-application.ts +0 -64
  33. package/src/e2ee/message/builders/message-transport.ts +0 -84
  34. package/src/e2ee/message/codecs/protobuf-codecs.ts +0 -101
  35. package/src/e2ee/message/constants.ts +0 -4
  36. package/src/e2ee/message/message-builder.ts +0 -15
  37. package/src/e2ee/signal/prekey-manager.ts +0 -140
  38. package/src/e2ee/signal/signal-manager.ts +0 -365
  39. package/src/e2ee/store/device-json.ts +0 -47
  40. package/src/e2ee/store/device-repository.ts +0 -12
  41. package/src/e2ee/store/device-store.ts +0 -538
  42. package/src/e2ee/transport/binary/decoder.ts +0 -180
  43. package/src/e2ee/transport/binary/encoder.ts +0 -143
  44. package/src/e2ee/transport/binary/stanzas.ts +0 -97
  45. package/src/e2ee/transport/binary/tokens.ts +0 -64
  46. package/src/e2ee/transport/binary/wa-binary.ts +0 -8
  47. package/src/e2ee/transport/dgw/dgw-socket.ts +0 -345
  48. package/src/e2ee/transport/noise/noise-handshake.ts +0 -417
  49. package/src/e2ee/transport/noise/noise-socket.ts +0 -230
  50. package/src/index.ts +0 -34
  51. package/src/models/client.ts +0 -26
  52. package/src/models/config.ts +0 -14
  53. package/src/models/domain.ts +0 -299
  54. package/src/models/e2ee.ts +0 -295
  55. package/src/models/media.ts +0 -41
  56. package/src/models/messaging.ts +0 -88
  57. package/src/models/thread.ts +0 -69
  58. package/src/repositories/session.repository.ts +0 -20
  59. package/src/services/auth.service.ts +0 -55
  60. package/src/services/e2ee.service.ts +0 -174
  61. package/src/services/facebook-gateway.service.ts +0 -245
  62. package/src/services/icdc.service.ts +0 -177
  63. package/src/services/media.service.ts +0 -304
  64. package/src/services/messaging.service.ts +0 -28
  65. package/src/services/thread.service.ts +0 -199
  66. package/src/types/advanced-types.ts +0 -61
  67. package/src/types/fca-unofficial.d.ts +0 -212
  68. package/src/types/protocol-types.ts +0 -43
  69. package/src/utils/fca-utils.ts +0 -30
  70. package/src/utils/logger.ts +0 -24
  71. package/src/utils/mime.ts +0 -51
  72. package/tests/.env.example +0 -87
  73. package/tests/data/1x1.png +0 -0
  74. package/tests/data/example.txt +0 -1
  75. package/tests/data/file_example.mp3 +0 -0
  76. package/tests/data/file_example.mp4 +0 -0
  77. package/tests/integration.test.ts +0 -498
  78. package/tests/script/echo-e2ee.ts +0 -174
  79. package/tests/script/send-e2ee-media.ts +0 -227
  80. package/tests/script/send-e2ee-reaction.ts +0 -108
  81. package/tests/script/send-e2ee-unsend.ts +0 -115
  82. package/tests/script/send-typing.ts +0 -107
  83. package/tests/script/test-group-send.ts +0 -105
  84. package/tests/setup.ts +0 -3
  85. package/tests/types.test.ts +0 -57
  86. package/tests/unit/controllers/dgw-handler.test.ts +0 -60
  87. package/tests/unit/controllers/e2ee-handler.test.ts +0 -293
  88. package/tests/unit/controllers/event-mapper.test.ts +0 -252
  89. package/tests/unit/e2ee/application-helpers.test.ts +0 -418
  90. package/tests/unit/e2ee/device-store.test.ts +0 -126
  91. package/tests/unit/e2ee/facebook-protocol-utils.test.ts +0 -134
  92. package/tests/unit/e2ee/media-crypto.test.ts +0 -55
  93. package/tests/unit/e2ee/media-upload.test.ts +0 -60
  94. package/tests/unit/e2ee/message-builder.test.ts +0 -42
  95. package/tests/unit/e2ee/message-builders.test.ts +0 -230
  96. package/tests/unit/e2ee/noise-handshake.test.ts +0 -260
  97. package/tests/unit/e2ee/prekey-manager.test.ts +0 -55
  98. package/tests/unit/e2ee/wa-binary.test.ts +0 -127
  99. package/tests/unit/services/e2ee.service.test.ts +0 -101
  100. package/tests/unit/services/facebook-gateway.service.test.ts +0 -138
  101. package/tests/unit/services/media.service.test.ts +0 -169
  102. package/tests/unit/utils/fca-utils.test.ts +0 -48
  103. package/tsconfig.json +0 -19
  104. /package/{src/e2ee/message/proto → proto}/ArmadilloApplication.proto +0 -0
  105. /package/{src/e2ee/message/proto → proto}/ArmadilloICDC.proto +0 -0
  106. /package/{src/e2ee/message/proto → proto}/ConsumerApplication.proto +0 -0
  107. /package/{src/e2ee/message/proto → proto}/MessageApplication.proto +0 -0
  108. /package/{src/e2ee/message/proto → proto}/MessageTransport.proto +0 -0
  109. /package/{src/e2ee/message/proto → proto}/WACommon.proto +0 -0
  110. /package/{src/e2ee/message/proto → proto}/WAMediaTransport.proto +0 -0
  111. /package/{src/e2ee/message/proto → proto}/proto-writer.ts +0 -0
@@ -1,327 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import type { MessengerEvent, MessengerMessage, Attachment, E2EEMessage, E2EEMessageKind } from "../models/domain.ts";
3
- import { str, num, now } from "../utils/fca-utils.ts";
4
- import type { MediaService } from "../services/media.service.ts";
5
- import type { E2EEService } from "../services/e2ee.service.ts";
6
-
7
- export class EventMapper {
8
- constructor(
9
- private readonly eventBus: EventEmitter,
10
- private readonly mediaService: MediaService,
11
- private readonly e2eeService: E2EEService
12
- ) {}
13
-
14
- public emitMappedEvent(rawEvent: Record<string, unknown>): void {
15
- const type = str(rawEvent.type);
16
-
17
- // Standard LightSpeed messages
18
- if (type === "message" || type === "message_reply") {
19
- const msg: MessengerMessage = {
20
- id: str(rawEvent.messageID),
21
- threadId: str(rawEvent.threadID),
22
- senderId: str(rawEvent.senderID),
23
- text: str(rawEvent.body),
24
- timestampMs: num(rawEvent.timestamp) || now(),
25
- attachments: this.mapAttachments(rawEvent.attachments),
26
- mentions: this.mapMentions(rawEvent),
27
- };
28
-
29
- const reply = rawEvent.messageReply as Record<string, unknown> | undefined;
30
- if (reply?.messageID) {
31
- msg.replyTo = {
32
- messageId: str(reply.messageID),
33
- senderId: str(reply.senderID),
34
- text: str(reply.body),
35
- };
36
- }
37
-
38
- this.emit({ type: "message", data: msg });
39
- return;
40
- }
41
-
42
- // Message edit
43
- if (type === "message_edit" || type === "messageEdit") {
44
- this.emit({
45
- type: "messageEdit",
46
- data: {
47
- messageId: str(rawEvent.messageID),
48
- threadId: str(rawEvent.threadID),
49
- newText: str(rawEvent.newText ?? rawEvent.text ?? rawEvent.body),
50
- editCount: num(rawEvent.editCount),
51
- timestampMs: num(rawEvent.timestamp) || now(),
52
- },
53
- });
54
- return;
55
- }
56
-
57
- // Reactions
58
- if (type === "message_reaction" || type === "reaction") {
59
- this.emit({
60
- type: "reaction",
61
- data: {
62
- messageId: str(rawEvent.messageID),
63
- threadId: str(rawEvent.threadID),
64
- actorId: str(rawEvent.userID ?? rawEvent.senderID),
65
- reaction: str(rawEvent.reaction),
66
- timestampMs: num(rawEvent.timestamp) || now(),
67
- },
68
- });
69
- return;
70
- }
71
-
72
- // Typing
73
- if (type === "typ") {
74
- this.emit({
75
- type: "typing",
76
- data: {
77
- threadId: str(rawEvent.threadID),
78
- senderId: str(rawEvent.from ?? rawEvent.senderID),
79
- isTyping: Boolean(rawEvent.isTyping),
80
- },
81
- });
82
- return;
83
- }
84
-
85
- // Unsend
86
- if (type === "message_unsend") {
87
- this.emit({
88
- type: "message_unsend",
89
- data: {
90
- messageId: str(rawEvent.messageID),
91
- threadId: str(rawEvent.threadID),
92
- actorId: str(rawEvent.senderID),
93
- timestampMs: num(rawEvent.timestamp) || now(),
94
- },
95
- });
96
- return;
97
- }
98
-
99
- // Read receipt
100
- if (type === "read_receipt") {
101
- this.emit({
102
- type: "read_receipt",
103
- data: {
104
- threadId: str(rawEvent.threadID),
105
- readerId: str(rawEvent.reader ?? rawEvent.readerID),
106
- readWatermarkTimestampMs: num(rawEvent.readWatermarkTimestampMs),
107
- timestampMs: num(rawEvent.time ?? rawEvent.timestamp) || now(),
108
- },
109
- });
110
- return;
111
- }
112
-
113
- // Presence
114
- if (type === "presence") {
115
- this.emit({
116
- type: "presence",
117
- data: {
118
- userId: str(rawEvent.userID),
119
- isOnline: Boolean(rawEvent.userStatus ?? rawEvent.isOnline),
120
- lastActiveTimestampMs: num(rawEvent.timestamp),
121
- },
122
- });
123
- return;
124
- }
125
-
126
- // Handshake events
127
- if (type === "disconnected") {
128
- this.emit({ type: "disconnected", data: { isE2EE: Boolean(rawEvent.isE2EE) } });
129
- return;
130
- }
131
- if (type === "reconnected") {
132
- this.emit({ type: "reconnected", data: {} });
133
- return;
134
- }
135
- if (type === "ready") {
136
- this.emit({ type: "ready", data: { isNewSession: Boolean(rawEvent.isNewSession) } });
137
- return;
138
- }
139
-
140
- // E2EE specific
141
- if (type === "e2ee_connected" || type === "e2eeConnected") {
142
- this.e2eeService.markConnected();
143
- this.emit({ type: "e2ee_connected", data: {} });
144
- return;
145
- }
146
- if (type === "e2ee_message" || type === "e2eeMessage") {
147
- const e2eeData = rawEvent.data as any;
148
- if (!e2eeData) return;
149
-
150
- const rawChatJid = str(e2eeData.chatJid || e2eeData.threadId);
151
- const senderInfo = this.parseMessengerJid(str(e2eeData.senderJid));
152
- const senderId = str(e2eeData.senderId) || senderInfo.user || senderInfo.rawUser || senderInfo.jid;
153
- const senderJid = this.canonicalMessengerDeviceJid(str(e2eeData.senderJid), senderId, senderInfo.device);
154
- const chat = this.normalizeE2EEChat(rawChatJid || senderJid);
155
-
156
- if (e2eeData.type === "decryption_failed") {
157
- this.emit({
158
- type: "error",
159
- data: {
160
- message: `E2EE decrypt failed${chat.chatJid ? ` in ${chat.chatJid}` : ""}${senderJid ? ` from ${senderJid}` : ""}: ${str(e2eeData.error)}`,
161
- },
162
- });
163
- return;
164
- }
165
-
166
- const kind = this.normalizeE2EEKind(e2eeData.kind || e2eeData.type, e2eeData);
167
- const data: Record<string, unknown> = {
168
- id: str(e2eeData.messageId || e2eeData.messageID),
169
- threadId: chat.threadId,
170
- chatJid: chat.chatJid,
171
- senderJid,
172
- senderId,
173
- isGroup: chat.isGroup,
174
- kind,
175
- text: str(e2eeData.text || e2eeData.body || ""),
176
- timestampMs: num(e2eeData.timestampMs || e2eeData.timestamp) || now(),
177
- };
178
-
179
- if (senderInfo.device > 0) data.senderDeviceId = senderInfo.device;
180
- if (Array.isArray(e2eeData.attachments) && e2eeData.attachments.length > 0) data.attachments = e2eeData.attachments;
181
- if (Array.isArray(e2eeData.mentions) && e2eeData.mentions.length > 0) data.mentions = e2eeData.mentions;
182
- if (e2eeData.media) data.media = e2eeData.media;
183
- if (e2eeData.raw) data.raw = e2eeData.raw;
184
- if (e2eeData.emoji || e2eeData.reaction) data.reaction = str(e2eeData.emoji || e2eeData.reaction);
185
- if (e2eeData.targetId) data.targetId = str(e2eeData.targetId);
186
- if (typeof e2eeData.fromMe === "boolean") data.fromMe = e2eeData.fromMe;
187
-
188
- if (e2eeData.replyToId) {
189
- const replySender = this.parseMessengerJid(str(e2eeData.replyToSenderJid));
190
- data.replyTo = {
191
- messageId: str(e2eeData.replyToId),
192
- senderId: replySender.user || str(e2eeData.replyToSenderJid),
193
- };
194
- }
195
-
196
- this.emit({
197
- type: "e2ee_message",
198
- data: data as unknown as E2EEMessage,
199
- });
200
- return;
201
- }
202
- if (type === "e2ee_reaction" || type === "e2eeReaction") {
203
- const d = rawEvent.data as Record<string, unknown> | undefined ?? rawEvent;
204
- this.emit({
205
- type: "e2ee_reaction",
206
- data: {
207
- messageId: str(d.messageId),
208
- chatJid: str(d.chatJid),
209
- senderJid: str(d.senderJid),
210
- senderId: str(d.senderId),
211
- reaction: str(d.reaction),
212
- },
213
- });
214
- return;
215
- }
216
- if (type === "e2ee_receipt" || type === "e2eeReceipt") {
217
- const d = rawEvent.data as Record<string, unknown> | undefined ?? rawEvent;
218
- this.emit({
219
- type: "e2ee_receipt",
220
- data: {
221
- type: str(d.type),
222
- chat: str(d.chat),
223
- sender: str(d.sender),
224
- messageIds: Array.isArray(d.messageIds) ? (d.messageIds as unknown[]).map(str) : [],
225
- },
226
- });
227
- return;
228
- }
229
-
230
- // Raw fallback
231
- this.emit({ type: "raw", data: rawEvent });
232
- }
233
-
234
- private normalizeE2EEKind(value: unknown, data: Record<string, unknown>): E2EEMessageKind {
235
- const kind = str(value);
236
- if (this.isE2EEMessageKind(kind)) return kind;
237
- if (data.media && typeof data.media === "object" && data.media !== null) {
238
- const mediaType = str((data.media as Record<string, unknown>).type);
239
- if (this.isE2EEMessageKind(mediaType)) return mediaType;
240
- }
241
- if (str(data.text || data.body)) return "text";
242
- return "unknown";
243
- }
244
-
245
- private isE2EEMessageKind(value: string): value is E2EEMessageKind {
246
- return ["text", "image", "video", "audio", "document", "sticker", "reaction", "edit", "revoke", "unknown"].includes(value);
247
- }
248
-
249
- private normalizeE2EEChat(jid: string): { threadId: string; chatJid: string; isGroup: boolean } {
250
- if (!jid) return { threadId: "", chatJid: "", isGroup: false };
251
- if (this.isGroupJid(jid)) return { threadId: jid, chatJid: jid, isGroup: true };
252
-
253
- const parsed = this.parseMessengerJid(jid);
254
- if (parsed.server === "msgr" && parsed.user) {
255
- return {
256
- threadId: parsed.user,
257
- chatJid: `${parsed.user}.0@msgr`,
258
- isGroup: false,
259
- };
260
- }
261
-
262
- if (/^\d+$/.test(jid)) {
263
- return { threadId: jid, chatJid: `${jid}.0@msgr`, isGroup: false };
264
- }
265
-
266
- return { threadId: jid, chatJid: jid, isGroup: false };
267
- }
268
-
269
- private isGroupJid(jid: string): boolean {
270
- return jid.endsWith("@g.us") || jid.includes(".g.");
271
- }
272
-
273
- private canonicalMessengerDeviceJid(jid: string, fallbackUser: string, fallbackDevice = 0): string {
274
- const parsed = this.parseMessengerJid(jid);
275
- if (parsed.server === "msgr" && parsed.user) return `${parsed.user}.${parsed.device}@msgr`;
276
- if (!jid && fallbackUser) return `${fallbackUser}.${fallbackDevice}@msgr`;
277
- return jid;
278
- }
279
-
280
- private parseMessengerJid(jid: string): { jid: string; rawUser: string; user: string; device: number; server: string } {
281
- const [userPart = jid, server = ""] = jid.split("@");
282
- const colonIdx = userPart.indexOf(":");
283
- const dotIdx = userPart.indexOf(".");
284
- const userEnd = dotIdx !== -1 ? dotIdx : (colonIdx !== -1 ? colonIdx : userPart.length);
285
- const user = userPart.slice(0, userEnd) || userPart;
286
- const rawDevice = colonIdx !== -1
287
- ? userPart.slice(colonIdx + 1)
288
- : (dotIdx !== -1 ? userPart.slice(dotIdx + 1) : "0");
289
- return { jid, rawUser: userPart, user, device: Number(rawDevice) || 0, server };
290
- }
291
-
292
- public emit(event: MessengerEvent): void {
293
- // Node's EventEmitter treats "error" specially: emitting it without a
294
- // typed error listener throws ERR_UNHANDLED_ERROR and can kill long-running
295
- // listeners such as tests/script/echo-e2ee.ts. We still always emit the
296
- // catch-all "event" below, so client.onEvent(listener) receives the error.
297
- if (event.type !== "error" || this.eventBus.listenerCount("error") > 0) {
298
- this.eventBus.emit(event.type as any, event.data);
299
- }
300
- this.eventBus.emit("event", event);
301
- }
302
-
303
- private mapAttachments(raw: unknown): Attachment[] | undefined {
304
- if (!Array.isArray(raw) || raw.length === 0) return undefined;
305
- const mapped = (raw as unknown[])
306
- .map(item => this.mediaService.normalizeAttachment(item))
307
- .filter((item): item is Attachment => item !== null);
308
- return mapped.length > 0 ? mapped : undefined;
309
- }
310
-
311
- private mapMentions(rawEvent: Record<string, unknown>) {
312
- const mentions = rawEvent.mentions;
313
- if (!Array.isArray(mentions) || mentions.length === 0) return undefined;
314
- return (mentions as unknown[]).flatMap(m => {
315
- if (typeof m !== "object" || m === null) return [];
316
- const item = m as Record<string, unknown>;
317
- return [
318
- {
319
- userId: str(item.id ?? item.userId),
320
- offset: num(item.fromIndex ?? item.offset),
321
- length: num(item.length),
322
- type: str(item.type) || "user",
323
- },
324
- ];
325
- });
326
- }
327
- }
@@ -1,151 +0,0 @@
1
- import type { MessengerEvent } from "../models/domain.ts";
2
- import type {
3
- SendMediaInput,
4
- SendMessageInput,
5
- SendReactionInput,
6
- TypingInput,
7
- } from "../models/messaging.ts";
8
- import type { ClientOptions, MessengerEventMap } from "../models/client.ts";
9
- import { TypedEventEmitter } from "../types/advanced-types.ts";
10
- import { ClientController } from "../controllers/client.controller.ts";
11
- import { FileSessionRepository } from "../repositories/session.repository.ts";
12
- import { AuthService } from "../services/auth.service.ts";
13
- import { E2EEService } from "../services/e2ee.service.ts";
14
- import { FacebookGatewayService } from "../services/facebook-gateway.service.ts";
15
- import { MediaService } from "../services/media.service.ts";
16
- import { ICDCService } from "../services/icdc.service.ts";
17
-
18
- /**
19
- * E2EE-only Messenger client facade.
20
- *
21
- * `fca-unofficial` is still used internally for app-state login and CAT/bootstrap
22
- * material that the E2EE transport currently requires, but plaintext/non-E2EE
23
- * messaging, thread management, polls, stickers, and history APIs are intentionally
24
- * not exposed here. Use `fca-unofficial` directly for those non-E2EE surfaces.
25
- */
26
- export class FBClient {
27
- private readonly eventBus = new TypedEventEmitter<MessengerEventMap>();
28
- private readonly controller: ClientController;
29
-
30
- public constructor(private readonly options: ClientOptions) {
31
- const sessionRepository = new FileSessionRepository();
32
- const authService = new AuthService(sessionRepository);
33
- const gateway = new FacebookGatewayService();
34
- const mediaService = new MediaService(gateway);
35
- const e2eeService = new E2EEService();
36
-
37
- const icdcService = new ICDCService(
38
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
39
- );
40
- this.controller = new ClientController(
41
- authService,
42
- gateway,
43
- mediaService,
44
- e2eeService,
45
- icdcService,
46
- this.eventBus as any,
47
- );
48
- }
49
-
50
- // Events
51
-
52
- /** Listen for events. Supports catch-all or specific event types. */
53
- public onEvent(listener: (event: MessengerEvent) => void): void;
54
- public onEvent<K extends keyof MessengerEventMap>(
55
- event: K,
56
- listener: (data: MessengerEventMap[K]) => void,
57
- ): void;
58
- public onEvent(arg1: any, arg2?: any): void {
59
- if (typeof arg1 === "function") {
60
- this.eventBus.on("event", arg1);
61
- } else {
62
- this.eventBus.on(arg1, arg2);
63
- }
64
- }
65
-
66
- /** Stop listening for events. */
67
- public offEvent(listener: (event: MessengerEvent) => void): void;
68
- public offEvent<K extends keyof MessengerEventMap>(
69
- event: K,
70
- listener: (data: MessengerEventMap[K]) => void,
71
- ): void;
72
- public offEvent(arg1: any, arg2?: any): void {
73
- if (typeof arg1 === "function") {
74
- this.eventBus.off("event", arg1);
75
- } else {
76
- this.eventBus.off(arg1, arg2);
77
- }
78
- }
79
-
80
- /** Legacy helper for the catch-all wrapper event. */
81
- public onAnyEvent(listener: (event: MessengerEvent) => void): void {
82
- (this.eventBus as any).on("event", listener);
83
- }
84
-
85
- // Lifecycle
86
-
87
- /**
88
- * Login with appState and prepare auth/CAT bootstrap state.
89
- * This does not start plaintext/non-E2EE MQTT listening.
90
- */
91
- public async connect(): Promise<{ userId: string }> {
92
- return this.controller.connect(
93
- {
94
- appStatePath: this.options.appStatePath,
95
- appState: this.options.appState,
96
- platform: this.options.platform ?? "facebook",
97
- },
98
- this.options.sessionStorePath,
99
- );
100
- }
101
-
102
- public async disconnect(): Promise<void> {
103
- await this.controller.disconnect();
104
- }
105
-
106
- // E2EE lifecycle
107
-
108
- public async connectE2EE(deviceStorePath: string, userId: string): Promise<void> {
109
- await this.controller.connectE2EE(deviceStorePath, userId);
110
- }
111
-
112
- public async sendNoiseKeepAlive(): Promise<void> {
113
- await this.controller.sendNoiseKeepAlive();
114
- }
115
-
116
- // E2EE messaging
117
-
118
- public async sendMessage(input: SendMessageInput): Promise<Record<string, unknown>> {
119
- return this.controller.sendMessage(input);
120
- }
121
-
122
- public async sendReaction(input: SendReactionInput): Promise<void> {
123
- await this.controller.sendReaction(input);
124
- }
125
-
126
- public async unsendMessage(messageId: string, threadId?: string): Promise<void> {
127
- await this.controller.unsendMessage(messageId, threadId);
128
- }
129
-
130
- public async sendTyping(input: TypingInput): Promise<void> {
131
- await this.controller.sendTyping(input);
132
- }
133
-
134
- // E2EE media send
135
-
136
- public async sendImage(input: SendMediaInput): Promise<Record<string, unknown>> {
137
- return this.controller.sendImage(input);
138
- }
139
-
140
- public async sendVideo(input: SendMediaInput): Promise<Record<string, unknown>> {
141
- return this.controller.sendVideo(input);
142
- }
143
-
144
- public async sendAudio(input: SendMediaInput): Promise<Record<string, unknown>> {
145
- return this.controller.sendAudio(input);
146
- }
147
-
148
- public async sendFile(input: SendMediaInput): Promise<Record<string, unknown>> {
149
- return this.controller.sendFile(input);
150
- }
151
- }