@karinjs/adapter-qqbot 3.0.3 → 3.0.6
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/README.md +1 -11
- package/dist/apps/login.js +46 -42
- package/dist/index.js +6 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ pnpm add @karinjs/adapter-qqbot
|
|
|
12
12
|
|
|
13
13
|
## 配置
|
|
14
14
|
|
|
15
|
-
首次启动没有 QQBot 配置时,使用**任意已连接的机器人**或在**控制台中**发送 `#
|
|
15
|
+
首次启动没有 QQBot 配置时,使用**任意已连接的机器人**或在**控制台中**发送 `#QQBot登录` 完成扫码授权。
|
|
16
16
|
|
|
17
17
|
也可以访问 Karin WebUI 可视化编辑 或者 手动编辑:`@karinjs-adapter-qqbot/config/config.json`。
|
|
18
18
|
|
|
@@ -22,18 +22,9 @@ pnpm add @karinjs/adapter-qqbot
|
|
|
22
22
|
"name": "我的机器人",
|
|
23
23
|
"appId": "1234567890",
|
|
24
24
|
"secret": "your-secret",
|
|
25
|
-
"sandbox": false,
|
|
26
25
|
"qqEnable": true,
|
|
27
26
|
"guildEnable": true,
|
|
28
27
|
"guildMode": 0,
|
|
29
|
-
"proxy": {
|
|
30
|
-
"prodApi": "https://api.sgroup.qq.com",
|
|
31
|
-
"sandboxApi": "https://sandbox.api.sgroup.qq.com",
|
|
32
|
-
"tokenApi": "https://bots.qq.com/app/getAppAccessToken",
|
|
33
|
-
"prodWs": "wss://api.sgroup.qq.com/websocket/",
|
|
34
|
-
"sandboxWs": "wss://sandbox.api.sgroup.qq.com/websocket/"
|
|
35
|
-
},
|
|
36
|
-
"keyboard": { "enable": true },
|
|
37
28
|
"markdown": { "enable": true },
|
|
38
29
|
"event": { "type": 2 }
|
|
39
30
|
}
|
|
@@ -42,7 +33,6 @@ pnpm add @karinjs/adapter-qqbot
|
|
|
42
33
|
|
|
43
34
|
- `event.type`: `0` 关闭、`1` Webhook、`2` WebSocket(默认)。
|
|
44
35
|
- `guildMode`: `0` 公域,只收 @ 消息;`1` 私域,接收全部频道消息。
|
|
45
|
-
- `proxy`: 自定义连接代理地址。`prodApi` / `sandboxApi` 作为 OpenAPI 根地址使用,后端拼接路径时会兼容末尾 `/`;`tokenApi` 是完整接口地址;`prodWs` / `sandboxWs` 是完整 WebSocket 网关地址,支持 `ws://` 和 `wss://`,路径和查询参数会按配置原样连接。
|
|
46
36
|
- `markdown.enable`: 是否让普通文本和图片自动合并为 Markdown 消息,默认开启。关闭后普通图片会改为单独上传发送;插件显式传入的 `segment.markdown` 不受此开关影响。
|
|
47
37
|
|
|
48
38
|
## 按钮
|
package/dist/apps/login.js
CHANGED
|
@@ -105,51 +105,55 @@ const PollBindResult = async (taskId, key) => {
|
|
|
105
105
|
//#region src/apps/login.ts
|
|
106
106
|
let busy = false;
|
|
107
107
|
const QQBotLogin = karin.command(/^#qqbot(登录|login)$/i, async (e) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
msg.push(segment.text(`\n${qrcode$1}`));
|
|
125
|
-
} else {
|
|
126
|
-
const qrcode$2 = await qrcode.toDataURL(url);
|
|
127
|
-
msg.push(segment.image(qrcode$2));
|
|
128
|
-
}
|
|
129
|
-
msg.push(segment.text(`或使用手机 QQ 打开链接登录: ${url}`));
|
|
130
|
-
await reply(msg);
|
|
131
|
-
const ok = await PollBindResult(task.taskId, task.aesKey);
|
|
132
|
-
msgIds.forEach(async (id) => {
|
|
133
|
-
await e.bot.recallMsg(e.contact, id).catch(() => {});
|
|
134
|
-
});
|
|
135
|
-
if (ok.status === 2) {
|
|
136
|
-
const list = config();
|
|
137
|
-
const idx = list.findIndex((item) => item.appId === ok.appId);
|
|
138
|
-
if (idx >= 0) {
|
|
139
|
-
list[idx].secret = ok.secret;
|
|
140
|
-
e.reply(`Bot存在,已更新[${ok.appId}]配置`, { reply: true });
|
|
141
|
-
} else {
|
|
142
|
-
const defaults = getDefaultConfig()[0];
|
|
143
|
-
list.push({
|
|
144
|
-
...defaults,
|
|
145
|
-
appId: ok.appId,
|
|
146
|
-
secret: ok.secret
|
|
108
|
+
try {
|
|
109
|
+
const msgIds = [];
|
|
110
|
+
const reply = async (elements) => {
|
|
111
|
+
const res = await e.reply(elements, { at: true });
|
|
112
|
+
msgIds.push(res.messageId);
|
|
113
|
+
};
|
|
114
|
+
if (busy) return await e.reply("已有扫码授权在进行中,请稍候再试", { reply: true });
|
|
115
|
+
busy = true;
|
|
116
|
+
await reply("注意: 确认登录后将刷新 QQBot 的 AppSecret,旧的 AppSecret 将失效");
|
|
117
|
+
const task = await createBindTask();
|
|
118
|
+
const url = buildConnectUrl(task.taskId);
|
|
119
|
+
const msg = [segment.text("请使用 QQ 扫码登录")];
|
|
120
|
+
if (e.bot.adapter.protocol === "console") {
|
|
121
|
+
const qrcode$1 = await qrcode.toString(url, {
|
|
122
|
+
type: "terminal",
|
|
123
|
+
small: true
|
|
147
124
|
});
|
|
148
|
-
|
|
125
|
+
msg.push(segment.text(`\n${qrcode$1}`));
|
|
126
|
+
} else {
|
|
127
|
+
const qrcode$2 = await qrcode.toDataURL(url);
|
|
128
|
+
msg.push(segment.image(qrcode$2));
|
|
129
|
+
}
|
|
130
|
+
msg.push(segment.text(`或使用手机 QQ 打开链接登录: ${url}`));
|
|
131
|
+
await reply(msg);
|
|
132
|
+
const ok = await PollBindResult(task.taskId, task.aesKey);
|
|
133
|
+
msgIds.forEach(async (id) => {
|
|
134
|
+
await e.bot.recallMsg(e.contact, id).catch(() => {});
|
|
135
|
+
});
|
|
136
|
+
if (ok.status === 2) {
|
|
137
|
+
const list = config();
|
|
138
|
+
const idx = list.findIndex((item) => item.appId === ok.appId);
|
|
139
|
+
if (idx >= 0) {
|
|
140
|
+
list[idx].secret = ok.secret;
|
|
141
|
+
e.reply(`Bot存在,已更新[${ok.appId}]配置`, { reply: true });
|
|
142
|
+
} else {
|
|
143
|
+
const defaults = getDefaultConfig()[0];
|
|
144
|
+
list.push({
|
|
145
|
+
...defaults,
|
|
146
|
+
appId: ok.appId,
|
|
147
|
+
secret: ok.secret
|
|
148
|
+
});
|
|
149
|
+
e.reply(`[${ok.appId}] 扫码登录成功`, { reply: true });
|
|
150
|
+
}
|
|
151
|
+
return;
|
|
149
152
|
}
|
|
150
|
-
return;
|
|
153
|
+
return await e.reply("二维码过期,请重新触发指令", { reply: true });
|
|
154
|
+
} finally {
|
|
155
|
+
busy = false;
|
|
151
156
|
}
|
|
152
|
-
return await e.reply("二维码过期,请重新触发指令", { reply: true });
|
|
153
157
|
}, {
|
|
154
158
|
perm: "master",
|
|
155
159
|
name: "QQBot 扫码登录"
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,6 @@ import { t as log } from "./logger-sza6kuy3.js";
|
|
|
3
3
|
import { i as random, n as fakeEvent, r as getImageSize, t as QQAPIBASEURL } from "./utils-QpIUJhxK.js";
|
|
4
4
|
import { t as getMessageStore } from "./message-CVJVFAGR.js";
|
|
5
5
|
import karin, { AdapterBase, app, buttonHandle, common, createDirectMessage, createFriendDecreaseNotice, createFriendIncreaseNotice, createFriendMessage, createGroupApplyRequest, createGroupInviteRequest, createGroupMemberAddNotice, createGroupMemberDelNotice, createGroupMessage, createGuildMessage, fileToUrl, fileToUrlHandlerKey, handler, karin as karin$1, karinToQQBot, logger, registerBot, segment, senderGroup, unregisterBot } from "node-karin";
|
|
6
|
-
import path from "path";
|
|
7
6
|
import { URL } from "url";
|
|
8
7
|
import lodash from "node-karin/lodash";
|
|
9
8
|
import { createReadStream } from "node:fs";
|
|
@@ -11,7 +10,7 @@ import FormData from "form-data";
|
|
|
11
10
|
import axios from "node-karin/axios";
|
|
12
11
|
import crypto from "node:crypto";
|
|
13
12
|
import { open, readFile, stat } from "node:fs/promises";
|
|
14
|
-
import path
|
|
13
|
+
import path from "node:path";
|
|
15
14
|
import { fileURLToPath as fileURLToPath$1 } from "node:url";
|
|
16
15
|
import os from "node:os";
|
|
17
16
|
import EventEmitter from "node:events";
|
|
@@ -688,7 +687,7 @@ const formatBytes = (bytes) => {
|
|
|
688
687
|
const normalizeUploadFileName = (type, name) => {
|
|
689
688
|
const value = name?.trim();
|
|
690
689
|
if (!value) return DEFAULT_FILENAME$1[type];
|
|
691
|
-
return path
|
|
690
|
+
return path.basename(value) || DEFAULT_FILENAME$1[type];
|
|
692
691
|
};
|
|
693
692
|
/**
|
|
694
693
|
* 检查 fallback 资源大小是否超过 QQ 对应类型上限。
|
|
@@ -774,7 +773,7 @@ const buildFallbackSource = async (type, source, fileName) => {
|
|
|
774
773
|
if (isLocalPathSource(value)) {
|
|
775
774
|
const file = normalizeLocalPath(value);
|
|
776
775
|
const info = await stat(file);
|
|
777
|
-
const name = normalizeUploadFileName(type, fileName || path
|
|
776
|
+
const name = normalizeUploadFileName(type, fileName || path.basename(file));
|
|
778
777
|
return {
|
|
779
778
|
kind: "local",
|
|
780
779
|
file,
|
|
@@ -1343,7 +1342,7 @@ const tokens = /* @__PURE__ */ new Map();
|
|
|
1343
1342
|
const getAccessToken = async (appId, secret) => {
|
|
1344
1343
|
let res;
|
|
1345
1344
|
try {
|
|
1346
|
-
const tokenurl =
|
|
1345
|
+
const tokenurl = `${QQAPIBASEURL}/app/getAppAccessToken`;
|
|
1347
1346
|
res = await axios.post(tokenurl, {
|
|
1348
1347
|
appId: String(appId),
|
|
1349
1348
|
clientSecret: secret
|
|
@@ -2151,7 +2150,7 @@ const buildGuildImageItem = async (source) => {
|
|
|
2151
2150
|
};
|
|
2152
2151
|
const resolveImageFilename = (source) => {
|
|
2153
2152
|
const file = source.split(/[?#]/)[0] || "";
|
|
2154
|
-
const name = path
|
|
2153
|
+
const name = path.basename(file);
|
|
2155
2154
|
return name.includes(".") ? name : "image.jpg";
|
|
2156
2155
|
};
|
|
2157
2156
|
const buildKeyboard = (grouping) => {
|
|
@@ -4456,7 +4455,7 @@ const fetchGateway = async (cfg) => {
|
|
|
4456
4455
|
return "wss://api.bot.qq.com/websocket";
|
|
4457
4456
|
}
|
|
4458
4457
|
try {
|
|
4459
|
-
const { data } = await axios.get(path
|
|
4458
|
+
const { data } = await axios.get(path.join(apiUrl, "gateway"), {
|
|
4460
4459
|
headers: {
|
|
4461
4460
|
Authorization: `QQBot ${accessToken}`,
|
|
4462
4461
|
"User-Agent": getUserAgent()
|