onebots 0.4.25 → 0.4.27
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 -0
- package/lib/adapters/qq/bot.d.ts +0 -2
- package/lib/adapters/qq/bot.js +1 -0
- package/lib/adapters/qq/elements.d.ts +7 -2
- package/lib/adapters/qq/index.d.ts +2 -7
- package/lib/adapters/qq/index.js +4 -2
- package/lib/adapters/qq/message.d.ts +4 -3
- package/lib/adapters/qq/message.js +90 -68
- package/lib/adapters/qq/qqBot.d.ts +1 -1
- package/lib/adapters/qq/qqBot.js +17 -7
- package/lib/adapters/qq/sessionManager.js +5 -6
- package/lib/config.sample.yaml +13 -1
- package/lib/service/V11/index.js +1 -0
- package/lib/service/V12/action/guild.d.ts +13 -11
- package/lib/service/V12/action/guild.js +5 -1
- package/package.json +3 -3
package/README.md
CHANGED
package/lib/adapters/qq/bot.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { QQAdapter } from "../../adapters/qq";
|
|
2
2
|
import { AxiosInstance } from "axios";
|
|
3
3
|
import { WebSocket } from "ws";
|
|
4
|
-
import { SessionManager } from "../../adapters/qq/sessionManager";
|
|
5
4
|
import { OneBot } from "../../onebot";
|
|
6
5
|
import { QQBot } from "../../adapters/qq/qqBot";
|
|
7
6
|
export declare class Bot extends QQBot {
|
|
@@ -12,7 +11,6 @@ export declare class Bot extends QQBot {
|
|
|
12
11
|
nickname: string;
|
|
13
12
|
status: number;
|
|
14
13
|
ws: WebSocket;
|
|
15
|
-
sessionManager: SessionManager;
|
|
16
14
|
constructor(oneBot: OneBot, appId: string, config: QQAdapter.Config['protocol']);
|
|
17
15
|
init(): Promise<void>;
|
|
18
16
|
stop(): void;
|
package/lib/adapters/qq/bot.js
CHANGED
|
@@ -87,6 +87,9 @@ export interface MessageElemMap {
|
|
|
87
87
|
res_id?: string;
|
|
88
88
|
data: string | Record<string, any>;
|
|
89
89
|
};
|
|
90
|
+
node: {
|
|
91
|
+
message: Sendable;
|
|
92
|
+
};
|
|
90
93
|
markdown: {
|
|
91
94
|
content: string;
|
|
92
95
|
};
|
|
@@ -105,7 +108,8 @@ export interface MessageElemMap {
|
|
|
105
108
|
export type MessageElemType = keyof MessageElemMap;
|
|
106
109
|
export type MessageElem<T extends MessageElemType = MessageElemType> = {
|
|
107
110
|
type: T;
|
|
108
|
-
|
|
111
|
+
data: MessageElemMap[T];
|
|
112
|
+
};
|
|
109
113
|
export type TextElem = MessageElem<"text">;
|
|
110
114
|
export type AtElem = MessageElem<"at">;
|
|
111
115
|
export type FaceElem = MessageElem<"face">;
|
|
@@ -116,10 +120,11 @@ export type LinkElem = MessageElem<'link'>;
|
|
|
116
120
|
export type XmlElem = MessageElem<"xml">;
|
|
117
121
|
export type JsonElem = MessageElem<"json">;
|
|
118
122
|
export type MDElem = MessageElem<'markdown'>;
|
|
123
|
+
export type NodeElem = MessageElem<"node">;
|
|
119
124
|
export type MusicElem = MessageElem<"music">;
|
|
120
125
|
export type ButtonElem = MessageElem<'button'>;
|
|
121
126
|
export type ReplyElem = MessageElem<"reply">;
|
|
122
127
|
type RepeatableCombineElem = TextElem | FaceElem | ImageElem | AtElem | ButtonElem;
|
|
123
128
|
type WithReply<T extends MessageElem> = T | [T] | [ReplyElem, T] | [ReplyElem, ...RepeatableCombineElem[]];
|
|
124
|
-
export type Sendable = string | RepeatableCombineElem | (RepeatableCombineElem | string)[] | WithReply<MDElem | LinkElem | VideoElem | AudioElem | XmlElem | MusicElem | JsonElem>;
|
|
129
|
+
export type Sendable = string | RepeatableCombineElem | (RepeatableCombineElem | string)[] | WithReply<MDElem | NodeElem | LinkElem | VideoElem | AudioElem | XmlElem | MusicElem | JsonElem>;
|
|
125
130
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Adapter } from "../../adapter";
|
|
2
2
|
import { App } from "../../server/app";
|
|
3
3
|
import { OneBot } from "../../onebot";
|
|
4
|
+
import { QQBot } from "../../adapters/qq/qqBot";
|
|
4
5
|
export default class QQAdapter extends Adapter<'qq'> {
|
|
5
6
|
#private;
|
|
6
7
|
constructor(app: App, config: QQAdapter.Config);
|
|
@@ -24,12 +25,6 @@ declare module '../../adapter' {
|
|
|
24
25
|
}
|
|
25
26
|
export declare namespace QQAdapter {
|
|
26
27
|
interface Config extends Adapter.Config<'qq'> {
|
|
27
|
-
protocol:
|
|
28
|
-
secret: string;
|
|
29
|
-
token: string;
|
|
30
|
-
sandbox?: boolean;
|
|
31
|
-
maxRetry?: number;
|
|
32
|
-
intents?: string[];
|
|
33
|
-
};
|
|
28
|
+
protocol: Omit<QQBot.Config, 'appid'>;
|
|
34
29
|
}
|
|
35
30
|
}
|
package/lib/adapters/qq/index.js
CHANGED
|
@@ -117,13 +117,13 @@ class QQAdapter extends adapter_1.Adapter {
|
|
|
117
117
|
if (value instanceof Array)
|
|
118
118
|
return `${key}=${value.map(v => JSON.stringify(v)).join(',')}`;
|
|
119
119
|
// is String
|
|
120
|
-
return `${key}=${item
|
|
120
|
+
return `${key}=${item[key]}`;
|
|
121
121
|
});
|
|
122
122
|
return `[CQ:${item.type},${dataStr.join(',')}]`;
|
|
123
123
|
}).join('');
|
|
124
124
|
}
|
|
125
125
|
formatEventPayload(version, event, data) {
|
|
126
|
-
|
|
126
|
+
const result = {
|
|
127
127
|
id: data.id,
|
|
128
128
|
type: event,
|
|
129
129
|
version: version,
|
|
@@ -135,6 +135,8 @@ class QQAdapter extends adapter_1.Adapter {
|
|
|
135
135
|
platform: 'qq',
|
|
136
136
|
...data,
|
|
137
137
|
};
|
|
138
|
+
delete data.bot;
|
|
139
|
+
return result;
|
|
138
140
|
}
|
|
139
141
|
async start(uin) {
|
|
140
142
|
const startOneBots = [...this.oneBots.values()].filter(oneBot => {
|
|
@@ -5,11 +5,12 @@ import { Bot } from "./bot";
|
|
|
5
5
|
export declare class Message {
|
|
6
6
|
bot: Bot;
|
|
7
7
|
sub_type: Message.SubType;
|
|
8
|
-
|
|
8
|
+
self_id: string;
|
|
9
9
|
guild_id?: string;
|
|
10
10
|
channel_id?: string;
|
|
11
11
|
group_id?: string;
|
|
12
12
|
message_id: string;
|
|
13
|
+
seq: number;
|
|
13
14
|
sender: Message.Sender;
|
|
14
15
|
user_id: string;
|
|
15
16
|
constructor(bot: Bot, attrs: Partial<Message>);
|
|
@@ -46,7 +47,7 @@ export declare class GroupMessageEvent extends Message implements MessageEvent {
|
|
|
46
47
|
}
|
|
47
48
|
export declare class DirectMessageEvent extends Message implements MessageEvent {
|
|
48
49
|
user_id: string;
|
|
49
|
-
|
|
50
|
+
guild_id: string;
|
|
50
51
|
constructor(bot: Bot, payload: Partial<Message>);
|
|
51
52
|
reply(message: Sendable): Promise<{
|
|
52
53
|
message_id: string;
|
|
@@ -71,7 +72,7 @@ export declare namespace Message {
|
|
|
71
72
|
user_id: string;
|
|
72
73
|
user_name: string;
|
|
73
74
|
}
|
|
74
|
-
type SubType =
|
|
75
|
+
type SubType = "private" | "group" | "guild" | "direct";
|
|
75
76
|
function parse(this: QQBot, payload: Dict): (string | MessageElem[])[];
|
|
76
77
|
function format(this: QQBot, message: Sendable, source?: Quotable): Promise<{
|
|
77
78
|
messages: Dict;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GuildMessageEvent = exports.DirectMessageEvent = exports.GroupMessageEvent = exports.PrivateMessageEvent = exports.Message = void 0;
|
|
4
|
-
const qqBot_1 = require("./qqBot");
|
|
5
4
|
const utils_1 = require("./utils");
|
|
6
5
|
const crypto_1 = require("crypto");
|
|
6
|
+
const bot_1 = require("./bot");
|
|
7
7
|
class Message {
|
|
8
|
-
get self_id() {
|
|
9
|
-
return this.bot.self_id;
|
|
10
|
-
}
|
|
11
8
|
constructor(bot, attrs) {
|
|
12
9
|
this.bot = bot;
|
|
13
10
|
Object.assign(this, attrs);
|
|
11
|
+
this.self_id = bot.self_id;
|
|
12
|
+
this.seq = attrs.seq || (0, crypto_1.randomInt)(1000000);
|
|
14
13
|
}
|
|
15
14
|
get [Symbol.unscopables]() {
|
|
16
15
|
return {
|
|
@@ -20,7 +19,8 @@ class Message {
|
|
|
20
19
|
toJSON() {
|
|
21
20
|
return Object.fromEntries(Object.keys(this)
|
|
22
21
|
.filter(key => {
|
|
23
|
-
|
|
22
|
+
console.log(key, typeof this[key]);
|
|
23
|
+
return typeof this[key] !== "function" && !(this[key] instanceof bot_1.Bot);
|
|
24
24
|
})
|
|
25
25
|
.map(key => [key, this[key]]));
|
|
26
26
|
}
|
|
@@ -29,7 +29,7 @@ exports.Message = Message;
|
|
|
29
29
|
class PrivateMessageEvent extends Message {
|
|
30
30
|
constructor(bot, payload) {
|
|
31
31
|
super(bot, payload);
|
|
32
|
-
this.sub_type =
|
|
32
|
+
this.sub_type = "private";
|
|
33
33
|
}
|
|
34
34
|
async reply(message) {
|
|
35
35
|
return this.bot.sendPrivateMessage(this.user_id, message, this);
|
|
@@ -39,7 +39,7 @@ exports.PrivateMessageEvent = PrivateMessageEvent;
|
|
|
39
39
|
class GroupMessageEvent extends Message {
|
|
40
40
|
constructor(bot, payload) {
|
|
41
41
|
super(bot, payload);
|
|
42
|
-
this.sub_type =
|
|
42
|
+
this.sub_type = "group";
|
|
43
43
|
}
|
|
44
44
|
async reply(message) {
|
|
45
45
|
return this.bot.sendGroupMessage(this.group_id, message, this);
|
|
@@ -49,7 +49,7 @@ exports.GroupMessageEvent = GroupMessageEvent;
|
|
|
49
49
|
class DirectMessageEvent extends Message {
|
|
50
50
|
constructor(bot, payload) {
|
|
51
51
|
super(bot, payload);
|
|
52
|
-
this.sub_type =
|
|
52
|
+
this.sub_type = "direct";
|
|
53
53
|
}
|
|
54
54
|
reply(message) {
|
|
55
55
|
return this.bot.sendDirectMessage(this.guild_id, message, this);
|
|
@@ -59,7 +59,7 @@ exports.DirectMessageEvent = DirectMessageEvent;
|
|
|
59
59
|
class GuildMessageEvent extends Message {
|
|
60
60
|
constructor(bot, payload) {
|
|
61
61
|
super(bot, payload);
|
|
62
|
-
this.sub_type =
|
|
62
|
+
this.sub_type = "guild";
|
|
63
63
|
}
|
|
64
64
|
async asAnnounce() {
|
|
65
65
|
return this.bot.setChannelAnnounce(this.guild_id, this.channel_id, this.message_id);
|
|
@@ -74,9 +74,9 @@ class GuildMessageEvent extends Message {
|
|
|
74
74
|
exports.GuildMessageEvent = GuildMessageEvent;
|
|
75
75
|
(function (Message) {
|
|
76
76
|
function parse(payload) {
|
|
77
|
-
let template = payload.content ||
|
|
77
|
+
let template = payload.content || "";
|
|
78
78
|
let result = [];
|
|
79
|
-
let brief =
|
|
79
|
+
let brief = "";
|
|
80
80
|
// 1. 处理文字表情混排
|
|
81
81
|
const regex = /("[^"]*?"|'[^']*?'|`[^`]*?`|“[^”]*?”|‘[^’]*?’|<[^>]+?>)/;
|
|
82
82
|
while (template.length) {
|
|
@@ -87,48 +87,61 @@ exports.GuildMessageEvent = GuildMessageEvent;
|
|
|
87
87
|
const prevText = template.slice(0, index);
|
|
88
88
|
if (prevText) {
|
|
89
89
|
result.push({
|
|
90
|
-
type:
|
|
91
|
-
|
|
90
|
+
type: "text",
|
|
91
|
+
data: {
|
|
92
|
+
text: prevText
|
|
93
|
+
}
|
|
92
94
|
});
|
|
93
95
|
brief += prevText;
|
|
94
96
|
}
|
|
95
97
|
template = template.slice(index + match.length);
|
|
96
|
-
if (match.startsWith(
|
|
97
|
-
let [type, ...attrs] = match.slice(1, -1).split(
|
|
98
|
-
if (type.startsWith(
|
|
99
|
-
type =
|
|
100
|
-
attrs = attrs.map((attr) => attr.replace(
|
|
98
|
+
if (match.startsWith("<")) {
|
|
99
|
+
let [type, ...attrs] = match.slice(1, -1).split(",");
|
|
100
|
+
if (type.startsWith("faceType")) {
|
|
101
|
+
type = "face";
|
|
102
|
+
attrs = attrs.map((attr) => attr.replace("faceId", "id"));
|
|
101
103
|
}
|
|
102
|
-
else if (type.startsWith(
|
|
103
|
-
if (type.startsWith(
|
|
104
|
+
else if (type.startsWith("@")) {
|
|
105
|
+
if (type.startsWith("@!")) {
|
|
104
106
|
const id = type.slice(2);
|
|
105
|
-
type =
|
|
107
|
+
type = "at";
|
|
106
108
|
attrs = Object.entries(payload.mentions.find((u) => u.id === id) || {})
|
|
107
109
|
.map(([key, value]) => `${key}=${value}`);
|
|
108
110
|
}
|
|
109
|
-
else if (type ===
|
|
110
|
-
type =
|
|
111
|
-
attrs = [[
|
|
111
|
+
else if (type === "@everyone") {
|
|
112
|
+
type = "at";
|
|
113
|
+
attrs = [["all", true]];
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
116
|
else if (/^[a-z]+:[0-9]+$/.test(type)) {
|
|
115
|
-
attrs = [[
|
|
116
|
-
type =
|
|
117
|
+
attrs = [["id", type.split(":")[1]]];
|
|
118
|
+
type = "face";
|
|
117
119
|
}
|
|
118
120
|
result.push({
|
|
119
121
|
type,
|
|
120
|
-
|
|
121
|
-
const [key, ...values] = attr.split(
|
|
122
|
-
return [key.toLowerCase(), (0, utils_1.trimQuote)(values.join(
|
|
122
|
+
data: Object.fromEntries(attrs.map((attr) => {
|
|
123
|
+
const [key, ...values] = attr.split("=");
|
|
124
|
+
return [key.toLowerCase(), (0, utils_1.trimQuote)(values.join("="))];
|
|
123
125
|
}))
|
|
124
126
|
});
|
|
125
|
-
brief += `<${type}:${attrs.join(
|
|
127
|
+
brief += `<${type}:${attrs.join(",")}>`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
result.push({
|
|
131
|
+
type: "text",
|
|
132
|
+
data: {
|
|
133
|
+
text: match
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
brief += match;
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
if (template) {
|
|
129
140
|
result.push({
|
|
130
|
-
type:
|
|
131
|
-
|
|
141
|
+
type: "text",
|
|
142
|
+
data: {
|
|
143
|
+
text: template
|
|
144
|
+
}
|
|
132
145
|
});
|
|
133
146
|
brief += template;
|
|
134
147
|
}
|
|
@@ -136,14 +149,14 @@ exports.GuildMessageEvent = GuildMessageEvent;
|
|
|
136
149
|
if (payload.attachments) {
|
|
137
150
|
for (const attachment of payload.attachments) {
|
|
138
151
|
let { content_type, ...data } = attachment;
|
|
139
|
-
const [type] = content_type.split(
|
|
152
|
+
const [type] = content_type.split("/");
|
|
140
153
|
result.push({
|
|
141
154
|
type,
|
|
142
155
|
...data,
|
|
143
156
|
src: data.src || data.url,
|
|
144
157
|
url: data.url || data.src
|
|
145
158
|
});
|
|
146
|
-
brief += `<$${type},${Object.entries(data).map(([key, value]) => `${key}=${value}`).join(
|
|
159
|
+
brief += `<$${type},${Object.entries(data).map(([key, value]) => `${key}=${value}`).join(",")}>`;
|
|
147
160
|
}
|
|
148
161
|
}
|
|
149
162
|
delete payload.attachments;
|
|
@@ -153,12 +166,12 @@ exports.GuildMessageEvent = GuildMessageEvent;
|
|
|
153
166
|
Message.parse = parse;
|
|
154
167
|
async function format(message, source = {}) {
|
|
155
168
|
const getType = (type) => {
|
|
156
|
-
return [
|
|
169
|
+
return ["image", "video", "audio"].indexOf(type) + 1;
|
|
157
170
|
};
|
|
158
|
-
let brief =
|
|
171
|
+
let brief = "";
|
|
159
172
|
const messages = {
|
|
160
173
|
msg_type: 0,
|
|
161
|
-
content:
|
|
174
|
+
content: "",
|
|
162
175
|
msg_id: source?.message_id,
|
|
163
176
|
msg_seq: (0, crypto_1.randomInt)(1, 1000000),
|
|
164
177
|
timestamp: Number((Date.now() / 1000).toFixed(0))
|
|
@@ -172,74 +185,83 @@ exports.GuildMessageEvent = GuildMessageEvent;
|
|
|
172
185
|
if (!Array.isArray(message))
|
|
173
186
|
message = [message];
|
|
174
187
|
for (let elem of message) {
|
|
175
|
-
if (typeof elem ===
|
|
176
|
-
elem = { type:
|
|
188
|
+
if (typeof elem === "string") {
|
|
189
|
+
elem = { type: "text", data: { text: elem } };
|
|
177
190
|
}
|
|
178
191
|
switch (elem.type) {
|
|
179
|
-
case
|
|
180
|
-
messages.msg_id = elem.message_id;
|
|
181
|
-
files.msg_id = elem.message_id;
|
|
182
|
-
brief += `<$reply,message_id=${elem.message_id}>`;
|
|
192
|
+
case "reply":
|
|
193
|
+
messages.msg_id = elem.data.message_id;
|
|
194
|
+
files.msg_id = elem.data.message_id;
|
|
195
|
+
brief += `<$reply,message_id=${elem.data.message_id}>`;
|
|
183
196
|
break;
|
|
184
197
|
case "at":
|
|
185
198
|
if (messages.content) {
|
|
186
|
-
messages.content += `<@${elem.id ||
|
|
199
|
+
messages.content += `<@${elem.data.id || "everyone"}>`;
|
|
187
200
|
}
|
|
188
201
|
else {
|
|
189
|
-
messages.content = `<@${elem.id ||
|
|
202
|
+
messages.content = `<@${elem.data.id || "everyone"}>`;
|
|
190
203
|
}
|
|
191
|
-
brief += `<$at,user=${elem.id ||
|
|
204
|
+
brief += `<$at,user=${elem.data.id || "everyone"}>`;
|
|
192
205
|
break;
|
|
193
|
-
case
|
|
206
|
+
case "link":
|
|
194
207
|
if (messages.content) {
|
|
195
|
-
messages.content += `<#${elem.channel_id}>`;
|
|
208
|
+
messages.content += `<#${elem.data.channel_id}>`;
|
|
196
209
|
}
|
|
197
210
|
else {
|
|
198
|
-
messages.content = `<#${elem.channel_id}>`;
|
|
211
|
+
messages.content = `<#${elem.data.channel_id}>`;
|
|
199
212
|
}
|
|
200
|
-
brief += `<$link,channel=${elem.channel_id}>`;
|
|
213
|
+
brief += `<$link,channel=${elem.data.channel_id}>`;
|
|
201
214
|
break;
|
|
202
|
-
case
|
|
215
|
+
case "text":
|
|
203
216
|
if (messages.content) {
|
|
204
|
-
messages.content += elem.text;
|
|
217
|
+
messages.content += elem.data.text;
|
|
205
218
|
}
|
|
206
219
|
else {
|
|
207
|
-
messages.content = elem.text;
|
|
220
|
+
messages.content = elem.data.text;
|
|
208
221
|
}
|
|
209
222
|
hasMessages = true;
|
|
210
|
-
brief += elem.text;
|
|
223
|
+
brief += elem.data.text;
|
|
211
224
|
break;
|
|
212
|
-
case
|
|
225
|
+
case "face":
|
|
213
226
|
if (messages.content) {
|
|
214
|
-
messages.content += `<emoji:${elem.id}>`;
|
|
227
|
+
messages.content += `<emoji:${elem.data.id}>`;
|
|
215
228
|
}
|
|
216
229
|
else {
|
|
217
|
-
messages.content = `<emoji:${elem.id}>`;
|
|
230
|
+
messages.content = `<emoji:${elem.data.id}>`;
|
|
218
231
|
}
|
|
219
|
-
brief += `<$face,id=${elem.id}>`;
|
|
232
|
+
brief += `<$face,id=${elem.data.id}>`;
|
|
220
233
|
hasMessages = true;
|
|
221
234
|
break;
|
|
222
|
-
case
|
|
223
|
-
|
|
224
|
-
|
|
235
|
+
case "node":
|
|
236
|
+
const { messages: m, hasFiles: hf, hasMessages: hm, brief: b, files: f } = await format.call(this, elem.data.message);
|
|
237
|
+
messages.content += m.content;
|
|
238
|
+
messages.msg_id = messages.msg_id || m.msg_id;
|
|
239
|
+
hasMessages = hasMessages || hm;
|
|
240
|
+
hasFiles = hasFiles || hf;
|
|
241
|
+
brief += b;
|
|
242
|
+
Object.assign(files, f);
|
|
243
|
+
break;
|
|
244
|
+
case "image":
|
|
245
|
+
case "audio":
|
|
246
|
+
case "video":
|
|
225
247
|
files.file_type = getType(elem.type);
|
|
226
|
-
files.content =
|
|
227
|
-
files.url = elem.file;
|
|
248
|
+
files.content = "file";
|
|
249
|
+
files.url = elem.data.file;
|
|
228
250
|
files.event_id = source.event_id;
|
|
229
251
|
files.msg_id = source?.message_id;
|
|
230
252
|
files.srv_send_msg = true;
|
|
231
253
|
hasFiles = true;
|
|
232
|
-
brief += `<${elem.type},file=${elem.file}>`;
|
|
254
|
+
brief += `<${elem.type},file=${elem.data.file}>`;
|
|
233
255
|
break;
|
|
234
|
-
case
|
|
256
|
+
case "markdown":
|
|
235
257
|
messages.markdown = {
|
|
236
|
-
content: elem.content
|
|
258
|
+
content: elem.data.content
|
|
237
259
|
};
|
|
238
260
|
messages.msg_type = 2;
|
|
239
261
|
hasMessages = true;
|
|
240
|
-
brief += `<#markdown,content=${elem.content}>`;
|
|
262
|
+
brief += `<#markdown,content=${elem.data.content}>`;
|
|
241
263
|
break;
|
|
242
|
-
case
|
|
264
|
+
case "button":
|
|
243
265
|
buttons.push(elem.data);
|
|
244
266
|
brief += `<$button,data=${JSON.stringify(elem.data)}>`;
|
|
245
267
|
break;
|
|
@@ -21,7 +21,7 @@ export declare class QQBot extends EventEmitter {
|
|
|
21
21
|
sessionManager: SessionManager;
|
|
22
22
|
constructor(config: QQBot.Config);
|
|
23
23
|
removeAt(payload: Dict): void;
|
|
24
|
-
processPayload(event_id: string, event: string, payload: Dict):
|
|
24
|
+
processPayload(event_id: string, event: string, payload: Dict): Dict | PrivateMessageEvent | GroupMessageEvent | DirectMessageEvent | GuildMessageEvent;
|
|
25
25
|
getSelfInfo(): Promise<any>;
|
|
26
26
|
getChannelPermissionOfRole(channel_id: string, role_id: string): Promise<any>;
|
|
27
27
|
setChannelAnnounce(guild_id: string, channel_id: string, message_id: string): Promise<any>;
|
package/lib/adapters/qq/qqBot.js
CHANGED
|
@@ -88,7 +88,9 @@ class QQBot extends events_1.EventEmitter {
|
|
|
88
88
|
raw_message: brief,
|
|
89
89
|
sender: {
|
|
90
90
|
user_id: payload.author?.id,
|
|
91
|
-
|
|
91
|
+
nickname: payload.author?.name || '',
|
|
92
|
+
user_openid: payload.author?.user_openid || payload.author?.member_openid,
|
|
93
|
+
...(payload.author || {})
|
|
92
94
|
},
|
|
93
95
|
timestamp: new Date(payload.timestamp).getTime() / 1000,
|
|
94
96
|
});
|
|
@@ -250,14 +252,16 @@ class QQBot extends events_1.EventEmitter {
|
|
|
250
252
|
if (!res.data?.length)
|
|
251
253
|
return [];
|
|
252
254
|
const result = (res.data || []).map(g => {
|
|
253
|
-
const { joined_at, ...guild } = g;
|
|
255
|
+
const { id: guild_id, name: guild_name, joined_at, ...guild } = g;
|
|
254
256
|
return {
|
|
257
|
+
guild_id,
|
|
258
|
+
guild_name,
|
|
255
259
|
join_time: new Date(joined_at).getTime() / 1000,
|
|
256
260
|
...guild
|
|
257
261
|
};
|
|
258
262
|
});
|
|
259
263
|
const last = result[result.length - 1];
|
|
260
|
-
return [...result, ...await _getGuildList(last.
|
|
264
|
+
return [...result, ...await _getGuildList(last.guild_id)];
|
|
261
265
|
};
|
|
262
266
|
return await _getGuildList();
|
|
263
267
|
}
|
|
@@ -272,16 +276,17 @@ class QQBot extends events_1.EventEmitter {
|
|
|
272
276
|
if (!res.data?.length)
|
|
273
277
|
return [];
|
|
274
278
|
const result = (res.data || []).map(m => {
|
|
275
|
-
const { id: member_id, role, join_time, ...member } = m;
|
|
279
|
+
const { id: member_id, name: member_name, role, join_time, ...member } = m;
|
|
276
280
|
return {
|
|
277
281
|
member_id,
|
|
282
|
+
member_name,
|
|
278
283
|
role,
|
|
279
284
|
join_time: new Date(join_time).getTime() / 1000,
|
|
280
285
|
...member
|
|
281
286
|
};
|
|
282
287
|
});
|
|
283
288
|
const last = result[result.length - 1];
|
|
284
|
-
return [...result, ...await _getGuildMemberList(last.
|
|
289
|
+
return [...result, ...await _getGuildMemberList(last.member_id)];
|
|
285
290
|
};
|
|
286
291
|
return await _getGuildMemberList();
|
|
287
292
|
}
|
|
@@ -307,7 +312,13 @@ class QQBot extends events_1.EventEmitter {
|
|
|
307
312
|
}
|
|
308
313
|
async getChannelList(guild_id) {
|
|
309
314
|
const { data: result = [] } = await this.request.get(`/guilds/${guild_id}/channels`);
|
|
310
|
-
return result
|
|
315
|
+
return result.map(({ id: channel_id, name: channel_name, ...channel }) => {
|
|
316
|
+
return {
|
|
317
|
+
channel_id,
|
|
318
|
+
channel_name,
|
|
319
|
+
...channel
|
|
320
|
+
};
|
|
321
|
+
});
|
|
311
322
|
}
|
|
312
323
|
async sendPrivateMessage(user_id, message, source) {
|
|
313
324
|
const { hasMessages, messages, brief, hasFiles, files } = await message_1.Message.format.call(this, message, source);
|
|
@@ -379,7 +390,6 @@ class QQBot extends events_1.EventEmitter {
|
|
|
379
390
|
let message_id = '';
|
|
380
391
|
if (hasMessages) {
|
|
381
392
|
const { data: result } = await this.request.post(`/v2/groups/${group_id}/messages`, messages);
|
|
382
|
-
console.log(result);
|
|
383
393
|
message_id = result.seq;
|
|
384
394
|
}
|
|
385
395
|
if (hasFiles) {
|
|
@@ -167,11 +167,9 @@ class SessionManager extends events_1.EventEmitter {
|
|
|
167
167
|
this.sendWs(authOp);
|
|
168
168
|
}
|
|
169
169
|
startListen() {
|
|
170
|
-
this.bot.ws.on("open", () => {
|
|
171
|
-
this.bot.logger.info("[CLIENT] 连接成功");
|
|
172
|
-
});
|
|
173
170
|
this.bot.ws.on("close", (code) => {
|
|
174
|
-
this.
|
|
171
|
+
this.alive = false;
|
|
172
|
+
this.bot.logger.mark(`[CLIENT] 连接关闭:${code}`);
|
|
175
173
|
this.emit(constans_1.SessionEvents.EVENT_WS, {
|
|
176
174
|
eventType: constans_1.SessionEvents.DISCONNECT,
|
|
177
175
|
code,
|
|
@@ -186,7 +184,8 @@ class SessionManager extends events_1.EventEmitter {
|
|
|
186
184
|
}
|
|
187
185
|
});
|
|
188
186
|
this.bot.ws.on("error", (e) => {
|
|
189
|
-
this.
|
|
187
|
+
this.alive = false;
|
|
188
|
+
this.bot.logger.mark("[CLIENT] 连接错误");
|
|
190
189
|
this.emit(constans_1.SessionEvents.CLOSED, { eventType: constans_1.SessionEvents.CLOSED });
|
|
191
190
|
});
|
|
192
191
|
this.bot.ws.on("message", (data) => {
|
|
@@ -203,7 +202,7 @@ class SessionManager extends events_1.EventEmitter {
|
|
|
203
202
|
}
|
|
204
203
|
// 鉴权通过
|
|
205
204
|
if (wsRes.t === constans_1.SessionEvents.READY) {
|
|
206
|
-
this.bot.logger.
|
|
205
|
+
this.bot.logger.mark(`[CLIENT] 鉴权通过`);
|
|
207
206
|
const { d, s } = wsRes;
|
|
208
207
|
const { session_id, user = {} } = d;
|
|
209
208
|
this.bot.self_id = user.id;
|
package/lib/config.sample.yaml
CHANGED
|
@@ -40,5 +40,17 @@ qq.a: # `${适配器名称}:${账号}`
|
|
|
40
40
|
- version: V11
|
|
41
41
|
# 。。。其他配置项参见上方对应oneBot版本的通用配置
|
|
42
42
|
protocol: # 将会覆盖通用配置中的protocol
|
|
43
|
-
|
|
43
|
+
token: '' # qq机器人token
|
|
44
|
+
secret: '' # qq机器人secret
|
|
45
|
+
sandbox: false # 是否沙箱环境
|
|
46
|
+
intents: # 需要监听的intents
|
|
47
|
+
- 'GROUP_AT_MESSAGE_CREATE' # 群聊@事件 没有群聊权限请注释
|
|
48
|
+
- 'C2C_MESSAGE_CREATE' # 私聊事件 没有私聊权限请注释
|
|
49
|
+
- 'DIRECT_MESSAGE' # 频道私信事件
|
|
50
|
+
# - 'GUILD_MESSAGES' # 私域机器人频道消息事件,公域机器人请注释
|
|
51
|
+
- 'GUILDS' # 频道变更事件
|
|
52
|
+
- 'GUILD_MEMBERS' # 频道成员变更事件
|
|
53
|
+
- 'GUILD_MESSAGE_REACTIONS' # 频道消息表态事件
|
|
54
|
+
- 'INTERACTION' # 互动事件
|
|
55
|
+
- 'PUBLIC_GUILD_MESSAGES' # 公域机器人频道消息事件,私域机器人请注释
|
|
44
56
|
# 。。。其他配置项参见上方对应oneBot版本的通用配置
|
package/lib/service/V11/index.js
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import { V12 } from "../../../service/V12";
|
|
2
|
-
import {
|
|
3
|
-
import { Channel } from "../../../adapters/qq/entries/channel";
|
|
4
|
-
import { Guild } from "../../../adapters/qq/entries/guild";
|
|
2
|
+
import { Dict } from "@zhinjs/shared";
|
|
5
3
|
export declare class GuildAction {
|
|
6
4
|
getGuildSelfInfo(this: V12): Promise<any>;
|
|
7
5
|
getChannelPermissionOfRole(this: V12, channel_id: string, role_id: string): Promise<any>;
|
|
8
6
|
setChannelAnnounce(this: V12, guild_id: string, channel_id: string, message_id: string): Promise<any>;
|
|
9
|
-
updateChannelPermissionOfRole(this: V12, channel_id: string, role_id: string, permission:
|
|
7
|
+
updateChannelPermissionOfRole(this: V12, channel_id: string, role_id: string, permission: Dict): Promise<any>;
|
|
10
8
|
getChannelMemberPermission(this: V12, channel_id: string, member_id: string): Promise<any>;
|
|
11
|
-
updateChannelMemberPermission(this: V12, channel_id: string, member_id: string, permission:
|
|
9
|
+
updateChannelMemberPermission(this: V12, channel_id: string, member_id: string, permission: Dict): Promise<any>;
|
|
12
10
|
getChannelPins(this: V12, channel_id: string): Promise<string[]>;
|
|
13
11
|
pinChannelMessage(this: V12, channel_id: string, message_id: string): Promise<any>;
|
|
14
12
|
unPinChannelMessage(this: V12, channel_id: string, message_id: string): Promise<any>;
|
|
15
|
-
createChannel(this: V12, guild_id: string, channelInfo:
|
|
13
|
+
createChannel(this: V12, guild_id: string, channelInfo: Dict): Promise<any>;
|
|
16
14
|
updateChannel(this: V12, { channel_id, ...updateInfo }: {
|
|
17
15
|
channel_id: string;
|
|
18
|
-
} &
|
|
16
|
+
} & Dict): Promise<any>;
|
|
19
17
|
deleteChannel(this: V12, channel_id: string): Promise<any>;
|
|
20
18
|
getGuildRoles(this: V12, guild_id: string): Promise<any>;
|
|
21
|
-
creatGuildRole(this: V12, guild_id: string, role:
|
|
22
|
-
updateGuildRole(this: V12, guild_id: string, { id, ...role }:
|
|
19
|
+
creatGuildRole(this: V12, guild_id: string, role: Dict): Promise<any>;
|
|
20
|
+
updateGuildRole(this: V12, guild_id: string, { id, ...role }: {
|
|
21
|
+
[x: string]: any;
|
|
22
|
+
id: any;
|
|
23
|
+
}): Promise<any>;
|
|
23
24
|
deleteGuildRole(this: V12, role_id: string): Promise<any>;
|
|
24
25
|
getGuildAccessApis(this: V12, guild_id: string): Promise<any>;
|
|
25
|
-
applyGuildAccess(this: V12, guild_id: string, channel_id: string, apiInfo:
|
|
26
|
+
applyGuildAccess(this: V12, guild_id: string, channel_id: string, apiInfo: Dict, desc?: string): Promise<any>;
|
|
26
27
|
unMuteGuild(this: V12, guild_id: string): Promise<any>;
|
|
27
28
|
muteGuild(this: V12, guild_id: string, seconds: number, end_time?: number): Promise<any>;
|
|
28
29
|
unMuteGuildMembers(this: V12, guild_id: string, member_ids: string[]): Promise<any>;
|
|
@@ -39,10 +40,11 @@ export declare class GuildAction {
|
|
|
39
40
|
getGuildMemberList(this: V12, guild_id: string): Promise<any>;
|
|
40
41
|
/**
|
|
41
42
|
* 发送频道消息
|
|
43
|
+
* @param guild_id {string} 频道id
|
|
42
44
|
* @param channel_id {string} 子频道id
|
|
43
45
|
* @param message {import('icqq/lib/service').Sendable} 消息
|
|
44
46
|
*/
|
|
45
|
-
sendGuildMsg(this: V12, channel_id: string, message: V12.Sendable): Promise<any>;
|
|
47
|
+
sendGuildMsg(this: V12, guild_id: string, channel_id: string, message: V12.Sendable): Promise<any>;
|
|
46
48
|
createDirectSession(this: V12, guild_id: string, user_id: string): Promise<any>;
|
|
47
49
|
sendDirectMsg(this: V12, guild_id: string, message: V12.Sendable): Promise<any>;
|
|
48
50
|
}
|
|
@@ -100,10 +100,14 @@ class GuildAction {
|
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
102
|
* 发送频道消息
|
|
103
|
+
* @param guild_id {string} 频道id
|
|
103
104
|
* @param channel_id {string} 子频道id
|
|
104
105
|
* @param message {import('icqq/lib/service').Sendable} 消息
|
|
105
106
|
*/
|
|
106
|
-
async sendGuildMsg(channel_id, message) {
|
|
107
|
+
async sendGuildMsg(guild_id, channel_id, message) {
|
|
108
|
+
if (channel_id === 'direct') {
|
|
109
|
+
return this.adapter.call(this.oneBot.uin, 'V12', 'sendDirectMessage', [guild_id, message]);
|
|
110
|
+
}
|
|
107
111
|
return this.adapter.call(this.oneBot.uin, 'V12', 'sendGuildMessage', [channel_id, message]);
|
|
108
112
|
}
|
|
109
113
|
async createDirectSession(guild_id, user_id) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "onebots",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"description": "基于icqq的多例oneBot实现",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=16"
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"/**/LICENSE"
|
|
57
57
|
],
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"icqq": "latest"
|
|
59
|
+
"icqq": "latest",
|
|
60
|
+
"sqlite3": "^5.1.6"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
63
|
"@koa/router": "^10.1.1",
|
|
@@ -69,7 +70,6 @@
|
|
|
69
70
|
"mime-types": "^2.1.35",
|
|
70
71
|
"reflect-metadata": "^0.1.13",
|
|
71
72
|
"seed-random": "^2.2.0",
|
|
72
|
-
"sqlite3": "^5.1.6",
|
|
73
73
|
"typeorm": "^0.3.17",
|
|
74
74
|
"ws": "^8.8.0"
|
|
75
75
|
}
|