koishi-plugin-forward-hime 1.2.3 → 1.3.1

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 CHANGED
@@ -7,6 +7,10 @@
7
7
 
8
8
  </div>
9
9
 
10
+ ## Screenshot
11
+
12
+ ![screenshot](https://github.com/Nigh/forward-hime/assets/1407471/796b4f1c-c828-438c-85e9-71379c6c7e21)
13
+
10
14
  ## 安装
11
15
 
12
16
  在 Koishi WebUI 或 Koishi 桌面应用中,打开插件市场,搜索 `forward-hime`,找到本插件后,点击 `添加` 按钮后点击 `安装` 即可。
package/lib/cache.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Context } from "koishi";
2
+ import { ConfigSet } from "./config";
2
3
  export interface MsgCache {
3
4
  platform: string;
4
5
  bot: string;
@@ -11,7 +12,7 @@ declare module "@koishijs/cache" {
11
12
  msgCache: MsgCache;
12
13
  }
13
14
  }
14
- export declare function msgCacheInit(context: Context): void;
15
+ export declare function msgCacheInit(context: Context, cfg: ConfigSet): void;
15
16
  export declare function msgCache(mc: MsgCache): Promise<void>;
16
17
  export declare function msgCacheDelete(key: string): Promise<void>;
17
18
  export declare function msgCacheFindByKey(key: string): Promise<any>;
