onebots 0.4.36 → 0.4.38
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 +15 -4
- package/dist/assets/index-Lg7SiZ8I.js +2 -0
- package/dist/assets/index-Q4D7Uqbk.css +1 -0
- package/dist/index.html +2 -10
- package/lib/adapter.d.ts +19 -1
- package/lib/adapter.js +19 -0
- package/lib/adapters/dingtalk/index.d.ts +42 -0
- package/lib/adapters/dingtalk/index.js +249 -0
- package/lib/adapters/dingtalk/utils.d.ts +10 -0
- package/lib/adapters/dingtalk/utils.js +68 -0
- package/lib/adapters/icqq/index.d.ts +3 -1
- package/lib/adapters/icqq/index.js +34 -6
- package/lib/adapters/qq/index.d.ts +6 -4
- package/lib/adapters/qq/index.js +56 -9
- package/lib/adapters/qq/utils.d.ts +0 -2
- package/lib/adapters/qq/utils.js +1 -19
- package/lib/config.sample.yaml +8 -0
- package/lib/onebot.d.ts +13 -2
- package/lib/onebot.js +14 -0
- package/lib/server/app.d.ts +22 -2
- package/lib/server/app.js +45 -22
- package/lib/service/V11/index.d.ts +2 -2
- package/lib/service/V12/action/group.d.ts +1 -1
- package/lib/service/V12/action/group.js +1 -1
- package/lib/service/V12/index.d.ts +2 -2
- package/package.json +10 -4
- package/dist/assets/index--Ry7B0Uf.js +0 -2
- package/dist/assets/index-RYQFvMzH.css +0 -1
- package/lib/adapters/qq/bot.d.ts +0 -22
- package/lib/adapters/qq/bot.js +0 -21
- package/lib/adapters/qq/constans.d.ts +0 -69
- package/lib/adapters/qq/constans.js +0 -128
- package/lib/adapters/qq/elements.d.ts +0 -131
- package/lib/adapters/qq/elements.js +0 -8
- package/lib/adapters/qq/entries/channel.d.ts +0 -17
- package/lib/adapters/qq/entries/channel.js +0 -2
- package/lib/adapters/qq/entries/friend.d.ts +0 -8
- package/lib/adapters/qq/entries/friend.js +0 -2
- package/lib/adapters/qq/entries/group.d.ts +0 -6
- package/lib/adapters/qq/entries/group.js +0 -2
- package/lib/adapters/qq/entries/groupMember.d.ts +0 -7
- package/lib/adapters/qq/entries/groupMember.js +0 -2
- package/lib/adapters/qq/entries/guild.d.ts +0 -21
- package/lib/adapters/qq/entries/guild.js +0 -2
- package/lib/adapters/qq/entries/guildMember.d.ts +0 -9
- package/lib/adapters/qq/entries/guildMember.js +0 -2
- package/lib/adapters/qq/entries/user.d.ts +0 -9
- package/lib/adapters/qq/entries/user.js +0 -2
- package/lib/adapters/qq/event.d.ts +0 -28
- package/lib/adapters/qq/event.js +0 -24
- package/lib/adapters/qq/message.d.ts +0 -84
- package/lib/adapters/qq/message.js +0 -294
- package/lib/adapters/qq/qqBot.d.ts +0 -122
- package/lib/adapters/qq/qqBot.js +0 -448
- package/lib/adapters/qq/sessionManager.d.ts +0 -33
- package/lib/adapters/qq/sessionManager.js +0 -256
- package/lib/adapters/qq/types.d.ts +0 -45
- package/lib/adapters/qq/types.js +0 -2
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SessionManager = exports.MAX_RETRY = void 0;
|
|
7
|
-
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
const ws_1 = require("ws");
|
|
9
|
-
const utils_1 = require("./utils");
|
|
10
|
-
const events_1 = require("events");
|
|
11
|
-
const constans_1 = require("./constans");
|
|
12
|
-
exports.MAX_RETRY = 10;
|
|
13
|
-
class SessionManager extends events_1.EventEmitter {
|
|
14
|
-
get token() {
|
|
15
|
-
return this.bot.config.token;
|
|
16
|
-
}
|
|
17
|
-
constructor(bot) {
|
|
18
|
-
super();
|
|
19
|
-
this.bot = bot;
|
|
20
|
-
this.retry = 0;
|
|
21
|
-
this.sessionRecord = {
|
|
22
|
-
sessionID: "",
|
|
23
|
-
seq: 0
|
|
24
|
-
};
|
|
25
|
-
this.heartbeatParam = {
|
|
26
|
-
op: constans_1.OpCode.HEARTBEAT,
|
|
27
|
-
d: null // 心跳唯一值
|
|
28
|
-
};
|
|
29
|
-
this.on(constans_1.SessionEvents.EVENT_WS, (data) => {
|
|
30
|
-
switch (data.eventType) {
|
|
31
|
-
case constans_1.SessionEvents.RECONNECT:
|
|
32
|
-
this.bot.logger.mark("[CLIENT] 等待断线重连中...");
|
|
33
|
-
break;
|
|
34
|
-
case constans_1.SessionEvents.DISCONNECT:
|
|
35
|
-
if (this.retry < (this.bot.config.maxRetry || exports.MAX_RETRY)) {
|
|
36
|
-
this.bot.logger.mark("[CLIENT] 重新连接中,尝试次数:", this.retry + 1);
|
|
37
|
-
if (constans_1.WebsocketCloseReason.find((v) => v.code === data.code)?.resume) {
|
|
38
|
-
this.sessionRecord = data.eventMsg;
|
|
39
|
-
}
|
|
40
|
-
this.isReconnect = true;
|
|
41
|
-
this.start();
|
|
42
|
-
this.retry += 1;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
this.bot.logger.mark("[CLIENT] 超过重试次数,连接终止");
|
|
46
|
-
this.emit(constans_1.SessionEvents.DEAD, {
|
|
47
|
-
eventType: constans_1.SessionEvents.ERROR,
|
|
48
|
-
msg: "连接已死亡,请检查网络或重启"
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
break;
|
|
52
|
-
case constans_1.SessionEvents.READY:
|
|
53
|
-
this.bot.logger.mark("[CLIENT] 连接成功");
|
|
54
|
-
this.retry = 0;
|
|
55
|
-
break;
|
|
56
|
-
default:
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
async getAccessToken() {
|
|
61
|
-
let { secret, appid } = this.bot.config;
|
|
62
|
-
const getToken = () => {
|
|
63
|
-
return new Promise((resolve, reject) => {
|
|
64
|
-
axios_1.default.post("https://bots.qq.com/app/getAppAccessToken", {
|
|
65
|
-
appId: appid,
|
|
66
|
-
clientSecret: secret
|
|
67
|
-
}).then(res => {
|
|
68
|
-
if (res.status === 200 && res.data && typeof res.data === "object") {
|
|
69
|
-
resolve(res.data);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
reject(res);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
};
|
|
77
|
-
const getNext = async (next_time) => {
|
|
78
|
-
return new Promise(resolve => {
|
|
79
|
-
setTimeout(async () => {
|
|
80
|
-
const token = await getToken();
|
|
81
|
-
this.bot.logger.debug("getAccessToken", token);
|
|
82
|
-
this.access_token = token.access_token;
|
|
83
|
-
getNext(token.expires_in - 1).catch(() => getNext(0));
|
|
84
|
-
resolve(token);
|
|
85
|
-
}, next_time * 1000);
|
|
86
|
-
});
|
|
87
|
-
};
|
|
88
|
-
return getNext(0);
|
|
89
|
-
}
|
|
90
|
-
async getWsUrl() {
|
|
91
|
-
return new Promise((resolve) => {
|
|
92
|
-
this.bot.request.get("/gateway/bot", {
|
|
93
|
-
headers: {
|
|
94
|
-
Accept: "*/*",
|
|
95
|
-
"Accept-Encoding": "utf-8",
|
|
96
|
-
"Accept-Language": "zh-CN,zh;q=0.8",
|
|
97
|
-
Connection: "keep-alive",
|
|
98
|
-
"User-Agent": "v1",
|
|
99
|
-
Authorization: ""
|
|
100
|
-
}
|
|
101
|
-
}).then(res => {
|
|
102
|
-
if (!res.data)
|
|
103
|
-
throw new Error("获取ws连接信息异常");
|
|
104
|
-
this.wsUrl = res.data.url;
|
|
105
|
-
resolve();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
getValidIntends() {
|
|
110
|
-
return (this.bot.config.intents || []).reduce((result, item) => {
|
|
111
|
-
const value = constans_1.Intends[item];
|
|
112
|
-
if (value === undefined) {
|
|
113
|
-
this.bot.logger.warn(`Invalid intends(${item}),skip...`);
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
return constans_1.Intends[item] | result;
|
|
117
|
-
}, 0);
|
|
118
|
-
}
|
|
119
|
-
async start() {
|
|
120
|
-
await this.getAccessToken();
|
|
121
|
-
await this.getWsUrl();
|
|
122
|
-
this.connect();
|
|
123
|
-
this.startListen();
|
|
124
|
-
}
|
|
125
|
-
connect() {
|
|
126
|
-
this.bot.ws = new ws_1.WebSocket(this.wsUrl, {
|
|
127
|
-
headers: {
|
|
128
|
-
"Authorization": "QQBot " + this.access_token,
|
|
129
|
-
"X-Union-Appid": this.bot.config.appid
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
reconnectWs() {
|
|
134
|
-
const reconnectParam = {
|
|
135
|
-
op: constans_1.OpCode.RESUME,
|
|
136
|
-
d: {
|
|
137
|
-
// token: `Bot ${this.bot.appId}${this.token}`,
|
|
138
|
-
token: `QQBot ${this.access_token}`,
|
|
139
|
-
session_id: this.sessionRecord.sessionID,
|
|
140
|
-
seq: this.sessionRecord.seq
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
this.sendWs(reconnectParam);
|
|
144
|
-
}
|
|
145
|
-
// 发送websocket
|
|
146
|
-
sendWs(msg) {
|
|
147
|
-
try {
|
|
148
|
-
// 先将消息转为字符串
|
|
149
|
-
this.bot.ws.send(typeof msg === "string" ? msg : JSON.stringify(msg));
|
|
150
|
-
}
|
|
151
|
-
catch (e) {
|
|
152
|
-
this.bot.logger.error(e);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
authWs() {
|
|
156
|
-
// 鉴权参数
|
|
157
|
-
const authOp = {
|
|
158
|
-
op: constans_1.OpCode.IDENTIFY, // 鉴权参数
|
|
159
|
-
d: {
|
|
160
|
-
// token: `Bot ${this.bot.appId}${this.token}`,
|
|
161
|
-
token: `QQBot ${this.access_token}`, // 根据配置转换token
|
|
162
|
-
intents: this.getValidIntends(), // todo 接受的类型
|
|
163
|
-
shard: [0, 1] // 分片信息,给一个默认值
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
// 发送鉴权请求
|
|
167
|
-
this.sendWs(authOp);
|
|
168
|
-
}
|
|
169
|
-
startListen() {
|
|
170
|
-
this.bot.ws.on("close", (code) => {
|
|
171
|
-
this.alive = false;
|
|
172
|
-
this.bot.logger.mark(`[CLIENT] 连接关闭:${code}`);
|
|
173
|
-
this.emit(constans_1.SessionEvents.EVENT_WS, {
|
|
174
|
-
eventType: constans_1.SessionEvents.DISCONNECT,
|
|
175
|
-
code,
|
|
176
|
-
eventMsg: this.sessionRecord
|
|
177
|
-
});
|
|
178
|
-
if (code) {
|
|
179
|
-
constans_1.WebsocketCloseReason.forEach((e) => {
|
|
180
|
-
if (e.code === code) {
|
|
181
|
-
this.emit(constans_1.SessionEvents.ERROR, e.reason);
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
this.bot.ws.on("error", (e) => {
|
|
187
|
-
this.alive = false;
|
|
188
|
-
this.bot.logger.mark("[CLIENT] 连接错误");
|
|
189
|
-
this.emit(constans_1.SessionEvents.CLOSED, { eventType: constans_1.SessionEvents.CLOSED });
|
|
190
|
-
});
|
|
191
|
-
this.bot.ws.on("message", (data) => {
|
|
192
|
-
this.bot.logger.debug(`[CLIENT] 收到消息: ${data}`);
|
|
193
|
-
// 先将消息解析
|
|
194
|
-
const wsRes = (0, utils_1.toObject)(data);
|
|
195
|
-
// 先判断websocket连接是否成功
|
|
196
|
-
if (wsRes?.op === constans_1.OpCode.HELLO && wsRes?.d?.heartbeat_interval) {
|
|
197
|
-
// websocket连接成功,拿到心跳周期
|
|
198
|
-
this.heartbeatInterval = wsRes?.d?.heartbeat_interval;
|
|
199
|
-
// 非断线重连时,需要鉴权
|
|
200
|
-
this.isReconnect ? this.reconnectWs() : this.authWs();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
// 鉴权通过
|
|
204
|
-
if (wsRes.t === constans_1.SessionEvents.READY) {
|
|
205
|
-
this.bot.logger.mark(`[CLIENT] 鉴权通过`);
|
|
206
|
-
const { d, s } = wsRes;
|
|
207
|
-
const { session_id, user = {} } = d;
|
|
208
|
-
this.bot.self_id = user.id;
|
|
209
|
-
this.bot.nickname = user.username;
|
|
210
|
-
this.bot.status = user.status || 0;
|
|
211
|
-
// 获取当前会话参数
|
|
212
|
-
if (session_id && s) {
|
|
213
|
-
this.sessionRecord.sessionID = session_id;
|
|
214
|
-
this.sessionRecord.seq = s;
|
|
215
|
-
this.heartbeatParam.d = s;
|
|
216
|
-
}
|
|
217
|
-
this.bot.logger.info(`connect to ${user.username}(${user.id})`);
|
|
218
|
-
this.isReconnect = false;
|
|
219
|
-
this.emit(constans_1.SessionEvents.READY, { eventType: constans_1.SessionEvents.READY, msg: d || "" });
|
|
220
|
-
// 第一次发送心跳
|
|
221
|
-
this.bot.logger.debug(`[CLIENT] 发送第一次心跳`, this.heartbeatParam);
|
|
222
|
-
this.sendWs(this.heartbeatParam);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
// 心跳测试
|
|
226
|
-
if (wsRes.op === constans_1.OpCode.HEARTBEAT_ACK || wsRes.t === constans_1.SessionEvents.RESUMED) {
|
|
227
|
-
if (!this.alive) {
|
|
228
|
-
this.alive = true;
|
|
229
|
-
this.emit(constans_1.SessionEvents.EVENT_WS, { eventType: constans_1.SessionEvents.READY });
|
|
230
|
-
}
|
|
231
|
-
this.bot.logger.debug("[CLIENT] 心跳校验", this.heartbeatParam);
|
|
232
|
-
setTimeout(() => {
|
|
233
|
-
this.sendWs(this.heartbeatParam);
|
|
234
|
-
}, this.heartbeatInterval);
|
|
235
|
-
}
|
|
236
|
-
// 收到服务端重连的通知
|
|
237
|
-
if (wsRes.op === constans_1.OpCode.RECONNECT) {
|
|
238
|
-
// 通知会话,当前已断线
|
|
239
|
-
this.emit(constans_1.SessionEvents.EVENT_WS, { eventType: constans_1.SessionEvents.RECONNECT });
|
|
240
|
-
}
|
|
241
|
-
// 服务端主动推送的消息
|
|
242
|
-
if (wsRes.op === constans_1.OpCode.DISPATCH) {
|
|
243
|
-
// 更新心跳唯一值
|
|
244
|
-
const { s } = wsRes;
|
|
245
|
-
if (s)
|
|
246
|
-
this.sessionRecord.seq = this.heartbeatParam.d = s;
|
|
247
|
-
// OpenAPI事件分发
|
|
248
|
-
this.bot.dispatchEvent(wsRes.t, wsRes);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
this.on(constans_1.SessionEvents.ERROR, (e) => {
|
|
252
|
-
this.bot.logger.error(`[CLIENT] 发生错误:${e}`);
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
exports.SessionManager = SessionManager;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { ChannelSubType, ChannelType, PrivateType, SpeakPermission } from "./constans";
|
|
2
|
-
export type Dict<T = any> = Record<string, T>;
|
|
3
|
-
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "mark" | "off";
|
|
4
|
-
export interface wsResData {
|
|
5
|
-
op: number;
|
|
6
|
-
d?: {
|
|
7
|
-
heartbeat_interval?: number;
|
|
8
|
-
session_id?: string;
|
|
9
|
-
user?: {
|
|
10
|
-
id?: string;
|
|
11
|
-
username?: string;
|
|
12
|
-
bot?: boolean;
|
|
13
|
-
status?: number;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
s: number;
|
|
17
|
-
t: string;
|
|
18
|
-
id?: string;
|
|
19
|
-
}
|
|
20
|
-
export interface ChannelInfo {
|
|
21
|
-
id: string;
|
|
22
|
-
guild_id: string;
|
|
23
|
-
name: string;
|
|
24
|
-
type: ChannelType;
|
|
25
|
-
sub_type: ChannelSubType;
|
|
26
|
-
position: number;
|
|
27
|
-
parent_id?: string;
|
|
28
|
-
owner_id: string;
|
|
29
|
-
private_type: PrivateType;
|
|
30
|
-
speak_permission: SpeakPermission;
|
|
31
|
-
application_id?: string;
|
|
32
|
-
permissions?: string;
|
|
33
|
-
}
|
|
34
|
-
export type UpdatePermissionParams = {
|
|
35
|
-
add?: string;
|
|
36
|
-
remove?: string;
|
|
37
|
-
};
|
|
38
|
-
export type ApiBaseInfo = {
|
|
39
|
-
path: string;
|
|
40
|
-
method: "GET" | "POST" | "DELETE" | "PATCH" | "PUT";
|
|
41
|
-
};
|
|
42
|
-
export type RecommendInfo = {
|
|
43
|
-
channel_id: string;
|
|
44
|
-
introduce: string;
|
|
45
|
-
};
|
package/lib/adapters/qq/types.js
DELETED