校对:soup
用于节点 NEXCA MQTT − 信号协议 E2EE( mautrix- go powered) • 会话Guard 90+ API 方法 ^ 0 类型脚本
特征 二. 支助 安装 二. 支助 快速启动 二. 支助 欧2EE 二. 支助 会话守护 二. 支助 发送广播 二. 支助 API 参考
为什么?
- ✅ (NEXCA MQTT) (英语) ——稳定的连接核心,自动重联,焦急
- ✅ E2EE信号议定书 ——Facebook真实加密对话支持. 可靠媒体/反应/未发送由捆绑式供电 ma-去/ ma-去 本地引擎 (© Tulir Asokan, MPL-2.0) – NEXCA自己的手写 E2EE 编码器生成了协议验证消息,Facebook接受了这些消息,但Misser客户端未能为附件/反应/未发送提供渲染,因此这个叉子会通过本地引擎来引导这些消息. 文本消息仍然使用原始引擎(已经可靠). 本地引擎是选入的 (
FCA_E2EE_NATIVE=1()——见 本地媒体引擎。 。 。 . - ✅ 会话守护 ——吹捧腐败和无声登录保护,自动备份
- ✅ 发送广播 ——限速多行广播
- ✅ 固定 MQTT 订阅种族条件 ——不再有"拒接:不存在订阅"
- ✅
isActiveClient()警卫 ——已停止处理的 MQTT 客户端事件 - ✅
connectTimeout延长 ——不过早登录慢网 - ✅ 自动重接 ——连接时自动重接
- ✅ 山羊瓶兼容性 ——所有API签名不变(
threadID选项等) - ✅ 90+ API 方法 ——发送Message,编辑Message,设置Message反应,获取ThreadInfo等
* 特性
- * 完全信使API——信息、反应、附件、贴纸、民意测验、针头
- NEXCA MQTT — 稳定的连接, 自动重联, 焦急, isActiveClient guard
- E2EE — 信号协议加密线程, 登录后自动连接( listen E2EE, e2ee. *)
- QQ E2EE 媒体引擎 — 本土的mautrix-go引擎(opt-in通过)
FCA_E2EE_NATIVE=1),用于可靠图像/视频/音频/文档发送,反应,以及加密线程中的未发送(自动倒回内置JS引擎) - E2EE接入的媒体——加密信件上的附件(包括回复)是自动解密并在当地服务,所以现有的命令工作没有修改
- QQ会话 Guard – 启动自动保存,腐败守卫,.bak 备份
- • 指挥反垃圾人性化器——人性式回复延迟,每条线冷却,山羊Bot无前置/onChat/onReply自动检测
- QQ 发送Broadcast – 并行/相继的多行发送并限制速率
- QQ MesserBot — Discord.js/ Telegraf 风格(.command,. hears,
- QQ 创建 FcaClient —— 名空外观( 客户端. messages, 客户端. threads等)
- QQ 山羊瓶/ 三井相容——倒置替换
* 安装
npm install @eryxenx/fca
需要20号节点.
E2EE媒体引擎搭载了已预先编译的本地二进制(src/api/socket/e2ee/native/build/用于 Linux ( 财务报告和审定财务报表 视窗 (.dll),通过 koffi FFI (法语). npm install 停车 koffi 财务报告和审定财务报表 yumi-json-bigint 自动——不需要额外设置. 注意本地引擎只在 FCA_E2EE_NATIVE=1 设置(参见 本地媒体引擎;在Linux/Windows x64以外的平台上(如:macOS,ARM),二进制失败加载,而E2EE媒体/反应/unsend自动倒回内置的JS引擎上(短信无论哪种方式都不受影响).
E2EE套接字的用户代理默认为桌面 Windows Chrome 139, 以匹配客户端的其余部分; 覆盖到 FCA_E2EE_UA 如果你用不同的UA运行.
QQ 快速启动
经典( 羊肉相容 )
const login = require("@eryxenx/fca");
login({ appState: require("./account.json") }, { listenEvents: true }, (err, api) => {
if (err) throw err;
api.sessionGuard("./account.json", {
interval: 3 * 60 * 1000,
debounce: 30 * 1000
});
api.listenMqtt((err, event) => {
if (err) throw err;
if (event.type === "message") api.sendMessage(event.body, event.threadID);
});
});
与 E2EE( 常规 + 加密线程)
connectE2EE() 运行 自动 在登录后,你从不自称。 在你自己的代码中再次调用它打开了第二个,赛跑连接在同一座桥上. 检查一下 api.e2ee.isConnected() 如果你需要知道状况.
login({ appState: require("./account.json") }, { listenEvents: true }, (err, api) => {
if (err) throw err;
api.sessionGuard("./account.json");
// E2EE is already connecting in the background here — do not call connectE2EE().
api.listenE2EE((err, event) => {
if (err) throw err;
if (event.type === "message") {
if (event.isE2EE) {
api.e2ee.sendMessage(event.threadID, "Got your encrypted message!");
} else {
api.sendMessage("Got it!", event.threadID);
}
}
});
});
GoatBot 登录.js
const login = require("@eryxenx/fca");
login({ appState }, options, (err, api) => {
if (err) return;
api.sessionGuard(path.join(process.cwd(), "account.txt"), {
interval: 3 * 60 * 1000,
debounce: 30 * 1000
});
// Nothing else needed for E2EE — it auto-connects inside @eryxenx/fca
// right after login. Do NOT call api.connectE2EE() here.
api.listenMqtt(callback);
});
这是唯一需要的设置——没有其他 login.js (或山羊博特的任何地方)E2EE必须换取. 一旦登录成功, api.e2ee 已经连接在背景, 和每一个现有的山羊瓶呼叫—— api.sendMessage(...) (有无) attachment, (中文(简体) ), api.setMessageReaction(...), (中文(简体) ), api.unsendMessage(...) ——当一线程是被加密的DM和通过E2EE引擎内部的路由时,自动检测. 命令不需要知道或关心一条线程是否被加密;它们无论怎样都称同一种功能.
将此添加到您的登录.js
你的机器人是真实的 login.js 将会看起来不同于上面的片段(dashboard设置,数据库同步,自定义日志等)——你不会替换文件,只是在您已有的登录回调中添加/检查两件事:
| 步骤 | 怎么办 |
|---|---|
| 1. 会议担保 | 添加 api.sessionGuard(accountPath, { interval, debounce }) 一次,在登录成功之后,如果它还没有出现. |
| 2. E2EE | 没什么可补充的——这是自动的. 狦 login.js 已经明确 await api.connectE2EE() 打电话, 删除它 ——与自动接通是多余的,两者可以进行比赛. |
要检查E2EE是否已经连接到您的机器人,请搜索 e2ee.isConnected 在你身边 login.js 如果它在那里, 设置已经完成.
E2EE——加密对话
使用Facebook真正的信号协议基础设施——与官方"信使"应用程序相同.
设置
E2EE 登录后自动连接( 创建) .nexca/e2ee_device.json —— 没有任何手动呼叫. 连接后只需检查状态 :
console.log(api.e2ee.isConnected()); // true (may need a moment right after login)
听(常规+E2EE组合)
api.listenE2EE((err, event) => {
if (event.type === "message") {
if (event.isE2EE) {
api.e2ee.sendMessage(event.threadID, "Encrypted reply!");
} else {
api.sendMessage("Normal reply!", event.threadID);
}
}
});
E2EE方法
await api.e2ee.sendMessage(threadID, "Hello!");
await api.e2ee.sendMessage(threadID, { body: "Photo!", attachment: fs.createReadStream("photo.jpg") });
await api.e2ee.sendReaction(threadID, messageID, "❤️");
await api.e2ee.sendTyping(threadID, true);
await api.e2ee.unsendMessage(messageID, threadID);
await api.e2ee.editMessage(threadID, messageID, "Updated!");
api.e2ee.isConnected();
await api.e2ee.disconnect();
本地媒体引擎
发送图像/视频/音频/文档附件,反应,以及未发送的 E2EE 线程可以通过预编译程序进行路由 ma-去/ ma-去 二进制( e)src/api/socket/e2ee/native/通过 koffi FFI,而不是这个项目自己的手写信号协议编码器. 这个项目的自有编码器构建了Facebook服务器接受的协议验证消息,但真正的"信使"客户端却默默地无法渲染——本地引擎完全避免了这一点.
QQ 本地引擎默认是 disableD . 供应商JS引擎和本地引擎都以脸书注册 不变 E2EE设备(同一种设备id),而Facebook的服务器只保留了每个设备一个活的E2EE套接字——因此当两人一跑一次就用回路互相踢出(每几秒钟有一次新鲜的握手,这看起来就像Facebook的自动行为). 因此,供应商JS引擎只能使用套接字,除非你选择:
-
设定
FCA_E2EE_NATIVE=1在环境中,使本地引擎能够运行。 随即获得E2EE 组的文本接收/发送, 本地媒体发送, 本地反应/ 发送/ 编辑/ markRead —— 但你也接受上面描述的装置- kick sock churn(JS引擎与指数回放重联. -
与其关闭(默认):E2EE DM文本+DM媒体通过销售引擎工作. 欧2EE 组 e2EEDMs中的反应/未发送/已接收,以及E2EE markRead则无法使用;E2EE DMs中的反应/未发送/已编辑回倒入出厂引擎.
-
短信总是使用@eryxenx/fca自己的E2EE引擎(已经可靠,没有本土依赖性).
-
如果本地引擎无法加载或发送失败( 不支持的平台, 二进制不匹配等) , @ eryxenx/ fca 自动倒回自己的引擎和日志
[native-media] ... falling back to legacy vendor engine。 。 。 . -
见
src/api/socket/e2ee/native/NOTICE.md将MPL-2.0归属于上游Mautrix-go/mautrix-meta项目(Tulir Asokan和贡献者)——如果重新分配这一分叉,则不删除.
接收 E2EE 介质(附件和答复)
接收到的加密图像/视频/音频/文档消息会自动被解密,并在短命的本地URL上服务(http://127.0.0.1:<port>/<token>, 15分TTL),并有人居住 event.attachments 编号 : event.messageReply.attachments ——形状与普通(非E2EE)附件相同. 基于回复的命令( 例如“ reply to a image with /imgur")在E2EE线程中与普通线程相同,不需要命令代码更改.
if (event.messageReply && event.messageReply.attachments.length) {
const url = event.messageReply.attachments[0].url; // works for E2EE too
}
如果媒体解析失败, 请检查控制台 [media-resolve] 编号 : [media-decode] 出错——这通常是指CDN下载主机(FB_E2EE_MEDIA_DOWNLOAD_HOST var, 默认 rupload.facebook.com需要调整您的账户/区域.
* 反垃圾指挥部(人文)
延迟和速率限制命令回复,使机器人的反应像一个人 输入, 不是脚本即时开火—— 并更快地发送命令 以至人类必定派遣他们.
登录时自动安装( N)enabled (默认情况下). 不需要设置 :
login({ appState }, {}, (err, api) => {
api.listenMqtt((err, event) => { /* ... */ });
});
配置它通过 humanize 登录选项,或 api.setOptions({ humanize })数字 :
login({ appState }, {
humanize: {
enabled: true,
reactDelayMs: [2000, 3000], // random delay before a command is let through
cooldownMs: 5500, // min gap between two accepted commands (per thread)
resetMs: 10000, // idle gap before cooldown state resets
maxPerMinute: 20, // global accepted-commands cap
commands: ["/", "!", "."], // prefixes that count as "this is a command"
perThread: true // cooldown tracked per thread vs. globally
}
}, cb);
api.setOptions({ humanize: { enabled: false } }) 完全关掉.
这算什么"命令"
默认情况下,只有从其中之一开始的信件 commands 前缀为
被视为命令——其他一切(平话)通过
未触及,无延迟和打字指标.
若为 global.GoatBot 存在(即运行在山羊Bot-Pro下)
人道主义者 自动 也把这些当作命令, 带有零
需要配置 :
- 无前缀管理员命令 —— 说
config.noPrefix.enable: true+ 键 发送者在config.adminBot第一个字匹配一个真正的命令/别名. onChat触发 ——信息,其全文完全与 命令名称注册于GoatBot.onChat(例如打字)prefix与 没有/,山羊博特的哪个prefix.js回应).onReply流动 - 对所追踪的信息的答复GoatBot.onReply(如"1","2","3"等"山羊博特"所使用的数字回文setting.js菜单系统).
这意味着整个多步骤 setting 命令流——不仅仅是
初次 /setting - 得到与下述情况相同的延迟/冷却/打字处理:
常规命令.
给它一个定制的配对者:
const h = api.getHumanizer();
h.setMatcher((event) => {
// your own logic — return true to treat this event as a command
return event.body === "some no-prefix trigger";
});
matcher 也可以直接通过 humanize 配置
(单位:千美元)humanize: { matcher: fn }) (中文(简体) ). 如果消息匹配, 则它会算作命令
前缀列表 或者说 内置羊肉盒检查 或者说 选手.
打字指标
当命令被接受时, api.sendTypingIndicator(threadID, true) 实值
立即呼叫,等待 准确接受的延迟,然后关闭
在转发事件之前——所以输入指标和
回复延迟是同一个窗口, 不是两个堆叠的等 。 已禁用
如果 global.GoatBot.config.enableTypingIndicator 实值 false。 。 。 .
检查一下
const h = api.getHumanizer();
h.stats(); // { enabled, global: {accepted, dropped, ...}, threads: [...] }
h.reset(); // clear all cooldown state
注:此操作于 收到 命令音量——从 正在发送间隔( 见
sendBroadcast下面,以及任何排队你 加入你身边api.sendMessage) (中文(简体) ).
QQ 会话担保
保护你的口号不被腐败和无声关闭.
api.sessionGuard("./account.json");
// Custom timing
api.sessionGuard("./account.json", {
interval: 3 * 60 * 1000,
debounce: 30 * 1000
});
它会做什么:
- 自动保存每 N 分钟应用一次
- 每次成功发送后保存信件( 已发出)
- 腐败的守护者——永远不要用更小的顶端来覆盖更大的顶端
- 自动备份——写
.bak在每一个覆盖之前
api.saveSession(); // force save now
api.restoreSessionBackup(); // restore from .bak
api.stopSessionGuard(); // stop the timer
QQ 发送广播
限速多行广播.
const result = await api.sendBroadcast(
"Hello everyone!",
["THREAD_1", "THREAD_2", "THREAD_3"],
{
delay: 2000,
parallel: 2,
onEach: (err, info, id) => {
console.log(err ? "Failed: " + id : "Sent: " + id);
}
}
);
console.log(result.sent.length + "/" + result.total + " delivered");
QQ 邮箱
Discord.js/Telegraf风格高档博特类.
const { createMessengerBot } = require("@eryxenx/fca");
const bot = await createMessengerBot(
{ appState: require("./account.json") },
{ commandPrefix: "/", stopOnSignals: true }
);
bot.command("ping", async ctx => await ctx.replyAsync("pong 🏓"));
bot.hears(/hello/i, async ctx => await ctx.replyAsync("Hi! 👋"));
bot.on("messageCreate", event => console.log(event.body));
await bot.launch({ stopOnSignals: true });
QQ 创建 FcaClient
命名空格将所有API方法按域分组.
const { createFcaClient } = require("@eryxenx/fca");
const client = createFcaClient(api);
await client.messages.send("Hello!", threadID);
await client.messages.react("❤️", messageID, threadID);
await client.threads.getInfo(threadID);
await client.users.getInfo(userID);
await client.account.refreshDtsg();
API 参考
发送信件
api.sendMessage("Hello!", threadID);
api.sendMessage({ body: "Photo!", attachment: fs.createReadStream("photo.jpg") }, threadID);
api.sendMessage({ body: "Hey @John", mentions: [{ id: "uid", tag: "@John", fromIndex: 4 }] }, threadID);
api.sendMessage({ sticker: "369239263222822" }, threadID);
api.sendMessage({ location: { latitude: 23.8, longitude: 90.4, current: true } }, threadID);
api.sendBroadcast("msg", ["tid1", "tid2"], { delay: 2000 });
api.sendGif("https://media.giphy.com/xyz.gif", threadID);
api.sendLocation(23.8, 90.4, threadID);
api.sendImage("./photo.jpg", threadID, "caption");
api.sendVideo("./video.mp4", threadID);
api.sendAudio("./voice.ogg", threadID);
api.sendFile("./doc.pdf", threadID);
api.shareLink("https://github.com", threadID, "Check this!");
api.shareContact("Meet my friend!", userID, threadID);
信件动作
api.editMessage("Updated text", messageID);
api.unsendMessage(messageID);
api.deleteMessage([messageID]);
api.setMessageReaction("😍", messageID, threadID); // threadID optional
api.setMessageReaction("", messageID); // remove reaction
api.getMessage(threadID, messageID);
api.forwardAttachment(attachmentID, [userID]);
api.uploadAttachment([fs.createReadStream("photo.jpg")]);
读取收据并打字
api.markAsRead(threadID);
api.markAsReadAll();
api.markAsDelivered(threadID, messageID);
api.markAsSeen();
api.sendTypingIndicator(threadID, true);
线索管理
api.getThreadInfo(threadID);
api.getThreadList(10, null, ["INBOX"]);
api.getThreadHistory(threadID, 20);
api.createGroup("Hey!", ["uid1", "uid2"]);
api.deleteThread(threadID);
api.muteThread(threadID, 3600);
api.changeArchivedStatus(threadID, true);
api.handleMessageRequest(threadID, true);
api.searchForThread("query");
线索自定义
api.setTitle("New Name", threadID);
api.changeThreadColor("#0084FF", threadID);
api.changeThreadEmoji("🔥", threadID);
api.changeNickname("The Boss", threadID, userID);
api.changeGroupImage(fs.createReadStream("group.jpg"), threadID);
api.changeAdminStatus(threadID, userID, true);
api.addUserToGroup(userID, threadID);
api.removeUserFromGroup(userID, threadID);
api.createPoll("Question?", threadID, { "Yes": false, "No": false });
api.pinMessage(messageID, threadID);
api.unpinMessage(messageID, threadID);
用户信息
api.getUserInfo(userID);
api.getUserID("John Doe", callback);
api.getUID("https://facebook.com/zuck");
api.getFriendsList();
api.getAvatarUser(userID);
api.getProfileInfo(userID);
api.getPublicData(userID);
api.sendFriendRequest(userID);
api.handleFriendRequest(userID, true);
api.changeBlockedStatus(userID, true);
api.followUser(userID);
api.unfollowUser(userID);
api.unfriend(userID);
社会
api.reactToPost(postID, "love");
api.reactToComment(commentID, "haha");
api.postComment(postID, "Great post!");
api.sharePost(postID, "Check this!");
账户配置( C)
api.getCurrentUserID();
api.getAppState();
api.setOptions({ listenTyping: true });
api.logout();
api.refreshFb_dtsg();
api.addExternalModule("myFunc", (defaultFuncs, api, ctx) => {
return function(text, threadID) {
return api.sendMessage("[BOT] " + text, threadID);
};
});
HTTP 公用事业
api.httpGet(url, params, callback);
api.httpPost(url, form, callback);
api.httpPostFormData(url, form, callback);
api.uploadImageToImgbb(imageUrl);
QQ 登录选项
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
selfListen | 布尔 | 虚假 | 接收您自己发送的信件 |
listenEvents | 布尔 | 真实 | 接收线索/ 组事件 |
listenTyping | 布尔 | 虚假 | 接收打入指标事件 |
updatePresence | 布尔 | 虚假 | 接收在线/离线存在活动 |
autoMarkDelivery | 布尔 | 虚假 | 自动标记已发送的信件 |
autoMarkRead | 布尔 | 虚假 | 自动标记线索为已读 |
autoReconnect | 布尔 | 真实 | 断开时自动重接 MQTT |
online | 布尔 | 虚假 | 外表与他人在线 |
emitReady | 布尔 | 虚假 | MQTT 连接时发送备忘事件 |
proxy | 字符串 | —— 说 | HTTP 代理服务器 URL |
userAgent | 字符串 | 萨法里大学 | 覆盖 HTTP 用户代理 |
许可证
MIT 许可证
@ eryxenx/ fca (英语) 以 EryXenX(穆罕默德·阿卡什)
E2EE本土媒体引擎(
src/api/socket/e2ee/native/捆绑 a 预编译二进制建自 毛发走 编号 : mautrix-meta 变相器,图里尔 Asokan和捐助者,根据 MPL - 2.0 导弹 (不是麻省理工学院). 见src/api/socket/e2ee/native/NOTICE.md——本通知 必须保留在这个分叉的任何再分配中. NEXCA MQTT 核心通过 德库 - 麻省理工学院许可证
禁止未经批准擅自复制或再分配无信用.
由 EryXenX 制作