package/lib/config.d.ts CHANGED
@@ -8,6 +8,7 @@ export interface ForwardNode {
8
8
  export interface ConfigSet {
9
9
  WithChannelName: boolean;
10
10
  WithPlatformName: boolean;
11
+ CacheTimeout: number;
11
12
  ForwardGroups: {
12
13
  Nodes: ForwardNode[];
13
14
  }[];
@@ -1,3 +1,5 @@
1
- import { Session } from "koishi";
1
+ import { Session, Element } from "koishi";
2
2
  import { ForwardNode } from "./config";
3
+ export declare function MsgMiddlewareCache(session: Session): Promise<void>;
3
4
  export declare function MsgDecorator(session: Session, node: ForwardNode): Promise<any>;
5
+ export declare function MsgDecoratorFallback(session: Session, node: ForwardNode): Promise<Element[]>;
package/lib/index.js CHANGED
@@ -35,7 +35,10 @@ var createConfig = /* @__PURE__ */ __name(() => import_koishi.Schema.intersect([
35
35
  import_koishi.Schema.object({
36
36
  WithChannelName: import_koishi.Schema.boolean().description("是否包含频道名称").default(false),
37
37
  WithPlatformName: import_koishi.Schema.boolean().description("是否包含平台名称").default(true)
38
- }).description("转发格式"),
38
+ }).description("转发格式").hidden(),
39
+ import_koishi.Schema.object({
40
+ CacheTimeout: import_koishi.Schema.number().description("消息缓存时间(分钟)- 影响跨平台删除与回复等功能").default(120).min(120).max(1440 * 7)
41
+ }).description("消息缓存"),
39
42
  import_koishi.Schema.object({
40
43
  ForwardGroups: import_koishi.Schema.array(
41
44
  import_koishi.Schema.object({
@@ -86,14 +89,51 @@ var kook_default = {
86
89
 
87
90
  // src/decorators/onebot.ts
88
91
  var import_koishi4 = require("koishi");
92
+ function cqJsonTranslator(content, elem) {
93
+ let json = JSON.parse(elem.attrs.data);
94
+ let hit = 0;
95
+ if (json) {
96
+ if (json.prompt) {
97
+ hit += 1;
98
+ content.push((0, import_koishi4.h)("p", `${json.prompt}`));
99
+ }
100
+ if (json.meta && json.meta.detail_1) {
101
+ if (json.meta.detail_1.preview) {
102
+ hit += 1;
103
+ content.push(import_koishi4.h.image(json.meta.detail_1.preview));
104
+ }
105
+ if (json.meta.detail_1.qqdocurl) {
106
+ hit += 1;
107
+ content.push((0, import_koishi4.h)("span", `${json.meta.detail_1.qqdocurl}`));
108
+ }
109
+ }
110
+ }
111
+ if (hit === 0) {
112
+ content.push((0, import_koishi4.h)("span", `[CQ:JSON消息]`));
113
+ }
114
+ }
115
+ __name(cqJsonTranslator, "cqJsonTranslator");
89
116
  function Middleware(session) {
90
117
  const platform = guessPlatform(session);
118
+ let newContent = [];
91
119
  let head = [
92
120
  (0, import_koishi4.h)("b", `${session.username}`),
93
121
  (0, import_koishi4.h)("span", " 转发自 "),
94
122
  (0, import_koishi4.h)("i", `${platform}`),
95
123
  (0, import_koishi4.h)("span", `:`)
96
124
  ];
125
+ if (platform === "QQ") {
126
+ for (const key in session.elements) {
127
+ if (session.elements[key].type === "forward") {
128
+ newContent.push((0, import_koishi4.h)("span", `[CQ:转发消息]`));
129
+ } else if (session.elements[key].type === "json") {
130
+ cqJsonTranslator(newContent, session.elements[key]);
131
+ } else {
132
+ newContent.push(session.elements[key]);
133
+ }
134
+ }
135
+ return { head, content: newContent };
136
+ }
97
137
  return { head, content: session.elements };
98
138
  }
99
139
  __name(Middleware, "Middleware");
@@ -112,6 +152,7 @@ var onebot_default = {
112
152
 
113
153
  // src/cache.ts
114
154
  var ctx;
155
+ var cacheTimeout = 86400 * 1e3;
115
156
  function cacheNotEnabled() {
116
157
  if (!ctx.cache) {
117
158
  return true;
@@ -119,8 +160,9 @@ function cacheNotEnabled() {
119
160
  return false;
120
161
  }
121
162
  __name(cacheNotEnabled, "cacheNotEnabled");
122
- function msgCacheInit(context) {
163
+ function msgCacheInit(context, cfg) {
123
164
  ctx = context;
165
+ cacheTimeout = 60 * cfg.CacheTimeout * 1e3;
124
166
  }
125
167
  __name(msgCacheInit, "msgCacheInit");
126
168
  async function msgCache(mc) {
@@ -129,7 +171,7 @@ async function msgCache(mc) {
129
171
  }
130
172
  const key = mc.guild + ":" + mc.msgid;
131
173
  logger.debug(`[message-cache] ${mc.platform} ${key}`);
132
- await ctx.cache.set("msgCache", key, mc, 7200 * 1e3);
174
+ await ctx.cache.set("msgCache", key, mc, cacheTimeout);
133
175
  }
134
176
  __name(msgCache, "msgCache");
135
177
  async function msgCacheDelete(key) {
@@ -191,15 +233,52 @@ function defaultMiddleware(session) {
191
233
  }
192
234
  __name(defaultMiddleware, "defaultMiddleware");
193
235
  var localDecorators = [atTranslator, quoteTranslator];
194
- async function MsgDecorator(session, node) {
236
+ var msgMiddleCache = [];
237
+ function msgMiddleCacheAppend(msg) {
238
+ msgMiddleCache.push(msg);
239
+ if (msgMiddleCache.length > 16) {
240
+ msgMiddleCache.shift();
241
+ }
242
+ logger.debug(`[msgMiddleCache]`, msgMiddleCache.length);
243
+ }
244
+ __name(msgMiddleCacheAppend, "msgMiddleCacheAppend");
245
+ function msgMiddleCacheFind(uuid) {
246
+ for (const item of msgMiddleCache) {
247
+ if (item.UUID === uuid) {
248
+ return item.msg;
249
+ }
250
+ }
251
+ return null;
252
+ }
253
+ __name(msgMiddleCacheFind, "msgMiddleCacheFind");
254
+ function MsgToMiddleware(session) {
195
255
  let elems = { head: [], content: [] };
196
256
  let _platform_in = decorators_exports[session.platform];
197
- let _platform_out = decorators_exports[node.Platform];
198
257
  if (_platform_in && typeof _platform_in.Middleware === "function") {
199
258
  elems = _platform_in.Middleware(session);
200
259
  } else {
201
260
  elems = defaultMiddleware(session);
202
261
  }
262
+ return elems;
263
+ }
264
+ __name(MsgToMiddleware, "MsgToMiddleware");
265
+ async function MsgMiddlewareCache(session) {
266
+ let elems = MsgToMiddleware(session);
267
+ msgMiddleCacheAppend({ UUID: MsgUUIDFromSession(session), msg: elems });
268
+ logger.debug(`[msgMiddleCache] CACHED`);
269
+ }
270
+ __name(MsgMiddlewareCache, "MsgMiddlewareCache");
271
+ async function MsgDecorator(session, node) {
272
+ let elems;
273
+ let _platform_out = decorators_exports[node.Platform];
274
+ let elemCache = msgMiddleCacheFind(MsgUUIDFromSession(session));
275
+ if (elemCache) {
276
+ logger.debug(`[msgMiddleCache] HIT`);
277
+ elems = elemCache;
278
+ } else {
279
+ logger.debug(`[msgMiddleCache] MISSED`);
280
+ elems = MsgToMiddleware(session);
281
+ }
203
282
  for (const fn of localDecorators) {
204
283
  elems = await fn(session, node, elems);
205
284
  }
@@ -210,6 +289,30 @@ async function MsgDecorator(session, node) {
210
289
  }
211
290
  }
212
291
  __name(MsgDecorator, "MsgDecorator");
292
+ function defaultDecoratorFallback({ head, content }) {
293
+ let msg = [];
294
+ let newContent = [];
295
+ newContent.push((0, import_koishi5.h)("span", `[消息降级] `));
296
+ for (const key in content) {
297
+ if (["img", "audio", "video", "file"].includes(content[key].type)) {
298
+ newContent.push((0, import_koishi5.h)("span", ` [${content[key].type}] `));
299
+ } else {
300
+ newContent.push(content[key]);
301
+ }
302
+ }
303
+ msg = msg.concat(head, (0, import_koishi5.h)("br"), newContent);
304
+ return msg;
305
+ }
306
+ __name(defaultDecoratorFallback, "defaultDecoratorFallback");
307
+ async function MsgDecoratorFallback(session, node) {
308
+ let elems = { head: [], content: [] };
309
+ elems = defaultMiddleware(session);
310
+ for (const fn of localDecorators) {
311
+ elems = await fn(session, node, elems);
312
+ }
313
+ return defaultDecoratorFallback(elems);
314
+ }
315
+ __name(MsgDecoratorFallback, "MsgDecoratorFallback");
213
316
  async function atTranslator(session, node, { head, content }) {
214
317
  const newMsg = await new Promise((resolve, reject) => {
215
318
  let newContent = [];
@@ -239,7 +342,8 @@ async function quoteTranslator(session, node, { head, content }) {
239
342
  if (cache) {
240
343
  let msgid = await msgCacheGetLocalIDByUUID(node, cache.uuid);
241
344
  if (msgid) {
242
- head.unshift((0, import_koishi5.h)("quote", { id: msgid }));
345
+ let newHead = [(0, import_koishi5.h)("quote", { id: msgid })].concat(head);
346
+ return { head: newHead, content };
243
347
  } else {
244
348
  logger.error(`[msgCacheGetLocalIDByUUID] ${cache.uuid} not found`);
245
349
  }
@@ -249,42 +353,64 @@ async function quoteTranslator(session, node, { head, content }) {
249
353
  __name(quoteTranslator, "quoteTranslator");
250
354
 
251
355
  // src/message.ts
252
- async function MessageForward(ctx2, node, session) {
356
+ async function MessageSendWithDecorator(ctx2, node, session, Deco) {
253
357
  const uuid = session.channelId + ":" + session.messageId;
254
- const content = await MsgDecorator(session, node);
255
- try {
256
- botExistsCheck(ctx2, node);
257
- await ctx2.bots[`${node.Platform}:${node.BotID}`].sendMessage(node.Guild, content).then((res) => {
258
- let mc = {
259
- platform: node.Platform,
260
- bot: node.BotID,
261
- guild: node.Guild,
262
- msgid: res[0],
263
- uuid
264
- };
358
+ const content = await Deco(session, node);
359
+ await ctx2.bots[`${node.Platform}:${node.BotID}`].sendMessage(node.Guild, content).then((res) => {
360
+ let mc = {
361
+ platform: node.Platform,
362
+ bot: node.BotID,
363
+ guild: node.Guild,
364
+ msgid: res[0],
365
+ uuid
366
+ };
367
+ if (!mc.msgid) {
368
+ throw new Error(`Empty Message ID`);
369
+ } else {
265
370
  msgCache(mc);
266
371
  logger.debug(`[MessageForward] to ${mc.platform} ${mc.uuid}`);
267
- });
268
- } catch (error) {
269
- logger.error(`ERROR:<MessageSend> ${error}`, content);
372
+ }
373
+ }).catch((error) => {
374
+ logger.error(`content: ${content}`);
375
+ throw error;
376
+ });
377
+ }
378
+ __name(MessageSendWithDecorator, "MessageSendWithDecorator");
379
+ async function MessageForward(ctx2, node, session) {
380
+ if (!botExistsCheck(ctx2, node)) {
381
+ return;
270
382
  }
383
+ MessageSendWithDecorator(ctx2, node, session, MsgDecorator).catch((error) => {
384
+ logger.error(`ERROR:<MessageSend ${node.Platform}> ${error}`);
385
+ MessageSendWithDecorator(ctx2, node, session, MsgDecoratorFallback).catch(
386
+ (error2) => {
387
+ logger.error(`ERROR:<MessageSendFallback ${node.Platform}> ${error2}`);
388
+ }
389
+ );
390
+ });
271
391
  }
272
392
  __name(MessageForward, "MessageForward");
273
393
  async function MessageDelete(ctx2, msg) {
274
- try {
275
- botExistsCheck(ctx2, { Platform: msg.platform, BotID: msg.bot, Guild: msg.guild });
276
- await ctx2.bots[`${msg.platform}:${msg.bot}`].deleteMessage(msg.guild, msg.msgid);
277
- } catch (error) {
278
- logger.error(`ERROR:<MessageDelete> ${error}`);
394
+ if (!botExistsCheck(ctx2, { Platform: msg.platform, BotID: msg.bot, Guild: msg.guild })) {
395
+ return;
279
396
  }
397
+ await ctx2.bots[`${msg.platform}:${msg.bot}`].deleteMessage(msg.guild, msg.msgid).catch((error) => {
398
+ logger.error(`ERROR:<MessageDelete> ${error}`);
399
+ });
280
400
  }
281
401
  __name(MessageDelete, "MessageDelete");
282
402
  function botExistsCheck(ctx2, node) {
283
403
  if (ctx2.bots[`${node.Platform}:${node.BotID}`] == void 0) {
284
- throw new Error("Bot Not Found");
404
+ logger.error(`ERROR:<BOT not Exist> ${node.Platform}:${node.BotID}`);
405
+ return false;
285
406
  }
407
+ return true;
286
408
  }
287
409
  __name(botExistsCheck, "botExistsCheck");
410
+ function MsgUUIDFromSession(session) {
411
+ return session.channelId + ":" + session.messageId;
412
+ }
413
+ __name(MsgUUIDFromSession, "MsgUUIDFromSession");
288
414
 
289
415
  // src/index.ts
290
416
  var name = `forward hime - 转发姬`;
@@ -305,18 +431,22 @@ var inject = {
305
431
  };
306
432
  var Config = createConfig();
307
433
  function apply(ctx2, cfg) {
308
- msgCacheInit(ctx2);
434
+ msgCacheInit(ctx2, cfg);
309
435
  ctx2.on("message-created", async (session) => {
310
436
  const hitGroup = [];
311
437
  for (const g in cfg.ForwardGroups) {
312
438
  const group = cfg.ForwardGroups[g];
313
439
  for (const k in group.Nodes) {
314
440
  if (group.Nodes[k].Guild === session.channelId && group.Nodes[k].Platform === session.platform && group.Nodes[k].BotID !== session.userId) {
441
+ if (!session.channelId || !session.messageId) {
442
+ continue;
443
+ }
315
444
  logger.debug(
316
445
  "[message-created]",
446
+ session.platform,
317
447
  session.channelId + ":" + session.messageId
318
448
  );
319
- let uuid = session.channelId + ":" + session.messageId;
449
+ let uuid = MsgUUIDFromSession(session);
320
450
  msgCache({
321
451
  platform: session.platform,
322
452
  bot: group.Nodes[k].BotID,
@@ -329,6 +459,9 @@ function apply(ctx2, cfg) {
329
459
  }
330
460
  }
331
461
  }
462
+ if (hitGroup.length > 0) {
463
+ await MsgMiddlewareCache(session);
464
+ }
332
465
  for (const g in hitGroup) {
333
466
  const group = cfg.ForwardGroups[hitGroup[g]];
334
467
  for (const k in group.Nodes) {
package/lib/message.d.ts CHANGED
@@ -4,3 +4,4 @@ import { MsgCache } from "./cache";
4
4
  export declare function MessageForward(ctx: Context, node: ForwardNode, session: Session): Promise<void>;
5
5
  export declare function MessageDelete(ctx: Context, msg: MsgCache): Promise<void>;
6
6
  export declare function MessageEdit(ctx: Context, node: ForwardNode, session: Session): Promise<void>;
7
+ export declare function MsgUUIDFromSession(session: Session): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-forward-hime",
3
3
  "description": "多群组消息互通",
4
- "version": "1.2.3",
4
+ "version": "1.3.1",
5
5
  "author": {
6
6
  "name": "xianii",
7
7
  "email": "jiyucheng007@gmail.com"
@@ -15,7 +15,7 @@
15
15
  "browser": true
16
16
  },
17
17
  "license": "MIT",
18
- "homepage": "https://github.com/Nigh/forward-hime",
18
+ "homepage": "https://nigh.github.io/forward-hime/",
19
19
  "repository": {
20
20
  "type": "git",
21
21
  "url": "git+https://github.com/Nigh/forward-hime.git"