@theophilusdev/conduit 1.1.3 → 1.2.5
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 +135 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -12
- package/dist/index.d.ts +50 -12
- package/dist/index.mjs +135 -45
- package/dist/index.mjs.map +1 -1
- package/docs/DOCS.md +11 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -48,36 +48,42 @@ var ConduitError = class _ConduitError extends Error {
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
// src/utils/sleep.ts
|
|
52
|
+
function sleep(min, max) {
|
|
53
|
+
const delay = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
setTimeout(resolve, delay);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
// src/api/ConduitMessagesAPI.ts
|
|
52
60
|
var ConduitMessagesAPI = class {
|
|
53
|
-
constructor(bot) {
|
|
61
|
+
constructor(bot, queue) {
|
|
54
62
|
this.bot = bot;
|
|
63
|
+
this.queue = queue;
|
|
55
64
|
}
|
|
56
65
|
bot;
|
|
66
|
+
queue;
|
|
57
67
|
/**
|
|
58
68
|
* Sends a message to a thread.
|
|
59
69
|
* @param body - The message text.
|
|
60
70
|
* @param threadID - The target thread ID.
|
|
61
71
|
*/
|
|
62
72
|
send(body, threadID) {
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
const fn = () => new Promise(async (resolve, reject) => {
|
|
74
|
+
await this.bot.ctx.api.sendTypingIndicator(threadID);
|
|
75
|
+
setTimeout(() => {
|
|
65
76
|
this.bot.ctx.api.sendMessage(
|
|
66
|
-
{ body },
|
|
77
|
+
typeof body === "string" ? { body } : body,
|
|
67
78
|
threadID,
|
|
68
79
|
(err, data) => {
|
|
69
80
|
if (err) reject(err);
|
|
70
81
|
else resolve(data);
|
|
71
82
|
}
|
|
72
83
|
);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
return new Promise((resolve, reject) => {
|
|
76
|
-
this.bot.ctx.api.sendMessage(body, threadID, (err, data) => {
|
|
77
|
-
if (err) reject(err);
|
|
78
|
-
else resolve(data);
|
|
79
|
-
});
|
|
84
|
+
}, 700);
|
|
80
85
|
});
|
|
86
|
+
return this.queue ? this.queue.enqueue(threadID, fn) : fn();
|
|
81
87
|
}
|
|
82
88
|
/**
|
|
83
89
|
* Sends a quoted reply to a specific message.
|
|
@@ -86,10 +92,11 @@ var ConduitMessagesAPI = class {
|
|
|
86
92
|
* @param messageID - The message ID to reply to.
|
|
87
93
|
*/
|
|
88
94
|
reply(body, threadID, messageID) {
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
const fn = () => new Promise(async (resolve, reject) => {
|
|
96
|
+
await this.bot.ctx.api.sendTypingIndicator(threadID);
|
|
97
|
+
setTimeout(() => {
|
|
91
98
|
this.bot.ctx.api.sendMessage(
|
|
92
|
-
{ body },
|
|
99
|
+
typeof body === "string" ? { body } : body,
|
|
93
100
|
threadID,
|
|
94
101
|
(err, data) => {
|
|
95
102
|
if (err) reject(err);
|
|
@@ -97,19 +104,9 @@ var ConduitMessagesAPI = class {
|
|
|
97
104
|
},
|
|
98
105
|
messageID
|
|
99
106
|
);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return new Promise((resolve, reject) => {
|
|
103
|
-
this.bot.ctx.api.sendMessage(
|
|
104
|
-
body,
|
|
105
|
-
threadID,
|
|
106
|
-
(err, data) => {
|
|
107
|
-
if (err) reject(err);
|
|
108
|
-
else resolve(data);
|
|
109
|
-
},
|
|
110
|
-
messageID
|
|
111
|
-
);
|
|
107
|
+
}, 700);
|
|
112
108
|
});
|
|
109
|
+
return this.queue ? this.queue.enqueue(threadID, fn) : fn();
|
|
113
110
|
}
|
|
114
111
|
/**
|
|
115
112
|
* Edits an existing message.
|
|
@@ -155,15 +152,16 @@ var ConduitMessagesAPI = class {
|
|
|
155
152
|
* @param threadID - The thread the message belongs to.
|
|
156
153
|
*/
|
|
157
154
|
react(emoji, messageID, threadID) {
|
|
158
|
-
return new Promise((resolve, reject) => {
|
|
155
|
+
return new Promise(async (resolve, reject) => {
|
|
156
|
+
await sleep(500, 700);
|
|
159
157
|
this.bot.ctx.api.setMessageReaction(
|
|
160
158
|
emoji,
|
|
161
159
|
messageID,
|
|
160
|
+
threadID,
|
|
162
161
|
(err) => {
|
|
163
162
|
if (err) reject(err);
|
|
164
163
|
else resolve(null);
|
|
165
|
-
}
|
|
166
|
-
threadID
|
|
164
|
+
}
|
|
167
165
|
);
|
|
168
166
|
});
|
|
169
167
|
}
|
|
@@ -173,7 +171,7 @@ var ConduitMessagesAPI = class {
|
|
|
173
171
|
*/
|
|
174
172
|
sendTypingIndicator(threadID) {
|
|
175
173
|
return new Promise((resolve, reject) => {
|
|
176
|
-
this.bot.ctx.api.sendTypingIndicator(threadID, (err) => {
|
|
174
|
+
this.bot.ctx.api.sendTypingIndicator(threadID, async (err) => {
|
|
177
175
|
if (err) reject(err);
|
|
178
176
|
else resolve(null);
|
|
179
177
|
});
|
|
@@ -282,10 +280,12 @@ var ConduitMessagesAPI = class {
|
|
|
282
280
|
|
|
283
281
|
// src/api/ConduitThreadsAPI.ts
|
|
284
282
|
var ConduitThreadsAPI = class {
|
|
285
|
-
constructor(bot) {
|
|
283
|
+
constructor(bot, queue) {
|
|
286
284
|
this.bot = bot;
|
|
285
|
+
this.queue = queue;
|
|
287
286
|
}
|
|
288
287
|
bot;
|
|
288
|
+
queue;
|
|
289
289
|
/**
|
|
290
290
|
* Fetches detailed info about a thread.
|
|
291
291
|
* @param threadID - The thread ID to query.
|
|
@@ -425,7 +425,7 @@ var ConduitThreadsAPI = class {
|
|
|
425
425
|
* @param userID - The target user ID.
|
|
426
426
|
*/
|
|
427
427
|
changeNickname(nickname, threadID, userID) {
|
|
428
|
-
|
|
428
|
+
const fn = () => new Promise((resolve, reject) => {
|
|
429
429
|
this.bot.ctx.api.changeNickname(
|
|
430
430
|
nickname,
|
|
431
431
|
threadID,
|
|
@@ -436,6 +436,7 @@ var ConduitThreadsAPI = class {
|
|
|
436
436
|
}
|
|
437
437
|
);
|
|
438
438
|
});
|
|
439
|
+
return this.queue ? this.queue.enqueue(threadID, fn) : fn();
|
|
439
440
|
}
|
|
440
441
|
/**
|
|
441
442
|
* Changes the title of a group thread.
|
|
@@ -443,12 +444,13 @@ var ConduitThreadsAPI = class {
|
|
|
443
444
|
* @param threadID - The target group thread ID.
|
|
444
445
|
*/
|
|
445
446
|
setTitle(title, threadID) {
|
|
446
|
-
|
|
447
|
+
const fn = () => new Promise((resolve, reject) => {
|
|
447
448
|
this.bot.ctx.api.setTitle(title, threadID, (err) => {
|
|
448
449
|
if (err) reject(err);
|
|
449
450
|
else resolve(null);
|
|
450
451
|
});
|
|
451
452
|
});
|
|
453
|
+
return this.queue ? this.queue.enqueue(threadID, fn) : fn();
|
|
452
454
|
}
|
|
453
455
|
/**
|
|
454
456
|
* Creates a poll in a thread.
|
|
@@ -457,7 +459,7 @@ var ConduitThreadsAPI = class {
|
|
|
457
459
|
* @param options - Array of answer options.
|
|
458
460
|
*/
|
|
459
461
|
createPoll(title, threadID, options) {
|
|
460
|
-
|
|
462
|
+
const fn = () => new Promise((resolve, reject) => {
|
|
461
463
|
this.bot.ctx.api.createPoll(
|
|
462
464
|
title,
|
|
463
465
|
threadID,
|
|
@@ -468,6 +470,7 @@ var ConduitThreadsAPI = class {
|
|
|
468
470
|
}
|
|
469
471
|
);
|
|
470
472
|
});
|
|
473
|
+
return this.queue ? this.queue.enqueue(threadID, fn) : fn();
|
|
471
474
|
}
|
|
472
475
|
/**
|
|
473
476
|
* Deletes a thread.
|
|
@@ -618,6 +621,55 @@ var ConduitAccountAPI = class {
|
|
|
618
621
|
}
|
|
619
622
|
};
|
|
620
623
|
|
|
624
|
+
// src/utils/ConduitQueue.ts
|
|
625
|
+
var ConduitQueue = class {
|
|
626
|
+
minDelayMs;
|
|
627
|
+
maxDelayMs;
|
|
628
|
+
switchDelayMinMs;
|
|
629
|
+
switchDelayMaxMs;
|
|
630
|
+
queues;
|
|
631
|
+
running;
|
|
632
|
+
lastThreadID = null;
|
|
633
|
+
constructor(options) {
|
|
634
|
+
this.minDelayMs = options.minDelayMs;
|
|
635
|
+
this.maxDelayMs = options.maxDelayMs;
|
|
636
|
+
this.switchDelayMinMs = options.switchDelayMinMs ?? 500;
|
|
637
|
+
this.switchDelayMaxMs = options.switchDelayMaxMs ?? 700;
|
|
638
|
+
this.queues = /* @__PURE__ */ new Map();
|
|
639
|
+
this.running = /* @__PURE__ */ new Map();
|
|
640
|
+
}
|
|
641
|
+
enqueue(threadID, job) {
|
|
642
|
+
return new Promise((resolve, reject) => {
|
|
643
|
+
if (!this.queues.has(threadID)) this.queues.set(threadID, []);
|
|
644
|
+
this.queues.get(threadID).push(async () => {
|
|
645
|
+
try {
|
|
646
|
+
resolve(await job());
|
|
647
|
+
} catch (e) {
|
|
648
|
+
reject(e);
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
if (!this.running.get(threadID)) this._run(threadID);
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
async _run(threadID) {
|
|
655
|
+
this.running.set(threadID, true);
|
|
656
|
+
const queue = this.queues.get(threadID);
|
|
657
|
+
while (queue.length > 0) {
|
|
658
|
+
if (this.lastThreadID !== null && this.lastThreadID !== threadID) {
|
|
659
|
+
await sleep(this.switchDelayMinMs, this.switchDelayMaxMs);
|
|
660
|
+
}
|
|
661
|
+
this.lastThreadID = threadID;
|
|
662
|
+
const job = queue.shift();
|
|
663
|
+
await job().catch(console.error);
|
|
664
|
+
if (queue.length > 0) {
|
|
665
|
+
await sleep(this.minDelayMs, this.maxDelayMs);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
this.queues.delete(threadID);
|
|
669
|
+
this.running.delete(threadID);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
|
|
621
673
|
// src/client/ConduitClient.ts
|
|
622
674
|
var FANOUT_EVENTS = /* @__PURE__ */ new Set([
|
|
623
675
|
"user:create",
|
|
@@ -629,6 +681,10 @@ var FANOUT_EVENTS = /* @__PURE__ */ new Set([
|
|
|
629
681
|
"thread:nickname_changed",
|
|
630
682
|
"thread:admin_changed"
|
|
631
683
|
]);
|
|
684
|
+
var MESSAGE_REPLYABLE = /* @__PURE__ */ new Set([
|
|
685
|
+
"message:create",
|
|
686
|
+
"message:respond"
|
|
687
|
+
]);
|
|
632
688
|
var LOG_MESSAGE_TYPE_MAP = {
|
|
633
689
|
"log:subscribe": "user:create",
|
|
634
690
|
"log:unsubscribe": "user:remove",
|
|
@@ -649,6 +705,10 @@ var ConduitClient = class {
|
|
|
649
705
|
_users = null;
|
|
650
706
|
/** Lazily-initialized account API wrapper. */
|
|
651
707
|
_account = null;
|
|
708
|
+
/** Lazily-initialized queue for message operations. */
|
|
709
|
+
_messageQueue = null;
|
|
710
|
+
/** Lazily-initialized queue for thread operations. */
|
|
711
|
+
_threadQueue = null;
|
|
652
712
|
/** Configuration forwarded to the FCA layer on login. */
|
|
653
713
|
config;
|
|
654
714
|
/**
|
|
@@ -681,7 +741,10 @@ var ConduitClient = class {
|
|
|
681
741
|
* and other message-level interactions.
|
|
682
742
|
*/
|
|
683
743
|
get messages() {
|
|
684
|
-
return this._messages ??= new ConduitMessagesAPI(
|
|
744
|
+
return this._messages ??= new ConduitMessagesAPI(
|
|
745
|
+
this.client,
|
|
746
|
+
this.config.queue?.messageQueue ? this.messageQueue : void 0
|
|
747
|
+
);
|
|
685
748
|
}
|
|
686
749
|
/**
|
|
687
750
|
* API for thread management operations.
|
|
@@ -691,7 +754,10 @@ var ConduitClient = class {
|
|
|
691
754
|
* and handling thread-level features like polls.
|
|
692
755
|
*/
|
|
693
756
|
get threads() {
|
|
694
|
-
return this._threads ??= new ConduitThreadsAPI(
|
|
757
|
+
return this._threads ??= new ConduitThreadsAPI(
|
|
758
|
+
this.client,
|
|
759
|
+
this.config.queue?.threadQueue ? this.threadQueue : void 0
|
|
760
|
+
);
|
|
695
761
|
}
|
|
696
762
|
/**
|
|
697
763
|
* API for user-related operations.
|
|
@@ -712,6 +778,24 @@ var ConduitClient = class {
|
|
|
712
778
|
get account() {
|
|
713
779
|
return this._account ??= new ConduitAccountAPI(this.client);
|
|
714
780
|
}
|
|
781
|
+
/**
|
|
782
|
+
* Lazily-initialized queue for message operations.
|
|
783
|
+
* Only created when `config.queue.messageQueue` is defined.
|
|
784
|
+
*/
|
|
785
|
+
get messageQueue() {
|
|
786
|
+
return this._messageQueue ??= new ConduitQueue(
|
|
787
|
+
this.config.queue?.messageQueue ?? {}
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Lazily-initialized queue for thread operations.
|
|
792
|
+
* Only created when `config.queue.threadQueue` is defined.
|
|
793
|
+
*/
|
|
794
|
+
get threadQueue() {
|
|
795
|
+
return this._threadQueue ??= new ConduitQueue(
|
|
796
|
+
this.config.queue?.threadQueue ?? {}
|
|
797
|
+
);
|
|
798
|
+
}
|
|
715
799
|
/**
|
|
716
800
|
* Authenticates with Messenger and initialises the underlying FCA bot.
|
|
717
801
|
* Must be called before any events can be received.
|
|
@@ -773,12 +857,10 @@ var ConduitClient = class {
|
|
|
773
857
|
return this;
|
|
774
858
|
}
|
|
775
859
|
/**
|
|
776
|
-
*
|
|
777
|
-
* have any type safety and auto-completion features. Use
|
|
778
|
-
* at your own risk.
|
|
860
|
+
* Direct access to the raw FCA API. No type safety — use as a last resort.
|
|
779
861
|
*
|
|
780
|
-
* @returns The raw
|
|
781
|
-
|
|
862
|
+
* @returns The raw FCA API context.
|
|
863
|
+
*/
|
|
782
864
|
get api() {
|
|
783
865
|
return this.client.ctx.api;
|
|
784
866
|
}
|
|
@@ -801,7 +883,7 @@ var ConduitClient = class {
|
|
|
801
883
|
* This getter enforces the client lifecycle by ensuring that the underlying
|
|
802
884
|
* FCA bot has been created via {@link login} before any access is allowed.
|
|
803
885
|
*
|
|
804
|
-
* @throws {ConduitError} If the client has not been initialized yet
|
|
886
|
+
* @throws {ConduitError} If the client has not been initialized yet.
|
|
805
887
|
* @returns {MessengerBot} The active Messenger bot instance.
|
|
806
888
|
*/
|
|
807
889
|
get client() {
|
|
@@ -813,8 +895,8 @@ var ConduitClient = class {
|
|
|
813
895
|
* relevant Conduit events based on the incoming `logMessageType`.
|
|
814
896
|
*
|
|
815
897
|
* `thread:update` always fires with the raw payload when its stack is
|
|
816
|
-
* non-empty. Specific sub-events
|
|
817
|
-
*
|
|
898
|
+
* non-empty. Specific sub-events fire only when their stack is also
|
|
899
|
+
* non-empty and a matching `logMessageType` exists.
|
|
818
900
|
*
|
|
819
901
|
* Calling this method more than once is a no-op.
|
|
820
902
|
*/
|
|
@@ -852,7 +934,7 @@ var ConduitClient = class {
|
|
|
852
934
|
const sendable = {
|
|
853
935
|
send: (body) => this.messages.send(body, threadID)
|
|
854
936
|
};
|
|
855
|
-
if (
|
|
937
|
+
if (MESSAGE_REPLYABLE.has(event)) {
|
|
856
938
|
return {
|
|
857
939
|
...raw,
|
|
858
940
|
...sendable,
|
|
@@ -860,6 +942,14 @@ var ConduitClient = class {
|
|
|
860
942
|
react: (emoji) => this.messages.react(emoji, messageID, threadID)
|
|
861
943
|
};
|
|
862
944
|
}
|
|
945
|
+
if (event.startsWith("thread:") || event === "user:create" || event === "user:remove") {
|
|
946
|
+
return {
|
|
947
|
+
...raw,
|
|
948
|
+
...sendable,
|
|
949
|
+
changeNickname: (nickname, userID) => this.threads.changeNickname(nickname, threadID, userID),
|
|
950
|
+
changeAdminStatus: (userID, isAdmin) => this.threads.changeAdminStatus(userID, threadID, isAdmin)
|
|
951
|
+
};
|
|
952
|
+
}
|
|
863
953
|
return { ...raw, ...sendable };
|
|
864
954
|
}
|
|
865
955
|
/**
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/toFcaEvent.ts","../src/errors/ConduitError.ts","../src/api/ConduitMessagesAPI.ts","../src/api/ConduitThreadsAPI.ts","../src/api/ConduitUsersAPI.ts","../src/api/ConduitAccountAPI.ts","../src/client/ConduitClient.ts"],"names":["createMessengerBot"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ConduitEvents } from \"../types.js\";\n\nconst FCA_EVENT_MAP = {\n \"message:create\": \"message\",\n \"message:remove\": \"message_unsend\",\n \"message:react\": \"message_reaction\",\n \"message:respond\": \"message_reply\",\n \"message:writing\": \"typ\",\n \"message:read\": \"read_receipt\",\n\n \"user:create\": \"event\", // log:subscribe\n \"user:remove\": \"event\", // log:unsubscribe\n\n \"thread:update\": \"event\",\n \"thread:title_change\": \"event\", // log:thread-name\n \"thread:photo_replaced\": \"event\", // log:thread-image\n \"thread:theme_changed\": \"event\", // log:thread-color\n \"thread:nickname_changed\": \"event\", // log:user-nickname\n \"thread:admin_changed\": \"event\", // log:admin-text\n} as const satisfies Record<keyof ConduitEvents, string>;\n\ntype FcaEventName = (typeof FCA_EVENT_MAP)[keyof typeof FCA_EVENT_MAP];\n\nexport function toFcaEvent(event: keyof ConduitEvents): FcaEventName {\n return FCA_EVENT_MAP[event];\n}\n","export class ConduitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConduitError\";\n }\n\n public static new(message: string) {\n return new ConduitError(message);\n }\n\n public static uninitializedClient() {\n return ConduitError.new(\n \"Conduit client not yet initialized. Please call the .login(credentials) method\",\n );\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\nimport { ConduitMessageBody } from \"../types.js\";\n\n/**\n * Provides message-related API methods wrapping the underlying FCA client.\n * Accessible via `client.messages`.\n */\nexport class ConduitMessagesAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Sends a message to a thread.\n * @param body - The message text.\n * @param threadID - The target thread ID.\n */\n send(body: string | ConduitMessageBody, threadID: string): Promise<any> {\n if (typeof body === \"string\") {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendMessage(\n { body },\n threadID,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendMessage(body, threadID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Sends a quoted reply to a specific message.\n * @param body - The reply text.\n * @param threadID - The target thread ID.\n * @param messageID - The message ID to reply to.\n */\n reply(\n body: string | ConduitMessageBody,\n threadID: string,\n messageID: string,\n ): Promise<any> {\n if (typeof body === \"string\") {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendMessage(\n { body },\n threadID,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n messageID,\n );\n });\n }\n\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendMessage(\n body,\n threadID,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n messageID,\n );\n });\n }\n\n /**\n * Edits an existing message.\n * @param messageID - The message ID to edit.\n * @param body - The new message text.\n */\n edit(messageID: string, body: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.editMessage(body, messageID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Unsends (retracts) a message sent by the bot.\n * @param messageID - The message ID to unsend.\n */\n unsend(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.unsendMessage(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Deletes a message.\n * @param messageID - The message ID to delete.\n */\n delete(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.deleteMessage(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Adds or removes a reaction on a message.\n * @param emoji - The emoji reaction string.\n * @param messageID - The target message ID.\n * @param threadID - The thread the message belongs to.\n */\n react(emoji: string, messageID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.setMessageReaction(\n emoji,\n messageID,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n threadID,\n );\n });\n }\n\n /**\n * Sends a typing indicator to a thread.\n * @param threadID - The target thread ID.\n */\n sendTypingIndicator(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendTypingIndicator(threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Marks a message as read.\n * @param messageID - The message ID to mark as read.\n */\n markAsRead(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.markAsRead(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Uploads a file attachment and returns an attachment object.\n * @param file - A readable stream or file buffer.\n */\n uploadAttachment(file: any): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.uploadAttachment(file, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Forwards an existing attachment to another thread.\n * @param attachmentID - The attachment ID to forward.\n * @param threadID - The target thread ID.\n */\n forwardAttachment(attachmentID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.forwardAttachment(attachmentID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Shares a contact card to a thread.\n * @param userID - The user ID of the contact to share.\n * @param threadID - The target thread ID.\n */\n shareContact(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.shareContact(userID, threadID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Changes the color theme of a thread.\n * @param color - The color hex string.\n * @param threadID - The target thread ID.\n */\n changeThreadColor(color: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeThreadColor(color, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Changes the quick-reaction emoji of a thread.\n * @param emoji - The emoji string.\n * @param threadID - The target thread ID.\n */\n changeThreadEmoji(emoji: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeThreadEmoji(emoji, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Fetches a specific message by ID.\n * @param messageID - The message ID to fetch.\n */\n getMessage(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getMessage(messageID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Returns all available thread color themes.\n */\n getThreadColors(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadColors((err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\n\n/**\n * Provides thread-related API methods wrapping the underlying FCA client.\n * Accessible via `client.threads`.\n */\nexport class ConduitThreadsAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Fetches detailed info about a thread.\n * @param threadID - The thread ID to query.\n */\n getInfo(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadInfo(threadID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Fetches a paginated list of threads.\n * @param limit - Number of threads to return.\n * @param cursor - Pagination cursor, or `null` for the first page.\n * @param folders - Folder filters e.g. `[\"INBOX\"]`.\n */\n getList(limit: number, cursor: any, folders: string[]): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadList(\n limit,\n cursor,\n folders,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Fetches message history for a thread.\n * @param threadID - The thread ID to query.\n * @param limit - Number of messages to return.\n */\n getHistory(threadID: string, limit: number): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadHistory(\n threadID,\n limit,\n undefined,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Searches for threads by name or keyword.\n * @param query - The search query string.\n */\n search(query: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.searchForThread(query, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Creates a new group conversation.\n * @param userIDs - Array of user IDs to add to the group.\n * @param name - Optional group name.\n */\n createGroup(userIDs: string[], name?: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.createNewGroup(userIDs, name, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Adds a user to an existing group thread.\n * @param userID - The user ID to add.\n * @param threadID - The target group thread ID.\n */\n addUser(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.addUserToGroup(userID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Removes a user from a group thread.\n * @param userID - The user ID to remove.\n * @param threadID - The target group thread ID.\n */\n removeUser(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.removeUserFromGroup(userID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Promotes or demotes a user's admin status in a group.\n * @param userID - The target user ID.\n * @param threadID - The group thread ID.\n * @param admin - `true` to promote, `false` to demote.\n */\n changeAdminStatus(\n userID: string,\n threadID: string,\n admin: boolean,\n ): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeAdminStatus(\n userID,\n threadID,\n admin,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n );\n });\n }\n\n /**\n * Updates the group's profile image.\n * @param image - A readable stream or file buffer.\n * @param threadID - The target group thread ID.\n */\n changeGroupImage(image: any, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeGroupImage(image, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Sets a participant's nickname in a thread.\n * @param nickname - The new nickname. Pass an empty string to clear.\n * @param threadID - The thread ID.\n * @param userID - The target user ID.\n */\n changeNickname(\n nickname: string,\n threadID: string,\n userID: string,\n ): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeNickname(\n nickname,\n threadID,\n userID,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n );\n });\n }\n\n /**\n * Changes the title of a group thread.\n * @param title - The new group title.\n * @param threadID - The target group thread ID.\n */\n setTitle(title: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.setTitle(title, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Creates a poll in a thread.\n * @param title - The poll question.\n * @param threadID - The target thread ID.\n * @param options - Array of answer options.\n */\n createPoll(title: string, threadID: string, options: string[]): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.createPoll(\n title,\n threadID,\n options,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Deletes a thread.\n * @param threadID - The thread ID to delete.\n */\n delete(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.deleteThread(threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Mutes or unmutes notifications for a thread.\n * @param threadID - The target thread ID.\n * @param muteUntil - Timestamp (ms) to mute until. Pass `-1` to mute indefinitely, `0` to unmute.\n */\n mute(threadID: string, muteUntil: number): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.muteThread(threadID, muteUntil, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Accepts or declines a message request.\n * @param threadID - The thread ID of the request.\n * @param accept - `true` to accept, `false` to decline.\n */\n handleMessageRequest(threadID: string, accept: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.handleMessageRequest(threadID, accept, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\n\n/**\n * Provides user-related API methods wrapping the underlying FCA client.\n * Accessible via `client.users`.\n */\nexport class ConduitUsersAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Fetches info for one or more users by ID.\n * @param userID - A single user ID or an array of user IDs.\n */\n getInfo(userID: string | string[]): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getUserInfo(\n Array.isArray(userID) ? userID : [userID],\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Resolves a vanity URL or username to a Facebook user ID.\n * @param vanity - The vanity name or profile URL slug.\n */\n getID(vanity: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getUserID(vanity, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Returns the authenticated user's friends list.\n */\n getFriendsList(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getFriendsList((err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\n\n/**\n * Provides account-related API methods wrapping the underlying FCA client.\n * Accessible via `client.account`.\n */\nexport class ConduitAccountAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Returns the logged-in user's Facebook ID.\n */\n getCurrentUserID(): string {\n return this.bot.ctx.api.getCurrentUserID();\n }\n\n /**\n * Blocks or unblocks a user.\n * @param userID - The target user ID.\n * @param block - `true` to block, `false` to unblock.\n */\n blockUser(userID: string, block: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeBlockedStatus(userID, block, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Accepts or declines a friend request.\n * @param userID - The user ID who sent the request.\n * @param accept - `true` to accept, `false` to decline.\n */\n handleFriendRequest(userID: string, accept: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.handleFriendRequest(userID, accept, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Removes a user from the friends list.\n * @param userID - The target user ID.\n */\n unfriend(userID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.unfriend(userID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Ends the current session and invalidates cookies.\n */\n logout(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.logout((err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n}\n","import { createMessengerBot, MessengerBot } from \"@dongdev/fca-unofficial\";\nimport {\n ConduitClientConfig,\n ConduitCredentials,\n ConduitEvents,\n Middleware,\n} from \"../types.js\";\nimport { toFcaEvent } from \"../utils/toFcaEvent.js\";\nimport { ConduitError } from \"../errors/ConduitError.js\";\nimport { ConduitMessagesAPI } from \"../api/ConduitMessagesAPI.js\";\nimport { ConduitThreadsAPI } from \"../api/ConduitThreadsAPI.js\";\nimport { ConduitUsersAPI } from \"../api/ConduitUsersAPI.js\";\nimport { ConduitAccountAPI } from \"../api/ConduitAccountAPI.js\";\n\n/**\n * Set of Conduit events that are dispatched via the fan-out mechanism,\n * meaning they are all sourced from a single underlying `threadUpdate` FCA event.\n */\nconst FANOUT_EVENTS = new Set<keyof ConduitEvents>([\n \"user:create\",\n \"user:remove\",\n \"thread:update\",\n \"thread:title_change\",\n \"thread:photo_replaced\",\n \"thread:theme_changed\",\n \"thread:nickname_changed\",\n \"thread:admin_changed\",\n]);\n\n/**\n * Maps FCA `logMessageType` strings to their corresponding Conduit event keys.\n * Used during fan-out to route `threadUpdate` payloads to the correct event stack.\n */\nconst LOG_MESSAGE_TYPE_MAP: Record<string, keyof ConduitEvents> = {\n \"log:subscribe\": \"user:create\",\n \"log:unsubscribe\": \"user:remove\",\n \"log:thread-name\": \"thread:title_change\",\n \"log:thread-image\": \"thread:photo_replaced\",\n \"log:thread-color\": \"thread:theme_changed\",\n \"log:user-nickname\": \"thread:nickname_changed\",\n \"log:thread-admins\": \"thread:admin_changed\",\n};\n\n/**\n * High-level Messenger client that wraps the FCA unofficial API and exposes\n * a middleware-based event system modelled after Express/Koa.\n *\n * @example\n * ```ts\n * const conduit = new ConduitClient(config);\n * await conduit.login(credentials);\n * conduit.on(\"message:text\", async (ctx, next) => {\n * console.log(ctx.body);\n * await next();\n * });\n * ```\n */\nexport class ConduitClient {\n /** Underlying FCA bot instance. `null` until {@link login} resolves. */\n private _client: MessengerBot | null;\n\n /** Lazily-initialized messages API wrapper. */\n private _messages: ConduitMessagesAPI | null = null;\n\n /** Lazily-initialized threads API wrapper. */\n private _threads: ConduitThreadsAPI | null = null;\n\n /** Lazily-initialized users API wrapper. */\n private _users: ConduitUsersAPI | null = null;\n\n /** Lazily-initialized account API wrapper. */\n private _account: ConduitAccountAPI | null = null;\n\n /** Configuration forwarded to the FCA layer on login. */\n private config: ConduitClientConfig;\n\n /**\n * Registry of middleware stacks keyed by Conduit event name.\n * Each stack is executed in insertion order via {@link runStack}.\n */\n private middlewares: Map<\n keyof ConduitEvents,\n Middleware<keyof ConduitEvents>[]\n >;\n\n /**\n * Guards against registering the `threadUpdate` fan-out listener more than once,\n * regardless of how many fan-out events are subscribed to.\n */\n private fanOutBound: boolean;\n\n /**\n * @param config - Client configuration passed through to the FCA bot.\n */\n constructor(config: ConduitClientConfig) {\n this._client = null;\n this.config = {\n ...config,\n logLevel: config.logLevel ?? \"silent\",\n };\n this.middlewares = new Map();\n this.fanOutBound = false;\n }\n\n /**\n * API for message operations.\n *\n * Provides methods for sending messages, replying to threads,\n * reacting to messages, editing content, deleting messages,\n * and other message-level interactions.\n */\n get messages(): ConduitMessagesAPI {\n return (this._messages ??= new ConduitMessagesAPI(this.client));\n }\n\n /**\n * API for thread management operations.\n *\n * Includes functionality for retrieving thread data,\n * managing participants, updating thread metadata (such as title),\n * and handling thread-level features like polls.\n */\n get threads(): ConduitThreadsAPI {\n return (this._threads ??= new ConduitThreadsAPI(this.client));\n }\n\n /**\n * API for user-related operations.\n *\n * Supports fetching user profiles, resolving user IDs,\n * and accessing social graph data such as friends or connections.\n */\n get users(): ConduitUsersAPI {\n return (this._users ??= new ConduitUsersAPI(this.client));\n }\n\n /**\n * API for account-level operations.\n *\n * Exposes actions tied to the authenticated account such as\n * retrieving the current user ID, managing friend requests,\n * blocking users, and logging out.\n */\n get account(): ConduitAccountAPI {\n return (this._account ??= new ConduitAccountAPI(this.client));\n }\n\n /**\n * Authenticates with Messenger and initialises the underlying FCA bot.\n * Must be called before any events can be received.\n *\n * @param credentials - App-state, cookies, or email/password credentials.\n * @returns The current instance for chaining.\n */\n public async login(credentials: ConduitCredentials): Promise<this> {\n this._client = await createMessengerBot(\n {\n appState: credentials.appstate,\n Cookie: credentials.cookies,\n email: credentials.account?.email,\n password: credentials.account?.password,\n },\n this.config,\n );\n return this;\n }\n\n /**\n * Registers one or more middleware handlers for a Conduit event.\n *\n * The first call for a given event also binds the corresponding FCA listener.\n * Fan-out events share a single `threadUpdate` FCA binding; all others get\n * their own dedicated listener via {@link bindConduitEvent}.\n *\n * @param event - The Conduit event name to subscribe to.\n * @param middlewares - Ordered middleware functions to push onto the stack.\n * @returns The current instance for chaining.\n */\n public on<K extends keyof ConduitEvents>(\n event: K,\n ...middlewares: Middleware<K>[]\n ): this {\n if (!this.middlewares.has(event)) {\n this.middlewares.set(event, []);\n\n if (FANOUT_EVENTS.has(event)) {\n this.bindFanOutEvents();\n } else {\n this.bindConduitEvent(event);\n }\n }\n this.middlewares\n .get(event)!\n .push(...(middlewares as Middleware<keyof ConduitEvents>[]));\n return this;\n }\n\n /**\n * Registers middleware directly against a raw FCA event, bypassing the\n * Conduit event abstraction entirely. Useful for events not yet mapped\n * by the Conduit layer.\n *\n * @param event - Raw FCA event name.\n * @param middlewares - Middleware functions receiving the raw FCA payload.\n * @returns The current instance for chaining.\n */\n public onFca(\n event: string,\n ...middlewares: ((data: any, next?: () => Promise<void>) => Promise<void>)[]\n ): this {\n this.client.on(event, async (data: any) => {\n await this.runStack(\n middlewares as Middleware<keyof ConduitEvents>[],\n data,\n );\n });\n return this;\n }\n\n /**\n * Uses the raw legacy api. Not recommended as this do not\n * have any type safety and auto-completion features. Use\n * at your own risk.\n *\n * @returns The raw api context.\n * */\n public get api(): any {\n return this.client.ctx.api;\n }\n\n /**\n * Translates a single Conduit event to its FCA equivalent and attaches a\n * listener that enriches the raw payload before running the middleware stack.\n *\n * @param event - The Conduit event to bind.\n */\n private bindConduitEvent<K extends keyof ConduitEvents>(event: K) {\n const fcaEvent = toFcaEvent(event);\n this.client.on(fcaEvent, async (raw: any) => {\n const stack = this.middlewares.get(event) ?? [];\n await this.runStack(stack, this.enrich(event, raw));\n });\n }\n\n /**\n * Returns the initialized Messenger client instance.\n *\n * This getter enforces the client lifecycle by ensuring that the underlying\n * FCA bot has been created via {@link login} before any access is allowed.\n *\n * @throws {ConduitError} If the client has not been initialized yet (login not called).\n * @returns {MessengerBot} The active Messenger bot instance.\n */\n private get client(): MessengerBot {\n if (this._client) return this._client;\n throw ConduitError.uninitializedClient();\n }\n\n /**\n * Attaches a single `threadUpdate` FCA listener that fans out to all\n * relevant Conduit events based on the incoming `logMessageType`.\n *\n * `thread:update` always fires with the raw payload when its stack is\n * non-empty. Specific sub-events (e.g. `thread:title_change`) fire only\n * when their stack is also non-empty and a matching `logMessageType` exists.\n *\n * Calling this method more than once is a no-op.\n */\n private bindFanOutEvents() {\n if (this.fanOutBound) return;\n this.fanOutBound = true;\n\n this.client.on(\"threadUpdate\", async (raw: any) => {\n const { logMessageType } = raw;\n\n const updateStack = this.middlewares.get(\"thread:update\") ?? [];\n if (updateStack.length > 0) {\n await this.runStack(updateStack, this.enrich(\"thread:update\", raw));\n }\n\n const conduitEvent = LOG_MESSAGE_TYPE_MAP[logMessageType];\n if (!conduitEvent) return;\n\n const stack = this.middlewares.get(conduitEvent) ?? [];\n if (stack.length === 0) return;\n\n await this.runStack(stack, this.enrich(conduitEvent, raw));\n });\n }\n\n /**\n * Augments a raw FCA payload with convenience helpers scoped to the event.\n *\n * All events receive a `send` helper for replying to the source thread.\n * Events in the `message:` namespace additionally receive:\n * - `reply` — sends a quoted reply to the triggering message.\n * - `react` — sets an emoji reaction on the triggering message.\n *\n * @param event - The Conduit event being enriched.\n * @param raw - The raw FCA payload.\n * @returns The enriched context object passed to middleware.\n */\n private enrich(event: keyof ConduitEvents, raw: any): any {\n const threadID = raw.threadID;\n const messageID = raw.messageID;\n\n const sendable = {\n send: (body: string) => this.messages.send(body, threadID),\n };\n\n if (event.startsWith(\"message:\")) {\n return {\n ...raw,\n ...sendable,\n reply: (body: string) => this.messages.reply(body, threadID, messageID),\n react: (emoji: string) =>\n this.messages.react(emoji, messageID, threadID),\n };\n }\n\n return { ...raw, ...sendable };\n }\n\n /**\n * Executes a middleware stack sequentially, where each handler must call\n * `next()` to advance to the following handler.\n *\n * @param stack - Ordered array of middleware functions to execute.\n * @param data - The enriched event payload threaded through the stack.\n */\n private async runStack(stack: Middleware<keyof ConduitEvents>[], data: any) {\n let i = 0;\n const next = async () => {\n if (i < stack.length) {\n await stack[i++](data as never, next);\n }\n };\n await next();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/toFcaEvent.ts","../src/errors/ConduitError.ts","../src/utils/sleep.ts","../src/api/ConduitMessagesAPI.ts","../src/api/ConduitThreadsAPI.ts","../src/api/ConduitUsersAPI.ts","../src/api/ConduitAccountAPI.ts","../src/utils/ConduitQueue.ts","../src/client/ConduitClient.ts"],"names":["createMessengerBot"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ConduitEvents } from \"../types.js\";\n\nconst FCA_EVENT_MAP = {\n \"message:create\": \"message\",\n \"message:remove\": \"message_unsend\",\n \"message:react\": \"message_reaction\",\n \"message:respond\": \"message_reply\",\n \"message:writing\": \"typ\",\n \"message:read\": \"read_receipt\",\n\n \"user:create\": \"event\", // log:subscribe\n \"user:remove\": \"event\", // log:unsubscribe\n\n \"thread:update\": \"event\",\n \"thread:title_change\": \"event\", // log:thread-name\n \"thread:photo_replaced\": \"event\", // log:thread-image\n \"thread:theme_changed\": \"event\", // log:thread-color\n \"thread:nickname_changed\": \"event\", // log:user-nickname\n \"thread:admin_changed\": \"event\", // log:admin-text\n} as const satisfies Record<keyof ConduitEvents, string>;\n\ntype FcaEventName = (typeof FCA_EVENT_MAP)[keyof typeof FCA_EVENT_MAP];\n\nexport function toFcaEvent(event: keyof ConduitEvents): FcaEventName {\n return FCA_EVENT_MAP[event];\n}\n","export class ConduitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConduitError\";\n }\n\n public static new(message: string) {\n return new ConduitError(message);\n }\n\n public static uninitializedClient() {\n return ConduitError.new(\n \"Conduit client not yet initialized. Please call the .login(credentials) method\",\n );\n }\n}\n","export function sleep(min: number, max: number) {\n const delay = Math.floor(Math.random() * (max - min + 1)) + min;\n\n return new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\nimport { ConduitMessageBody } from \"../types.js\";\nimport { ConduitQueue } from \"../utils/ConduitQueue.js\";\nimport { sleep } from \"../utils/sleep.js\";\n\n/**\n * Provides message-related API methods wrapping the underlying FCA client.\n * Accessible via `client.messages`.\n */\nexport class ConduitMessagesAPI {\n constructor(\n private readonly bot: MessengerBot,\n private readonly queue?: ConduitQueue,\n ) {}\n\n /**\n * Sends a message to a thread.\n * @param body - The message text.\n * @param threadID - The target thread ID.\n */\n send(body: string | ConduitMessageBody, threadID: string): Promise<any> {\n const fn = () =>\n new Promise(async (resolve, reject) => {\n await this.bot.ctx.api.sendTypingIndicator(threadID);\n setTimeout(() => {\n this.bot.ctx.api.sendMessage(\n typeof body === \"string\" ? { body } : body,\n threadID,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n }, 700);\n });\n\n return this.queue ? this.queue.enqueue(threadID, fn) : fn();\n }\n\n /**\n * Sends a quoted reply to a specific message.\n * @param body - The reply text.\n * @param threadID - The target thread ID.\n * @param messageID - The message ID to reply to.\n */\n reply(\n body: string | ConduitMessageBody,\n threadID: string,\n messageID: string,\n ): Promise<any> {\n const fn = () =>\n new Promise(async (resolve, reject) => {\n await this.bot.ctx.api.sendTypingIndicator(threadID);\n setTimeout(() => {\n this.bot.ctx.api.sendMessage(\n typeof body === \"string\" ? { body } : body,\n threadID,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n messageID,\n );\n }, 700);\n });\n\n return this.queue ? this.queue.enqueue(threadID, fn) : fn();\n }\n\n /**\n * Edits an existing message.\n * @param messageID - The message ID to edit.\n * @param body - The new message text.\n */\n edit(messageID: string, body: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.editMessage(body, messageID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Unsends (retracts) a message sent by the bot.\n * @param messageID - The message ID to unsend.\n */\n unsend(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.unsendMessage(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Deletes a message.\n * @param messageID - The message ID to delete.\n */\n delete(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.deleteMessage(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Adds or removes a reaction on a message.\n * @param emoji - The emoji reaction string.\n * @param messageID - The target message ID.\n * @param threadID - The thread the message belongs to.\n */\n react(emoji: string, messageID: string, threadID: string): Promise<any> {\n return new Promise(async (resolve, reject) => {\n await sleep(500, 700);\n this.bot.ctx.api.setMessageReaction(\n emoji,\n messageID,\n threadID,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n );\n });\n }\n\n /**\n * Sends a typing indicator to a thread.\n * @param threadID - The target thread ID.\n */\n sendTypingIndicator(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.sendTypingIndicator(threadID, async (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Marks a message as read.\n * @param messageID - The message ID to mark as read.\n */\n markAsRead(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.markAsRead(messageID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Uploads a file attachment and returns an attachment object.\n * @param file - A readable stream or file buffer.\n */\n uploadAttachment(file: any): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.uploadAttachment(file, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Forwards an existing attachment to another thread.\n * @param attachmentID - The attachment ID to forward.\n * @param threadID - The target thread ID.\n */\n forwardAttachment(attachmentID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.forwardAttachment(attachmentID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Shares a contact card to a thread.\n * @param userID - The user ID of the contact to share.\n * @param threadID - The target thread ID.\n */\n shareContact(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.shareContact(userID, threadID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Changes the color theme of a thread.\n * @param color - The color hex string.\n * @param threadID - The target thread ID.\n */\n changeThreadColor(color: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeThreadColor(color, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Changes the quick-reaction emoji of a thread.\n * @param emoji - The emoji string.\n * @param threadID - The target thread ID.\n */\n changeThreadEmoji(emoji: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeThreadEmoji(emoji, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Fetches a specific message by ID.\n * @param messageID - The message ID to fetch.\n */\n getMessage(messageID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getMessage(messageID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Returns all available thread color themes.\n */\n getThreadColors(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadColors((err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\nimport { ConduitQueue } from \"../utils/ConduitQueue.js\";\n\n/**\n * Provides thread-related API methods wrapping the underlying FCA client.\n * Accessible via `client.threads`.\n */\nexport class ConduitThreadsAPI {\n constructor(\n private readonly bot: MessengerBot,\n private readonly queue?: ConduitQueue,\n ) {}\n\n /**\n * Fetches detailed info about a thread.\n * @param threadID - The thread ID to query.\n */\n getInfo(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadInfo(threadID, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Fetches a paginated list of threads.\n * @param limit - Number of threads to return.\n * @param cursor - Pagination cursor, or `null` for the first page.\n * @param folders - Folder filters e.g. `[\"INBOX\"]`.\n */\n getList(limit: number, cursor: any, folders: string[]): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadList(\n limit,\n cursor,\n folders,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Fetches message history for a thread.\n * @param threadID - The thread ID to query.\n * @param limit - Number of messages to return.\n */\n getHistory(threadID: string, limit: number): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getThreadHistory(\n threadID,\n limit,\n undefined,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Searches for threads by name or keyword.\n * @param query - The search query string.\n */\n search(query: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.searchForThread(query, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Creates a new group conversation.\n * @param userIDs - Array of user IDs to add to the group.\n * @param name - Optional group name.\n */\n createGroup(userIDs: string[], name?: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.createNewGroup(userIDs, name, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Adds a user to an existing group thread.\n * @param userID - The user ID to add.\n * @param threadID - The target group thread ID.\n */\n addUser(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.addUserToGroup(userID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Removes a user from a group thread.\n * @param userID - The user ID to remove.\n * @param threadID - The target group thread ID.\n */\n removeUser(userID: string, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.removeUserFromGroup(userID, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Promotes or demotes a user's admin status in a group.\n * @param userID - The target user ID.\n * @param threadID - The group thread ID.\n * @param admin - `true` to promote, `false` to demote.\n */\n changeAdminStatus(\n userID: string,\n threadID: string,\n admin: boolean,\n ): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeAdminStatus(\n userID,\n threadID,\n admin,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n );\n });\n }\n\n /**\n * Updates the group's profile image.\n * @param image - A readable stream or file buffer.\n * @param threadID - The target group thread ID.\n */\n changeGroupImage(image: any, threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeGroupImage(image, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Sets a participant's nickname in a thread.\n * @param nickname - The new nickname. Pass an empty string to clear.\n * @param threadID - The thread ID.\n * @param userID - The target user ID.\n */\n changeNickname(\n nickname: string,\n threadID: string,\n userID: string,\n ): Promise<any> {\n const fn = () =>\n new Promise((resolve, reject) => {\n this.bot.ctx.api.changeNickname(\n nickname,\n threadID,\n userID,\n (err: any) => {\n if (err) reject(err);\n else resolve(null);\n },\n );\n });\n\n return this.queue ? this.queue.enqueue(threadID, fn) : fn();\n }\n\n /**\n * Changes the title of a group thread.\n * @param title - The new group title.\n * @param threadID - The target group thread ID.\n */\n setTitle(title: string, threadID: string): Promise<any> {\n const fn = () =>\n new Promise((resolve, reject) => {\n this.bot.ctx.api.setTitle(title, threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n\n return this.queue ? this.queue.enqueue(threadID, fn) : fn();\n }\n\n /**\n * Creates a poll in a thread.\n * @param title - The poll question.\n * @param threadID - The target thread ID.\n * @param options - Array of answer options.\n */\n createPoll(title: string, threadID: string, options: string[]): Promise<any> {\n const fn = () =>\n new Promise((resolve, reject) => {\n this.bot.ctx.api.createPoll(\n title,\n threadID,\n options,\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n\n return this.queue ? this.queue.enqueue(threadID, fn) : fn();\n }\n\n /**\n * Deletes a thread.\n * @param threadID - The thread ID to delete.\n */\n delete(threadID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.deleteThread(threadID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Mutes or unmutes notifications for a thread.\n * @param threadID - The target thread ID.\n * @param muteUntil - Timestamp (ms) to mute until. Pass `-1` to mute indefinitely, `0` to unmute.\n */\n mute(threadID: string, muteUntil: number): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.muteThread(threadID, muteUntil, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Accepts or declines a message request.\n * @param threadID - The thread ID of the request.\n * @param accept - `true` to accept, `false` to decline.\n */\n handleMessageRequest(threadID: string, accept: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.handleMessageRequest(threadID, accept, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\n\n/**\n * Provides user-related API methods wrapping the underlying FCA client.\n * Accessible via `client.users`.\n */\nexport class ConduitUsersAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Fetches info for one or more users by ID.\n * @param userID - A single user ID or an array of user IDs.\n */\n getInfo(userID: string | string[]): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getUserInfo(\n Array.isArray(userID) ? userID : [userID],\n (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n },\n );\n });\n }\n\n /**\n * Resolves a vanity URL or username to a Facebook user ID.\n * @param vanity - The vanity name or profile URL slug.\n */\n getID(vanity: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getUserID(vanity, (err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n\n /**\n * Returns the authenticated user's friends list.\n */\n getFriendsList(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.getFriendsList((err: any, data: any) => {\n if (err) reject(err);\n else resolve(data);\n });\n });\n }\n}\n","import { MessengerBot } from \"@dongdev/fca-unofficial\";\n\n/**\n * Provides account-related API methods wrapping the underlying FCA client.\n * Accessible via `client.account`.\n */\nexport class ConduitAccountAPI {\n constructor(private readonly bot: MessengerBot) {}\n\n /**\n * Returns the logged-in user's Facebook ID.\n */\n getCurrentUserID(): string {\n return this.bot.ctx.api.getCurrentUserID();\n }\n\n /**\n * Blocks or unblocks a user.\n * @param userID - The target user ID.\n * @param block - `true` to block, `false` to unblock.\n */\n blockUser(userID: string, block: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.changeBlockedStatus(userID, block, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Accepts or declines a friend request.\n * @param userID - The user ID who sent the request.\n * @param accept - `true` to accept, `false` to decline.\n */\n handleFriendRequest(userID: string, accept: boolean): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.handleFriendRequest(userID, accept, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Removes a user from the friends list.\n * @param userID - The target user ID.\n */\n unfriend(userID: string): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.unfriend(userID, (err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n\n /**\n * Ends the current session and invalidates cookies.\n */\n logout(): Promise<any> {\n return new Promise((resolve, reject) => {\n this.bot.ctx.api.logout((err: any) => {\n if (err) reject(err);\n else resolve(null);\n });\n });\n }\n}\n","import { ConduitQueueConfig, ConduitQueueJob } from \"../types.js\";\nimport { sleep } from \"./sleep.js\";\n\nexport class ConduitQueue {\n private minDelayMs: number;\n private maxDelayMs: number;\n private switchDelayMinMs: number;\n private switchDelayMaxMs: number;\n private queues: Map<string, ConduitQueueJob<any>[]>;\n private running: Map<string, boolean>;\n private lastThreadID: string | null = null;\n\n constructor(options: ConduitQueueConfig) {\n this.minDelayMs = options.minDelayMs;\n this.maxDelayMs = options.maxDelayMs;\n this.switchDelayMinMs = options.switchDelayMinMs ?? 500;\n this.switchDelayMaxMs = options.switchDelayMaxMs ?? 700;\n this.queues = new Map();\n this.running = new Map();\n }\n\n public enqueue<T>(threadID: string, job: ConduitQueueJob<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n if (!this.queues.has(threadID)) this.queues.set(threadID, []);\n this.queues.get(threadID)!.push(async () => {\n try {\n resolve(await job());\n } catch (e) {\n reject(e);\n }\n });\n if (!this.running.get(threadID)) this._run(threadID);\n });\n }\n\n private async _run(threadID: string) {\n this.running.set(threadID, true);\n const queue = this.queues.get(threadID)!;\n\n while (queue.length > 0) {\n if (this.lastThreadID !== null && this.lastThreadID !== threadID) {\n await sleep(this.switchDelayMinMs, this.switchDelayMaxMs);\n }\n\n this.lastThreadID = threadID;\n const job = queue.shift()!;\n await job().catch(console.error);\n\n if (queue.length > 0) {\n await sleep(this.minDelayMs, this.maxDelayMs);\n }\n }\n\n this.queues.delete(threadID);\n this.running.delete(threadID);\n }\n}\n","import { createMessengerBot, MessengerBot } from \"@dongdev/fca-unofficial\";\nimport {\n ConduitClientConfig,\n ConduitCredentials,\n ConduitEvents,\n ConduitMessageBody,\n ConduitQueueConfig,\n Middleware,\n} from \"../types.js\";\nimport { toFcaEvent } from \"../utils/toFcaEvent.js\";\nimport { ConduitError } from \"../errors/ConduitError.js\";\nimport { ConduitMessagesAPI } from \"../api/ConduitMessagesAPI.js\";\nimport { ConduitThreadsAPI } from \"../api/ConduitThreadsAPI.js\";\nimport { ConduitUsersAPI } from \"../api/ConduitUsersAPI.js\";\nimport { ConduitAccountAPI } from \"../api/ConduitAccountAPI.js\";\nimport { ConduitQueue } from \"../utils/ConduitQueue.js\";\n\nconst FANOUT_EVENTS = new Set<keyof ConduitEvents>([\n \"user:create\",\n \"user:remove\",\n \"thread:update\",\n \"thread:title_change\",\n \"thread:photo_replaced\",\n \"thread:theme_changed\",\n \"thread:nickname_changed\",\n \"thread:admin_changed\",\n]);\n\nconst MESSAGE_REPLYABLE = new Set<keyof ConduitEvents>([\n \"message:create\",\n \"message:respond\",\n]);\n\nconst LOG_MESSAGE_TYPE_MAP: Record<string, keyof ConduitEvents> = {\n \"log:subscribe\": \"user:create\",\n \"log:unsubscribe\": \"user:remove\",\n \"log:thread-name\": \"thread:title_change\",\n \"log:thread-image\": \"thread:photo_replaced\",\n \"log:thread-color\": \"thread:theme_changed\",\n \"log:user-nickname\": \"thread:nickname_changed\",\n \"log:thread-admins\": \"thread:admin_changed\",\n};\n\n/**\n * High-level Messenger client that wraps the FCA unofficial API and exposes\n * a middleware-based event system modelled after Express/Koa.\n *\n * @example\n * ```ts\n * const conduit = new ConduitClient(config);\n * await conduit.login(credentials);\n * conduit.on(\"message:create\", async (ctx, next) => {\n * console.log(ctx.body);\n * await next();\n * });\n * ```\n */\nexport class ConduitClient {\n /** Underlying FCA bot instance. `null` until {@link login} resolves. */\n private _client: MessengerBot | null;\n\n /** Lazily-initialized messages API wrapper. */\n private _messages: ConduitMessagesAPI | null = null;\n\n /** Lazily-initialized threads API wrapper. */\n private _threads: ConduitThreadsAPI | null = null;\n\n /** Lazily-initialized users API wrapper. */\n private _users: ConduitUsersAPI | null = null;\n\n /** Lazily-initialized account API wrapper. */\n private _account: ConduitAccountAPI | null = null;\n\n /** Lazily-initialized queue for message operations. */\n private _messageQueue: ConduitQueue | null = null;\n\n /** Lazily-initialized queue for thread operations. */\n private _threadQueue: ConduitQueue | null = null;\n\n /** Configuration forwarded to the FCA layer on login. */\n private config: ConduitClientConfig;\n\n /**\n * Registry of middleware stacks keyed by Conduit event name.\n * Each stack is executed in insertion order via {@link runStack}.\n */\n private middlewares: Map<\n keyof ConduitEvents,\n Middleware<keyof ConduitEvents>[]\n >;\n\n /**\n * Guards against registering the `threadUpdate` fan-out listener more than once,\n * regardless of how many fan-out events are subscribed to.\n */\n private fanOutBound: boolean;\n\n /**\n * @param config - Client configuration passed through to the FCA bot.\n */\n constructor(config: ConduitClientConfig) {\n this._client = null;\n this.config = {\n ...config,\n logLevel: config.logLevel ?? \"silent\",\n };\n this.middlewares = new Map();\n this.fanOutBound = false;\n }\n\n /**\n * API for message operations.\n *\n * Provides methods for sending messages, replying to threads,\n * reacting to messages, editing content, deleting messages,\n * and other message-level interactions.\n */\n get messages(): ConduitMessagesAPI {\n return (this._messages ??= new ConduitMessagesAPI(\n this.client,\n this.config.queue?.messageQueue ? this.messageQueue : undefined,\n ));\n }\n\n /**\n * API for thread management operations.\n *\n * Includes functionality for retrieving thread data,\n * managing participants, updating thread metadata (such as title),\n * and handling thread-level features like polls.\n */\n get threads(): ConduitThreadsAPI {\n return (this._threads ??= new ConduitThreadsAPI(\n this.client,\n this.config.queue?.threadQueue ? this.threadQueue : undefined,\n ));\n }\n\n /**\n * API for user-related operations.\n *\n * Supports fetching user profiles, resolving user IDs,\n * and accessing social graph data such as friends or connections.\n */\n get users(): ConduitUsersAPI {\n return (this._users ??= new ConduitUsersAPI(this.client));\n }\n\n /**\n * API for account-level operations.\n *\n * Exposes actions tied to the authenticated account such as\n * retrieving the current user ID, managing friend requests,\n * blocking users, and logging out.\n */\n get account(): ConduitAccountAPI {\n return (this._account ??= new ConduitAccountAPI(this.client));\n }\n\n /**\n * Lazily-initialized queue for message operations.\n * Only created when `config.queue.messageQueue` is defined.\n */\n private get messageQueue(): ConduitQueue {\n return (this._messageQueue ??= new ConduitQueue(\n this.config.queue?.messageQueue ?? ({} as ConduitQueueConfig),\n ));\n }\n\n /**\n * Lazily-initialized queue for thread operations.\n * Only created when `config.queue.threadQueue` is defined.\n */\n private get threadQueue(): ConduitQueue {\n return (this._threadQueue ??= new ConduitQueue(\n this.config.queue?.threadQueue ?? ({} as ConduitQueueConfig),\n ));\n }\n\n /**\n * Authenticates with Messenger and initialises the underlying FCA bot.\n * Must be called before any events can be received.\n *\n * @param credentials - App-state, cookies, or email/password credentials.\n * @returns The current instance for chaining.\n */\n public async login(credentials: ConduitCredentials): Promise<this> {\n this._client = await createMessengerBot(\n {\n appState: credentials.appstate,\n Cookie: credentials.cookies,\n email: credentials.account?.email,\n password: credentials.account?.password,\n },\n this.config,\n );\n return this;\n }\n\n /**\n * Registers one or more middleware handlers for a Conduit event.\n *\n * The first call for a given event also binds the corresponding FCA listener.\n * Fan-out events share a single `threadUpdate` FCA binding; all others get\n * their own dedicated listener via {@link bindConduitEvent}.\n *\n * @param event - The Conduit event name to subscribe to.\n * @param middlewares - Ordered middleware functions to push onto the stack.\n * @returns The current instance for chaining.\n */\n public on<K extends keyof ConduitEvents>(\n event: K,\n ...middlewares: Middleware<K>[]\n ): this {\n if (!this.middlewares.has(event)) {\n this.middlewares.set(event, []);\n\n if (FANOUT_EVENTS.has(event)) {\n this.bindFanOutEvents();\n } else {\n this.bindConduitEvent(event);\n }\n }\n this.middlewares\n .get(event)!\n .push(...(middlewares as Middleware<keyof ConduitEvents>[]));\n return this;\n }\n\n /**\n * Registers middleware directly against a raw FCA event, bypassing the\n * Conduit event abstraction entirely. Useful for events not yet mapped\n * by the Conduit layer.\n *\n * @param event - Raw FCA event name.\n * @param middlewares - Middleware functions receiving the raw FCA payload.\n * @returns The current instance for chaining.\n */\n public onFca(\n event: string,\n ...middlewares: ((data: any, next?: () => Promise<void>) => Promise<void>)[]\n ): this {\n this.client.on(event, async (data: any) => {\n await this.runStack(\n middlewares as Middleware<keyof ConduitEvents>[],\n data,\n );\n });\n return this;\n }\n\n /**\n * Direct access to the raw FCA API. No type safety — use as a last resort.\n *\n * @returns The raw FCA API context.\n */\n public get api(): any {\n return this.client.ctx.api;\n }\n\n /**\n * Translates a single Conduit event to its FCA equivalent and attaches a\n * listener that enriches the raw payload before running the middleware stack.\n *\n * @param event - The Conduit event to bind.\n */\n private bindConduitEvent<K extends keyof ConduitEvents>(event: K) {\n const fcaEvent = toFcaEvent(event);\n this.client.on(fcaEvent, async (raw: any) => {\n const stack = this.middlewares.get(event) ?? [];\n await this.runStack(stack, this.enrich(event, raw));\n });\n }\n\n /**\n * Returns the initialized Messenger client instance.\n *\n * This getter enforces the client lifecycle by ensuring that the underlying\n * FCA bot has been created via {@link login} before any access is allowed.\n *\n * @throws {ConduitError} If the client has not been initialized yet.\n * @returns {MessengerBot} The active Messenger bot instance.\n */\n private get client(): MessengerBot {\n if (this._client) return this._client;\n throw ConduitError.uninitializedClient();\n }\n\n /**\n * Attaches a single `threadUpdate` FCA listener that fans out to all\n * relevant Conduit events based on the incoming `logMessageType`.\n *\n * `thread:update` always fires with the raw payload when its stack is\n * non-empty. Specific sub-events fire only when their stack is also\n * non-empty and a matching `logMessageType` exists.\n *\n * Calling this method more than once is a no-op.\n */\n private bindFanOutEvents() {\n if (this.fanOutBound) return;\n this.fanOutBound = true;\n\n this.client.on(\"threadUpdate\", async (raw: any) => {\n const { logMessageType } = raw;\n\n const updateStack = this.middlewares.get(\"thread:update\") ?? [];\n if (updateStack.length > 0) {\n await this.runStack(updateStack, this.enrich(\"thread:update\", raw));\n }\n\n const conduitEvent = LOG_MESSAGE_TYPE_MAP[logMessageType];\n if (!conduitEvent) return;\n\n const stack = this.middlewares.get(conduitEvent) ?? [];\n if (stack.length === 0) return;\n\n await this.runStack(stack, this.enrich(conduitEvent, raw));\n });\n }\n\n /**\n * Augments a raw FCA payload with convenience helpers scoped to the event.\n *\n * All events receive a `send` helper for replying to the source thread.\n * Events in the `message:` namespace additionally receive:\n * - `reply` — sends a quoted reply to the triggering message.\n * - `react` — sets an emoji reaction on the triggering message.\n *\n * @param event - The Conduit event being enriched.\n * @param raw - The raw FCA payload.\n * @returns The enriched context object passed to middleware.\n */\n private enrich(event: keyof ConduitEvents, raw: any): any {\n const threadID = raw.threadID;\n const messageID = raw.messageID;\n\n const sendable = {\n send: (body: string | ConduitMessageBody) =>\n this.messages.send(body, threadID),\n };\n\n if (MESSAGE_REPLYABLE.has(event)) {\n return {\n ...raw,\n ...sendable,\n reply: (body: string | ConduitMessageBody) =>\n this.messages.reply(body, threadID, messageID),\n react: (emoji: string) =>\n this.messages.react(emoji, messageID, threadID),\n };\n }\n\n if (\n event.startsWith(\"thread:\") ||\n event === \"user:create\" ||\n event === \"user:remove\"\n ) {\n return {\n ...raw,\n ...sendable,\n changeNickname: (nickname: string, userID: string) =>\n this.threads.changeNickname(nickname, threadID, userID),\n changeAdminStatus: (userID: string, isAdmin: boolean) =>\n this.threads.changeAdminStatus(userID, threadID, isAdmin),\n };\n }\n\n return { ...raw, ...sendable };\n }\n\n /**\n * Executes a middleware stack sequentially, where each handler must call\n * `next()` to advance to the following handler.\n *\n * @param stack - Ordered array of middleware functions to execute.\n * @param data - The enriched event payload threaded through the stack.\n */\n private async runStack(stack: Middleware<keyof ConduitEvents>[], data: any) {\n let i = 0;\n const next = async () => {\n if (i < stack.length) {\n await stack[i++](data as never, next);\n }\n };\n await next();\n }\n}\n"]}
|