kook-client 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 凉菜
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # kook-client
2
+ [![CI](https://github.com/zhinjs/kook-client/actions/workflows/release.yaml/badge.svg?branch=master&event=push)](https://github.com/zhinjs/kook-client/actions/workflows/release.yaml)
3
+ [![Docs](https://github.com/zhinjs/kook-client/actions/workflows/docs.yaml/badge.svg?branch=master&event=push)](https://github.com/zhinjs/kook-client/actions/workflows/docs.yaml)
4
+ [![npm version](https://img.shields.io/npm/v/kook-client/latest.svg)](https://www.npmjs.com/package/kook-client)
5
+ [![qq group](https://img.shields.io/badge/group-446290761-blue?style=flat-square&labelColor=FAFAFA&logo=data:image/png;base64,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&logoColor=000000)](https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=rYaL-gcqTjWYqwBs9TDoVSXKu-i5ircB&authKey=TO02faBOpfhmfkw3YQuUCG2HxUEwWCuFdMBf5nSt3qyWD%2FqaO453O9Dx%2BK8JwBdM&noverify=0&group_code=446290761)
6
+ ## 安装依赖
7
+
8
+ ```shell
9
+ npm i kook-client # or yarn add kook-client
10
+ ```
11
+
12
+ ## 使用
13
+
14
+ ```js
15
+ const {Client} = require('kook-client')
16
+ // 创建机器人
17
+ const client = new Client({
18
+ logLevel:'info', // 日志等级
19
+ ignore:'bot', // 忽略消息配置,可选值为:bot|self
20
+ token:'', // 机器人秘钥
21
+ mode:'websocket' // 链接模式
22
+ })
23
+ // 启动机器人
24
+ client.connect()
25
+ ```
26
+
27
+ ## 发送消息
28
+ ```javascript
29
+ const {Client} = require('kook-client')
30
+ const client = new Client({
31
+ // ...
32
+ })
33
+ // 只有启动后,才能发送
34
+ client.connect().then(() => {
35
+ // 频道被动回复
36
+ client.on('message.channel', (e) => {
37
+ e.reply('hello world')
38
+ })
39
+ // 频道私信被动回复
40
+ client.on('message.private', (e) => {
41
+ e.reply('hello world')
42
+ })
43
+ // 主动发送频道消息
44
+ client.sendChannelMsg(channel_id, 'hello')
45
+ // 主动发送私聊消息
46
+ client.sendPrivateMsg(user_id, 'hello')
47
+ })
48
+ ```
49
+
50
+ ## API
51
+ 文档待更新
package/lib/client.js ADDED
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _Client_instances, _Client_initChannels, _Client_initUsers, _Client_initBlacklist;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Client = void 0;
10
+ exports.defineConfig = defineConfig;
11
+ exports.createClient = createClient;
12
+ const baseClient_1 = require("./core/baseClient");
13
+ const guild_1 = require("./entries/guild");
14
+ const channel_1 = require("./entries/channel");
15
+ const user_1 = require("./entries/user");
16
+ const guildMember_1 = require("./entries/guildMember");
17
+ const channelMember_1 = require("./entries/channelMember");
18
+ class Client extends baseClient_1.BaseClient {
19
+ constructor(config) {
20
+ super(Object.assign({}, Client.defaultConfig, config));
21
+ _Client_instances.add(this);
22
+ this.guilds = new Map();
23
+ this.blacklist = new Map();
24
+ this.channels = new Map();
25
+ this.guildMembers = new Map();
26
+ this.channelMembers = new Map();
27
+ this.users = new Map();
28
+ this.pickGuild = guild_1.Guild.as.bind(this);
29
+ this.pickGuildMember = guildMember_1.GuildMember.as.bind(this);
30
+ this.pickChannel = channel_1.Channel.as.bind(this);
31
+ this.pickChannelMember = channelMember_1.ChannelMember.as.bind(this);
32
+ this.pickUser = user_1.User.as.bind(this);
33
+ const nodeVersion = parseInt(process.version.slice(1));
34
+ if (nodeVersion < 16) {
35
+ this.logger.warn(`你的node版本(${process.version}) <16,可能会出现不可预测的错误,请升级node版本,为确保服务正常运行,请升级node版本`);
36
+ }
37
+ process.on("uncaughtException", e => {
38
+ this.logger.debug(e.stack);
39
+ });
40
+ }
41
+ get black_user_nums() {
42
+ return [...this.blacklist.values()].reduce((a, b) => a + b.size, 0);
43
+ }
44
+ async getSelfInfo() {
45
+ const { data } = await this.request.get('/v3/user/me');
46
+ return data;
47
+ }
48
+ async setOnline() {
49
+ const result = await this.request.post('/v3/user/online');
50
+ return result['code'] === 0;
51
+ }
52
+ async setOffline() {
53
+ const result = await this.request.post('/v3/user/offline');
54
+ return result['code'] === 0;
55
+ }
56
+ async getOnlineStatus() {
57
+ const { data } = await this.request.get('/v3/user/get-online-status');
58
+ return data;
59
+ }
60
+ /**
61
+ * 获取频道列表
62
+ */
63
+ async getGuildList() {
64
+ const _getGuildList = async (page = 1, page_size = 100) => {
65
+ const res = await this.request.get('/v3/guild/list', {
66
+ params: {
67
+ page,
68
+ page_size
69
+ }
70
+ }).catch(() => ({ data: { items: [] } })); // 私域不支持获取频道列表,做个兼容
71
+ if (!res.data.items?.length)
72
+ return [];
73
+ const result = res.data.items || [];
74
+ const { meta: { page_total } } = res.data;
75
+ if (page === page_total)
76
+ return result;
77
+ return [...result, ...await _getGuildList(page + 1)];
78
+ };
79
+ return await _getGuildList();
80
+ }
81
+ /**
82
+ * 获取频道信息
83
+ * @param guild_id
84
+ */
85
+ async getGuildInfo(guild_id) {
86
+ const { data } = await this.request.get(`/v3/guild/view`, {
87
+ params: { guild_id }
88
+ });
89
+ return data;
90
+ }
91
+ async getChannelList(guild_id) {
92
+ const _getChannelList = async (page = 1, page_size = 100) => {
93
+ const res = await this.request.get(`/v3/channel/list`, {
94
+ params: {
95
+ page,
96
+ page_size,
97
+ guild_id
98
+ }
99
+ }).catch(() => ({ data: { items: [] } })); // 公域没有权限,做个兼容
100
+ if (!res.data.items?.length)
101
+ return [];
102
+ const result = res.data.items || [];
103
+ if (page === res.data.meta.page_total)
104
+ return result;
105
+ return [...result, ...await _getChannelList(page + 1)];
106
+ };
107
+ return await _getChannelList();
108
+ }
109
+ /**
110
+ * 获取频道成员列表
111
+ * @param guild_id
112
+ * @param channel_id
113
+ */
114
+ async getGuildUserList(guild_id, channel_id) {
115
+ const _getGuildMemberList = async (page = 1, page_size = 100) => {
116
+ const res = await this.request.get(`/v3/guild/user-list`, {
117
+ params: {
118
+ page,
119
+ page_size,
120
+ guild_id,
121
+ channel_id
122
+ }
123
+ }).catch(() => ({ data: { items: [] } })); // 公域没有权限,做个兼容
124
+ if (!res.data.items?.length)
125
+ return [];
126
+ const result = res.data.items || [];
127
+ if (page === res.data.meta?.page_total)
128
+ return result;
129
+ return [...result, ...await _getGuildMemberList(page + 1)];
130
+ };
131
+ return await _getGuildMemberList();
132
+ }
133
+ async getBlacklist(guild_id) {
134
+ const { data: { items } } = await this.request.get('/v3/blacklist/list', {
135
+ params: {
136
+ guild_id
137
+ }
138
+ });
139
+ return items;
140
+ }
141
+ async sendPrivateMsg(user_id, message, quote) {
142
+ return this.pickUser(user_id).sendMsg(message, quote);
143
+ }
144
+ async sendChannelMsg(channel_id, message, quote) {
145
+ return this.pickChannel(channel_id).sendMsg(message, quote);
146
+ }
147
+ async getPrivateMsg(user_id, message_id) {
148
+ return this.pickUser(user_id).getMsg(message_id);
149
+ }
150
+ async getChannelMsg(channel_id, message_id) {
151
+ return this.pickChannel(channel_id).getMsg(message_id);
152
+ }
153
+ async recallPrivateMsg(user_id, message_id) {
154
+ return this.pickUser(user_id).recallMsg(message_id);
155
+ }
156
+ async recallChannelMsg(channel_id, message_is) {
157
+ return this.pickChannel(channel_id).recallMsg(message_is);
158
+ }
159
+ async getPrivateChatHistory(user_id, message_id, len = 50) {
160
+ return this.pickUser(user_id).getChatHistory(message_id, len);
161
+ }
162
+ async getChannelChatHistory(channel_id, message_id, len = 50) {
163
+ return this.pickChannel(channel_id).getChatHistory(message_id, len);
164
+ }
165
+ async init() {
166
+ const userInfo = await this.getSelfInfo();
167
+ this.self_id = userInfo.id;
168
+ this.nickname = userInfo.nickname;
169
+ this.logger.info(`welcome ${this.nickname}, 正在加载资源...`);
170
+ const guilds = await this.getGuildList();
171
+ for (const guildInfo of guilds) {
172
+ this.guilds.set(guildInfo.id, guildInfo);
173
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_initChannels).call(this, guildInfo.id);
174
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_initUsers).call(this, guildInfo.id);
175
+ await __classPrivateFieldGet(this, _Client_instances, "m", _Client_initBlacklist).call(this, guildInfo.id);
176
+ }
177
+ this.logger.info(`加载了${this.guilds.size}个服务器,共计${this.channels.size}个频道,${this.users.size}个用户,${this.blacklist.size}个黑名单用户`);
178
+ }
179
+ async connect() {
180
+ await this.receiver.connect();
181
+ return this.init();
182
+ }
183
+ async disconnect() {
184
+ await this.receiver.disconnect();
185
+ }
186
+ }
187
+ exports.Client = Client;
188
+ _Client_instances = new WeakSet(), _Client_initChannels = async function _Client_initChannels(guild_id) {
189
+ const channels = await this.getChannelList(guild_id);
190
+ for (const channel of channels) {
191
+ this.channelMembers.set(channel.id, new Map());
192
+ this.channels.set(channel.id, channel);
193
+ const channelMembers = await this.getGuildUserList(guild_id, channel.id);
194
+ for (const temp of channelMembers) {
195
+ const userInfo = this.users.get(temp.id) || temp;
196
+ this.channelMembers.get(channel.id)?.set(userInfo.id, userInfo);
197
+ }
198
+ }
199
+ }, _Client_initUsers = async function _Client_initUsers(guild_id) {
200
+ this.guildMembers.set(guild_id, new Map());
201
+ const users = await this.getGuildUserList(guild_id);
202
+ for (const temp of users) {
203
+ const user = this.users.get(temp.id) || temp;
204
+ this.guildMembers.get(guild_id)?.set(user.id, user);
205
+ this.users.set(user.id, user);
206
+ }
207
+ }, _Client_initBlacklist = async function _Client_initBlacklist(guild_id) {
208
+ this.blacklist.set(guild_id, new Map());
209
+ const blacklist = await this.getBlacklist(guild_id);
210
+ for (const temp of blacklist) {
211
+ this.blacklist.get(guild_id)?.set(temp.user_id, temp);
212
+ }
213
+ };
214
+ (function (Client) {
215
+ Client.defaultConfig = {};
216
+ })(Client || (exports.Client = Client = {}));
217
+ function defineConfig(config) {
218
+ return config;
219
+ }
220
+ function createClient(config) {
221
+ return new Client(config);
222
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotifyType = exports.ChannelType = exports.UnsupportedMethodError = exports.OpCode = void 0;
4
+ // 心跳参数
5
+ var OpCode;
6
+ (function (OpCode) {
7
+ OpCode[OpCode["Event"] = 0] = "Event";
8
+ OpCode[OpCode["Hello"] = 1] = "Hello";
9
+ OpCode[OpCode["Ping"] = 2] = "Ping";
10
+ OpCode[OpCode["Pong"] = 3] = "Pong";
11
+ OpCode[OpCode["Reconnect"] = 5] = "Reconnect";
12
+ OpCode[OpCode["ResumeAck"] = 6] = "ResumeAck";
13
+ })(OpCode || (exports.OpCode = OpCode = {}));
14
+ exports.UnsupportedMethodError = new Error('暂未支持');
15
+ var ChannelType;
16
+ (function (ChannelType) {
17
+ ChannelType["Channel"] = "GROUP";
18
+ ChannelType["Private"] = "PERSON";
19
+ ChannelType["Notice"] = "BROADCAST";
20
+ })(ChannelType || (exports.ChannelType = ChannelType = {}));
21
+ var NotifyType;
22
+ (function (NotifyType) {
23
+ NotifyType[NotifyType["Default"] = 0] = "Default";
24
+ NotifyType[NotifyType["All"] = 1] = "All";
25
+ NotifyType[NotifyType["At"] = 2] = "At";
26
+ NotifyType[NotifyType["Off"] = 3] = "Off";
27
+ })(NotifyType || (exports.NotifyType = NotifyType = {}));
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.BaseClient = void 0;
40
+ const axios_1 = __importDefault(require("axios"));
41
+ const form_data_1 = __importDefault(require("form-data"));
42
+ const log4js = __importStar(require("log4js"));
43
+ const events_1 = require("events");
44
+ const utils_1 = require("../utils");
45
+ const receiver_1 = require("../core/receiver");
46
+ class BaseClient extends events_1.EventEmitter {
47
+ constructor(config) {
48
+ var _a;
49
+ super();
50
+ this.processedEvents = new Set();
51
+ this.config = Object.assign({}, BaseClient.defaultConfig, config);
52
+ this.request = axios_1.default.create({
53
+ baseURL: 'https://www.kookapp.cn/api',
54
+ timeout: config.timeout || 5000,
55
+ headers: {
56
+ 'User-Agent': `NodeJSSDK/0.0.1`
57
+ }
58
+ });
59
+ this.request.interceptors.request.use((config) => {
60
+ config.headers['Authorization'] = `Bot ${this.config.token}`;
61
+ config.headers['Accept-Language'] = this.config.language;
62
+ if (config['rest']) {
63
+ const restObj = config['rest'];
64
+ delete config['rest'];
65
+ for (const key in restObj) {
66
+ config.url = config.url.replace(':' + key, restObj[key]);
67
+ }
68
+ }
69
+ if (config.headers['Content-Type'] === 'multipart/form-data') {
70
+ delete config.data.message_reference;
71
+ const formData = new form_data_1.default(); // 使用 form-data
72
+ for (const key in config.data) {
73
+ if (config.data[key] !== undefined) {
74
+ formData.append(key, config.data[key]); // 使用 append 而不是 set
75
+ }
76
+ }
77
+ config.data = formData;
78
+ }
79
+ return config;
80
+ });
81
+ this.request.interceptors.response.use((res) => res.data, (res) => {
82
+ if (!res || !res.response || !res.response.data)
83
+ return Promise.reject(res);
84
+ const { code = res?.response.status, message = res?.response.statusText } = res?.response?.data || {};
85
+ const err = new Error(`request "${res.config.url}" error with code(${code}): ${message}`);
86
+ return Promise.reject(err);
87
+ });
88
+ this.logger = log4js.getLogger(`[KOOK]`);
89
+ this.logger.level = (_a = this.config).logLevel || (_a.logLevel = 'info');
90
+ this.receiver = receiver_1.Receiver.create(config.mode, this, config);
91
+ this.logger.info(`using ${config.mode} mode`);
92
+ }
93
+ /**
94
+ * 上传多媒体文件
95
+ * @param data 文件数据:可以是本地文件(file://)或网络地址(http://)或base64或Buffer
96
+ * @returns 返回可直接访问的文件URL
97
+ */
98
+ async uploadMedia(data) {
99
+ const formData = new form_data_1.default();
100
+ const fileData = await (0, utils_1.getFile)(data);
101
+ // console.error(await getFile(data));
102
+ formData.append('file', fileData, 'awa.png'); // 显式指定文件名
103
+ try {
104
+ const response = await this.request.post(`/v3/asset/create`, formData, {
105
+ headers: {
106
+ ...formData.getHeaders(), // 自动设置 Content-Type
107
+ 'Accept': 'application/json',
108
+ },
109
+ });
110
+ // console.log("fileData结果:", fileData); // 调试日志
111
+ // console.log("Data结果:", data); // 调试日志
112
+ const url = response.data?.url;
113
+ if (!url) {
114
+ throw new Error(`Invalid response: ${JSON.stringify(response.data)}`);
115
+ }
116
+ return url;
117
+ }
118
+ catch (error) {
119
+ // console.error("Upload failed:", error.response?.data || error.message);
120
+ throw new Error(`Upload failed: ${error.message}`);
121
+ }
122
+ }
123
+ em(event, payload) {
124
+ // 添加消息去重逻辑 - 放在方法最前面
125
+ const eventId = payload.msg_id || payload.event_id;
126
+ if (eventId && this.processedEvents.has(eventId)) {
127
+ this.logger.debug(`Ignoring duplicate event: ${eventId}`);
128
+ return;
129
+ }
130
+ // 记录已处理事件
131
+ if (eventId)
132
+ this.processedEvents.add(eventId);
133
+ // 原始事件处理逻辑
134
+ const eventNames = event.split('.');
135
+ const [post_type, detail_type, ...sub_type] = eventNames;
136
+ Object.assign(payload, {
137
+ post_type,
138
+ [`${post_type}_type`]: detail_type,
139
+ sub_type: sub_type.join('.'),
140
+ ...payload
141
+ });
142
+ let prefix = '';
143
+ while (eventNames.length) {
144
+ let fullEventName = `${prefix}.${eventNames.shift()}`;
145
+ if (fullEventName.startsWith('.'))
146
+ fullEventName = fullEventName.slice(1);
147
+ this.emit(fullEventName, payload);
148
+ prefix = fullEventName;
149
+ }
150
+ }
151
+ }
152
+ exports.BaseClient = BaseClient;
153
+ (function (BaseClient) {
154
+ BaseClient.defaultConfig = {
155
+ ignore: 'bot'
156
+ };
157
+ function getFullTargetId(message) {
158
+ switch (message.message_type) {
159
+ case "private":
160
+ return `private-${message.author_id}`;
161
+ case "channel":
162
+ return `channel-${message.channel_id}:${message.author_id}`;
163
+ }
164
+ }
165
+ BaseClient.getFullTargetId = getFullTargetId;
166
+ })(BaseClient || (exports.BaseClient = BaseClient = {}));
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var _Receiver_instances, _Receiver_transformEvent, _Receiver_transformChannelEvent, _Receiver_transformPrivateEvent, _Receiver_transformNoticeEvent;
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Receiver = void 0;
10
+ const events_1 = require("events");
11
+ const crypto_1 = require("crypto");
12
+ const constans_1 = require("../constans");
13
+ const event_1 = require("../event");
14
+ class Receiver extends events_1.EventEmitter {
15
+ constructor(c) {
16
+ super();
17
+ _Receiver_instances.add(this);
18
+ this.c = c;
19
+ this.sn = 0;
20
+ this.buffer = [];
21
+ this.on("event", __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformEvent).bind(this));
22
+ }
23
+ reset() {
24
+ this.sn = 0;
25
+ this.buffer = [];
26
+ }
27
+ decryptData(data, key) {
28
+ if (!this.compress)
29
+ return data;
30
+ const decodeData = Buffer.from(data, 'base64');
31
+ const iv = decodeData.subarray(0, 16).toString('utf8');
32
+ const encryptedData = decodeData.subarray(16);
33
+ const finalKey = key.padEnd(32, '0');
34
+ const finalKeyBuf = Buffer.from(finalKey, 'utf8');
35
+ const finalIvBuf = Buffer.from(iv, 'utf8');
36
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-cbc', finalKeyBuf, finalIvBuf);
37
+ const decryptedData = decipher.update(encryptedData);
38
+ return decryptedData.toString('utf8') + decipher.final().toString('utf8');
39
+ }
40
+ }
41
+ exports.Receiver = Receiver;
42
+ _Receiver_instances = new WeakSet(), _Receiver_transformEvent = function _Receiver_transformEvent(event) {
43
+ switch (event.channel_type) {
44
+ case constans_1.ChannelType.Channel:
45
+ return __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformChannelEvent).call(this, event);
46
+ case constans_1.ChannelType.Private:
47
+ return __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformPrivateEvent).call(this, event);
48
+ case constans_1.ChannelType.Notice:
49
+ return __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformNoticeEvent).call(this, event);
50
+ default:
51
+ throw new Error(`unknown channel type ${event.channel_type}`);
52
+ }
53
+ }, _Receiver_transformChannelEvent = function _Receiver_transformChannelEvent(event) {
54
+ if (event.type === 255)
55
+ return __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformNoticeEvent).call(this, event);
56
+ if (event.extra?.author?.bot && this.c.config.ignore === 'bot')
57
+ return;
58
+ if (event.author_id === this.c.self_id && this.c.config.ignore === 'self')
59
+ return;
60
+ const messageEvent = new event_1.ChannelMessageEvent(this.c, event);
61
+ this.c.em('message.channel', messageEvent);
62
+ this.c.logger.info(`recv from Channel(${messageEvent.channel_id}): ${messageEvent.raw_message}`);
63
+ }, _Receiver_transformPrivateEvent = function _Receiver_transformPrivateEvent(event) {
64
+ if (event.type === 255)
65
+ return __classPrivateFieldGet(this, _Receiver_instances, "m", _Receiver_transformNoticeEvent).call(this, event);
66
+ if (event.extra?.author?.bot && this.c.config.ignore === 'bot')
67
+ return;
68
+ if (event.author_id === this.c.self_id && this.c.config.ignore === 'self')
69
+ return;
70
+ const messageEvent = new event_1.PrivateMessageEvent(this.c, event);
71
+ this.c.em('message.private', messageEvent);
72
+ this.c.logger.info(`recv from User(${messageEvent.author_id}): ${messageEvent.raw_message}`);
73
+ }, _Receiver_transformNoticeEvent = function _Receiver_transformNoticeEvent(event) {
74
+ };
75
+ (function (Receiver) {
76
+ const adapters = new Map;
77
+ function register(mode, receiver) {
78
+ adapters.set(mode, receiver);
79
+ }
80
+ Receiver.register = register;
81
+ function create(mode, ...args) {
82
+ const Construct = adapters.get(mode);
83
+ if (!Construct)
84
+ throw new Error(`未找到${mode}模式的接收器`);
85
+ return new Construct(...args);
86
+ }
87
+ Receiver.create = create;
88
+ })(Receiver || (exports.Receiver = Receiver = {}));
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebsocketReceiver = exports.WebhookReceiver = void 0;
4
+ var webhook_1 = require("./webhook");
5
+ Object.defineProperty(exports, "WebhookReceiver", { enumerable: true, get: function () { return webhook_1.WebhookReceiver; } });
6
+ var websocket_1 = require("./websocket");
7
+ Object.defineProperty(exports, "WebsocketReceiver", { enumerable: true, get: function () { return websocket_1.WebsocketReceiver; } });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhookReceiver = void 0;
4
+ const receiver_1 = require("../../core/receiver");
5
+ class WebhookReceiver extends receiver_1.Receiver {
6
+ constructor(client, config) {
7
+ super(client);
8
+ this.config = config;
9
+ }
10
+ connect() {
11
+ return Promise.resolve(undefined);
12
+ }
13
+ disconnect() {
14
+ return Promise.resolve(undefined);
15
+ }
16
+ }
17
+ exports.WebhookReceiver = WebhookReceiver;
18
+ receiver_1.Receiver.register('webhook', WebhookReceiver);