koishi-plugin-ll-mc 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. package/lib/index.js +81 -8
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -51,6 +51,84 @@ exports.inject = {
51
51
  optional: ["markdownToImage", "puppeteer", "canvas"],
52
52
  };
53
53
  const logger = new koishi_1.Logger("mc");
54
+ // ===== 官方QQ平台 群名/群昵称 修复补丁 =====
55
+ const nameCache = { channel: new Map(), member: new Map() };
56
+ const NAME_CACHE_TTL = 60 * 60 * 1000; // 缓存 1 小时,避免官方接口限频
57
+ function cacheGet(map, key) {
58
+ const item = map.get(key);
59
+ return item && Date.now() - item.t < NAME_CACHE_TTL ? item.v : undefined;
60
+ }
61
+ function cacheSet(map, key, value) {
62
+ map.set(key, { v: value, t: Date.now() });
63
+ }
64
+ async function resolveUsername(session, userId) {
65
+ const author = session.author;
66
+ if (author?.nick)
67
+ return author.nick; // OneBot:昵称在这
68
+ if (author?.name)
69
+ return author.name;
70
+ // 官方QQ平台:群消息原始事件自带 member.nick,零 API 调用
71
+ const raw = session.event?._data?.d;
72
+ if (raw?.member?.nick)
73
+ return raw.member.nick;
74
+ if (raw?.author?.username)
75
+ return raw.author.username;
76
+ // 兜底:调用 getGuildMember(官方 adapter 已实现)
77
+ const guildId = session.guildId || session.channelId;
78
+ const key = `${guildId}:${userId}`;
79
+ const cached = cacheGet(nameCache.member, key);
80
+ if (cached)
81
+ return cached;
82
+ if (guildId && typeof session.bot?.getGuildMember === "function") {
83
+ try {
84
+ const member = await session.bot.getGuildMember(guildId, userId);
85
+ const name = member?.name || member?.user?.name;
86
+ if (name) {
87
+ cacheSet(nameCache.member, key, name);
88
+ return name;
89
+ }
90
+ }
91
+ catch (e) {
92
+ logger.warn(`[mc] 获取成员昵称失败 ${userId}:`, e);
93
+ }
94
+ }
95
+ return userId;
96
+ }
97
+ async function resolveChannelName(session) {
98
+ if (session.event?.channel?.name)
99
+ return session.event.channel.name; // OneBot 走这里
100
+ const channelId = session.channelId;
101
+ const cached = cacheGet(nameCache.channel, channelId);
102
+ if (cached)
103
+ return cached;
104
+ const bot = session.bot;
105
+ if (typeof bot?.getChannel === "function") {
106
+ try {
107
+ const ch = await bot.getChannel(channelId);
108
+ if (ch?.name) {
109
+ cacheSet(nameCache.channel, channelId, ch.name);
110
+ return ch.name;
111
+ }
112
+ }
113
+ catch { /* 官方QQ对群无效,继续走 getGuild */ }
114
+ }
115
+ // 官方QQ平台:群信息走 getGuild(内部 getGuildInfo 返回群名)
116
+ const guildId = session.guildId || channelId;
117
+ if (guildId && typeof bot?.getGuild === "function") {
118
+ try {
119
+ const g = await bot.getGuild(guildId);
120
+ if (g?.name) {
121
+ cacheSet(nameCache.channel, channelId, g.name);
122
+ return g.name;
123
+ }
124
+ }
125
+ catch (e) {
126
+ logger.warn(`[mc] 获取群名失败 ${guildId}:`, e);
127
+ }
128
+ }
129
+ return channelId;
130
+ }
131
+ // ===== 补丁结束 =====
54
132
  // --- 定义字体选项常量 ---
55
133
  const FONT_OPTIONS = {
56
134
  TITLE: "HarmonyOS_Sans_Medium",
@@ -503,12 +581,10 @@ async function apply(ctx, config) {
503
581
  return next();
504
582
  session[PROCESSED] = true;
505
583
  const { userId, channelId, author } = session;
506
- let sessionChannelName = session.event.channel.name;
507
- const username = author?.nick || author?.name || userId;
584
+ const username = await resolveUsername(session, userId);
508
585
  const userAvatar = author?.avatar;
509
586
  try {
510
- const channelName = sessionChannelName ||
511
- (channelId ? await getChannelName(session.bot, channelId) : channelId);
587
+ const channelName = channelId ? await resolveChannelName(session) : channelId;
512
588
  await ctx.database.upsert("message_counter_records", (row) => [
513
589
  {
514
590
  channelId,
@@ -536,16 +612,13 @@ async function apply(ctx, config) {
536
612
  if (!session.channelId)
537
613
  return;
538
614
  const { channelId, bot } = session;
539
- let sessionChannelName = session.event.channel.name;
540
615
  const botUser = bot.user;
541
616
  if (!botUser) {
542
617
  logger.warn("Bot user is undefined, skipping bot message tracking.");
543
618
  return;
544
619
  }
545
620
  try {
546
- const channelName = sessionChannelName ||
547
- (await getChannelName(bot, channelId)) ||
548
- channelId;
621
+ const channelName = (await resolveChannelName(session)) || channelId;
549
622
  await ctx.database.upsert("message_counter_records", (row) => [
550
623
  {
551
624
  channelId,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-ll-mc",
3
3
  "description": "消息统计插件(克隆自 message-counter),支持排除指定群聊",
4
- "version": "1.0.1",
4
+ "version": "1.0.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [