@dsh-plugin/dsh-synapse 0.1.0-dev.41044228975 → 0.1.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 +661 -661
- package/README.md +0 -14
- package/package.json +1 -1
- package/vendor/gugle-chat-bot/LICENSE +661 -661
- package/vendor/gugle-chat-bot/package.json +57 -57
- package/vendor/gugle-chat-bot/src/allow-rule.yml +9345 -9345
- package/vendor/gugle-chat-bot/src/api.json +4284 -4284
- package/vendor/gugle-chat-bot/src/command/index.ts +141 -141
- package/vendor/gugle-chat-bot/src/config/features.ts +547 -547
- package/vendor/gugle-chat-bot/src/config/index.ts +184 -184
- package/vendor/gugle-chat-bot/src/config/manager.ts +356 -356
- package/vendor/gugle-chat-bot/src/constants/index.ts +13 -13
- package/vendor/gugle-chat-bot/src/custom.ts +548 -548
- package/vendor/gugle-chat-bot/src/event/index.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/admin/index.ts +414 -414
- package/vendor/gugle-chat-bot/src/features/bili/image/impl/video.ts +39 -39
- package/vendor/gugle-chat-bot/src/features/bili/image/index.ts +37 -37
- package/vendor/gugle-chat-bot/src/features/bili/index.ts +65 -65
- package/vendor/gugle-chat-bot/src/features/bili/template/style/video.css +97 -97
- package/vendor/gugle-chat-bot/src/features/bili/template/video.html +56 -56
- package/vendor/gugle-chat-bot/src/features/discord-bridge/index.ts +1128 -1128
- package/vendor/gugle-chat-bot/src/features/discord-bridge/markdown.ts +105 -105
- package/vendor/gugle-chat-bot/src/features/discord-bridge/slash.ts +355 -355
- package/vendor/gugle-chat-bot/src/features/discord-bridge/source.ts +96 -96
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/message.html +14 -14
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/style/message.css +144 -144
- package/vendor/gugle-chat-bot/src/features/github/api.ts +93 -93
- package/vendor/gugle-chat-bot/src/features/github/binding.ts +161 -161
- package/vendor/gugle-chat-bot/src/features/github/image/impl/issue.ts +132 -132
- package/vendor/gugle-chat-bot/src/features/github/image/impl/pr.ts +144 -144
- package/vendor/gugle-chat-bot/src/features/github/image/impl/release.ts +160 -160
- package/vendor/gugle-chat-bot/src/features/github/image/index.ts +310 -310
- package/vendor/gugle-chat-bot/src/features/github/index.ts +302 -302
- package/vendor/gugle-chat-bot/src/features/github/template/issue.html +118 -118
- package/vendor/gugle-chat-bot/src/features/github/template/pull_request.html +125 -125
- package/vendor/gugle-chat-bot/src/features/github/template/release.html +53 -53
- package/vendor/gugle-chat-bot/src/features/github/template/style/issue.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/pull_request.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/release.css +412 -412
- package/vendor/gugle-chat-bot/src/features/hermes/client.ts +184 -184
- package/vendor/gugle-chat-bot/src/features/hermes/config.ts +210 -210
- package/vendor/gugle-chat-bot/src/features/hermes/context.ts +67 -67
- package/vendor/gugle-chat-bot/src/features/hermes/history.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/index.ts +1533 -1533
- package/vendor/gugle-chat-bot/src/features/hermes/message.ts +319 -319
- package/vendor/gugle-chat-bot/src/features/hermes/reaction.ts +181 -181
- package/vendor/gugle-chat-bot/src/features/hermes/render.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/hermes/reply-units.ts +331 -331
- package/vendor/gugle-chat-bot/src/features/hermes/skills.ts +406 -406
- package/vendor/gugle-chat-bot/src/features/hermes/template/approval.html +30 -30
- package/vendor/gugle-chat-bot/src/features/hermes/template/progress.html +21 -21
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/approval.css +81 -81
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/progress.css +120 -120
- package/vendor/gugle-chat-bot/src/features/hermes/trigger.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/types.ts +327 -327
- package/vendor/gugle-chat-bot/src/features/management/index.ts +156 -156
- package/vendor/gugle-chat-bot/src/features/minecraft/index.ts +127 -127
- package/vendor/gugle-chat-bot/src/features/modrinth/index.ts +71 -71
- package/vendor/gugle-chat-bot/src/features/parentheses/index.ts +117 -117
- package/vendor/gugle-chat-bot/src/features/peak-valley-timer/index.ts +451 -451
- package/vendor/gugle-chat-bot/src/features/poke/index.ts +24 -24
- package/vendor/gugle-chat-bot/src/features/version-tracker/index.ts +77 -77
- package/vendor/gugle-chat-bot/src/features/welcome/index.ts +57 -57
- package/vendor/gugle-chat-bot/src/github-ip.json +5814 -5814
- package/vendor/gugle-chat-bot/src/image/index.ts +278 -278
- package/vendor/gugle-chat-bot/src/index.ts +695 -695
- package/vendor/gugle-chat-bot/src/logger/index.ts +54 -54
- package/vendor/gugle-chat-bot/src/result.json +359 -359
- package/vendor/gugle-chat-bot/src/type/bili.d.ts +825 -825
- package/vendor/gugle-chat-bot/src/type/event.d.ts +146 -146
- package/vendor/gugle-chat-bot/src/type/github.d.ts +446 -446
- package/vendor/gugle-chat-bot/src/type/index.d.ts +254 -254
- package/vendor/gugle-chat-bot/tsconfig.json +46 -46
- package/scripts/dump-npm-latest.mjs +0 -30
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { Message, NotifyNoticeWSMSG } from '@/type';
|
|
2
|
-
import { QQBot } from '@/index';
|
|
3
|
-
import { getFeatureGroups } from '@/config/features';
|
|
4
|
-
import dayjs from 'dayjs';
|
|
5
|
-
|
|
6
|
-
export class Poke {
|
|
7
|
-
public static processPokeMsg(bot: QQBot, msg: NotifyNoticeWSMSG, sentMessage: Message[]) {
|
|
8
|
-
const hour = dayjs().hour();
|
|
9
|
-
if (hour > 7 && hour < 21) return;
|
|
10
|
-
if (!msg.group_id || !getFeatureGroups('poke').includes(msg.group_id)) return;
|
|
11
|
-
const loginInfo = bot.getLoginInfoSync();
|
|
12
|
-
if (!loginInfo || msg.target_id !== loginInfo.user_id) return;
|
|
13
|
-
const msgPool = ['下一个', '零分', '负分', '给我滚'];
|
|
14
|
-
const banPool = [60, 120, 240, 300];
|
|
15
|
-
const rand = Math.round(Math.random() * msgPool.length);
|
|
16
|
-
sentMessage.push({
|
|
17
|
-
type: 'text',
|
|
18
|
-
data: {
|
|
19
|
-
text: msgPool[rand] || '零分'
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
bot.ban(msg.group_id, msg.user_id, banPool[rand] || 120);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
import { Message, NotifyNoticeWSMSG } from '@/type';
|
|
2
|
+
import { QQBot } from '@/index';
|
|
3
|
+
import { getFeatureGroups } from '@/config/features';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
|
|
6
|
+
export class Poke {
|
|
7
|
+
public static processPokeMsg(bot: QQBot, msg: NotifyNoticeWSMSG, sentMessage: Message[]) {
|
|
8
|
+
const hour = dayjs().hour();
|
|
9
|
+
if (hour > 7 && hour < 21) return;
|
|
10
|
+
if (!msg.group_id || !getFeatureGroups('poke').includes(msg.group_id)) return;
|
|
11
|
+
const loginInfo = bot.getLoginInfoSync();
|
|
12
|
+
if (!loginInfo || msg.target_id !== loginInfo.user_id) return;
|
|
13
|
+
const msgPool = ['下一个', '零分', '负分', '给我滚'];
|
|
14
|
+
const banPool = [60, 120, 240, 300];
|
|
15
|
+
const rand = Math.round(Math.random() * msgPool.length);
|
|
16
|
+
sentMessage.push({
|
|
17
|
+
type: 'text',
|
|
18
|
+
data: {
|
|
19
|
+
text: msgPool[rand] || '零分'
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
bot.ban(msg.group_id, msg.user_id, banPool[rand] || 120);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import { EventDataManager } from '@/event';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 版本发布的时间戳单调性跟踪器。
|
|
5
|
-
*
|
|
6
|
-
* 背景:Minecraft / Modrinth 的版本清单接口经过 CDN 缓存,缓存刷新不是
|
|
7
|
-
* 全量原子的,同一"最新版本"可能在几次请求间反复出现/消失(例如
|
|
8
|
-
* 1.21.10 → 1.21.9 → 1.21.10)。若只按"值变化即发送"会重复通知。
|
|
9
|
-
*
|
|
10
|
-
* 方案:利用各数据源自带的权威时间戳判断新版本,而不是观察窗口——
|
|
11
|
-
* - Minecraft version_manifest_v2.json 的 versions[].releaseTime:各版本
|
|
12
|
-
* 发布时间恒定,CDN 只缓存真实数据,同一版本号的时间戳永远不变。
|
|
13
|
-
* - Modrinth Maven maven-metadata.xml 的 <lastUpdated>:metadata 文件更新
|
|
14
|
-
* 时间,单调递增(只有发布新版本才更新);CDN 回退返回的旧缓存其
|
|
15
|
-
* lastUpdated 必然更小。
|
|
16
|
-
*
|
|
17
|
-
* 因此记录"已确认版本 + 时间戳":仅当观察到的时间戳严格晚于已记录值
|
|
18
|
-
* 才判定为新发布并通知。CDN 抖动期间版本号来回跳动,但时间戳不会往前
|
|
19
|
-
* 跳——旧缓存时间戳更小,自然不触发通知。
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
export interface ReleasedVersionState {
|
|
23
|
-
version: string;
|
|
24
|
-
/** 权威发布时间(毫秒时间戳):Minecraft 用 releaseTime,Modrinth 用 lastUpdated */
|
|
25
|
-
timestamp: number;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* 检查一个版本是否为新发布、需要通知。
|
|
30
|
-
*
|
|
31
|
-
* @param storageKey EventDataManager storage 键(各资源独立,如 mcupdate:release / modrinth:sodium)
|
|
32
|
-
* @param version 本次观察到的版本号(空串忽略)
|
|
33
|
-
* @param timestamp 版本权威发布时间(毫秒);0 或缺失时保守忽略(不误报)
|
|
34
|
-
* @returns true = 该版本时间戳严格晚于已记录的版本,确认为新发布
|
|
35
|
-
*/
|
|
36
|
-
export async function checkReleasedVersion(storageKey: string, version: string, timestamp: number): Promise<boolean> {
|
|
37
|
-
if (!version || !timestamp) return false;
|
|
38
|
-
|
|
39
|
-
const last = (await EventDataManager.getStorage(storageKey, 'released')) as ReleasedVersionState | undefined;
|
|
40
|
-
|
|
41
|
-
// 首次使用(冷启动 / 升级引入新键):只记录当前版本,不通知,
|
|
42
|
-
// 避免部署/重启后立即对既有版本轰炸;此后版本变化才正常通知。
|
|
43
|
-
if (!last || !last.version) {
|
|
44
|
-
await EventDataManager.setStorage(storageKey, 'released', { version, timestamp });
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 已确认过的版本:忽略(永不重复通知)
|
|
49
|
-
if (version === last.version) return false;
|
|
50
|
-
|
|
51
|
-
// 时间戳严格更晚:真实新发布 → 记录并通知
|
|
52
|
-
if (timestamp > last.timestamp) {
|
|
53
|
-
await EventDataManager.setStorage(storageKey, 'released', { version, timestamp });
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// CDN 回退到更旧的数据(旧缓存时间戳更小):忽略,不更新记录
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 解析 Maven <lastUpdated> 为毫秒时间戳。
|
|
63
|
-
* 兼容两种格式:标准 Maven 14 位 YYYYMMDDHHmmss,以及 13 位毫秒时间戳。
|
|
64
|
-
* 无法解析时返回 0(调用方按"无时间戳"保守处理,不误报)。
|
|
65
|
-
*/
|
|
66
|
-
export function parseMavenLastUpdated(raw: string): number {
|
|
67
|
-
const trimmed = (raw || '').trim();
|
|
68
|
-
if (/^\d{14}$/.test(trimmed)) {
|
|
69
|
-
const t = Date.parse(
|
|
70
|
-
`${trimmed.slice(0, 4)}-${trimmed.slice(4, 6)}-${trimmed.slice(6, 8)}T` +
|
|
71
|
-
`${trimmed.slice(8, 10)}:${trimmed.slice(10, 12)}:${trimmed.slice(12, 14)}Z`
|
|
72
|
-
);
|
|
73
|
-
return Number.isNaN(t) ? 0 : t;
|
|
74
|
-
}
|
|
75
|
-
if (/^\d{13}$/.test(trimmed)) return parseInt(trimmed, 10);
|
|
76
|
-
const t = Date.parse(trimmed);
|
|
77
|
-
return Number.isNaN(t) ? 0 : t;
|
|
1
|
+
import { EventDataManager } from '@/event';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 版本发布的时间戳单调性跟踪器。
|
|
5
|
+
*
|
|
6
|
+
* 背景:Minecraft / Modrinth 的版本清单接口经过 CDN 缓存,缓存刷新不是
|
|
7
|
+
* 全量原子的,同一"最新版本"可能在几次请求间反复出现/消失(例如
|
|
8
|
+
* 1.21.10 → 1.21.9 → 1.21.10)。若只按"值变化即发送"会重复通知。
|
|
9
|
+
*
|
|
10
|
+
* 方案:利用各数据源自带的权威时间戳判断新版本,而不是观察窗口——
|
|
11
|
+
* - Minecraft version_manifest_v2.json 的 versions[].releaseTime:各版本
|
|
12
|
+
* 发布时间恒定,CDN 只缓存真实数据,同一版本号的时间戳永远不变。
|
|
13
|
+
* - Modrinth Maven maven-metadata.xml 的 <lastUpdated>:metadata 文件更新
|
|
14
|
+
* 时间,单调递增(只有发布新版本才更新);CDN 回退返回的旧缓存其
|
|
15
|
+
* lastUpdated 必然更小。
|
|
16
|
+
*
|
|
17
|
+
* 因此记录"已确认版本 + 时间戳":仅当观察到的时间戳严格晚于已记录值
|
|
18
|
+
* 才判定为新发布并通知。CDN 抖动期间版本号来回跳动,但时间戳不会往前
|
|
19
|
+
* 跳——旧缓存时间戳更小,自然不触发通知。
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export interface ReleasedVersionState {
|
|
23
|
+
version: string;
|
|
24
|
+
/** 权威发布时间(毫秒时间戳):Minecraft 用 releaseTime,Modrinth 用 lastUpdated */
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 检查一个版本是否为新发布、需要通知。
|
|
30
|
+
*
|
|
31
|
+
* @param storageKey EventDataManager storage 键(各资源独立,如 mcupdate:release / modrinth:sodium)
|
|
32
|
+
* @param version 本次观察到的版本号(空串忽略)
|
|
33
|
+
* @param timestamp 版本权威发布时间(毫秒);0 或缺失时保守忽略(不误报)
|
|
34
|
+
* @returns true = 该版本时间戳严格晚于已记录的版本,确认为新发布
|
|
35
|
+
*/
|
|
36
|
+
export async function checkReleasedVersion(storageKey: string, version: string, timestamp: number): Promise<boolean> {
|
|
37
|
+
if (!version || !timestamp) return false;
|
|
38
|
+
|
|
39
|
+
const last = (await EventDataManager.getStorage(storageKey, 'released')) as ReleasedVersionState | undefined;
|
|
40
|
+
|
|
41
|
+
// 首次使用(冷启动 / 升级引入新键):只记录当前版本,不通知,
|
|
42
|
+
// 避免部署/重启后立即对既有版本轰炸;此后版本变化才正常通知。
|
|
43
|
+
if (!last || !last.version) {
|
|
44
|
+
await EventDataManager.setStorage(storageKey, 'released', { version, timestamp });
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 已确认过的版本:忽略(永不重复通知)
|
|
49
|
+
if (version === last.version) return false;
|
|
50
|
+
|
|
51
|
+
// 时间戳严格更晚:真实新发布 → 记录并通知
|
|
52
|
+
if (timestamp > last.timestamp) {
|
|
53
|
+
await EventDataManager.setStorage(storageKey, 'released', { version, timestamp });
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// CDN 回退到更旧的数据(旧缓存时间戳更小):忽略,不更新记录
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 解析 Maven <lastUpdated> 为毫秒时间戳。
|
|
63
|
+
* 兼容两种格式:标准 Maven 14 位 YYYYMMDDHHmmss,以及 13 位毫秒时间戳。
|
|
64
|
+
* 无法解析时返回 0(调用方按"无时间戳"保守处理,不误报)。
|
|
65
|
+
*/
|
|
66
|
+
export function parseMavenLastUpdated(raw: string): number {
|
|
67
|
+
const trimmed = (raw || '').trim();
|
|
68
|
+
if (/^\d{14}$/.test(trimmed)) {
|
|
69
|
+
const t = Date.parse(
|
|
70
|
+
`${trimmed.slice(0, 4)}-${trimmed.slice(4, 6)}-${trimmed.slice(6, 8)}T` +
|
|
71
|
+
`${trimmed.slice(8, 10)}:${trimmed.slice(10, 12)}:${trimmed.slice(12, 14)}Z`
|
|
72
|
+
);
|
|
73
|
+
return Number.isNaN(t) ? 0 : t;
|
|
74
|
+
}
|
|
75
|
+
if (/^\d{13}$/.test(trimmed)) return parseInt(trimmed, 10);
|
|
76
|
+
const t = Date.parse(trimmed);
|
|
77
|
+
return Number.isNaN(t) ? 0 : t;
|
|
78
78
|
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import { QQBot } from '@/index';
|
|
2
|
-
import { GroupIncreaseNoticeWSMSG } from '@/type';
|
|
3
|
-
import { getWelcomeConfig } from '@/config/features';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 新人欢迎模块。
|
|
7
|
-
*
|
|
8
|
-
* 配置(configs/features/welcome.json,v1):
|
|
9
|
-
* ```json
|
|
10
|
-
* {
|
|
11
|
-
* "version": 1,
|
|
12
|
-
* "welcomes": [
|
|
13
|
-
* { "group": [123456, 234567], "msg": "欢迎 ${at} 加入群聊" },
|
|
14
|
-
* { "group": [888888], "msg": ["${at} 欢迎你!", "请查看群公告", "有问题找管理员"] }
|
|
15
|
-
* ]
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
* - `group`:适用群号列表(可多个群共用同一条欢迎语)
|
|
19
|
-
* - `msg`:欢迎语模板(字符串或字符串数组,数组每项一行,\n 拼接),
|
|
20
|
-
* `${at}` 会被替换为 @新成员 消息段
|
|
21
|
-
*/
|
|
22
|
-
export class Welcome {
|
|
23
|
-
/**
|
|
24
|
-
* 处理 group_increase 通知,匹配到该群的欢迎配置后发送欢迎消息。
|
|
25
|
-
*/
|
|
26
|
-
public static handleGroupIncreaseNotice(bot: QQBot, msg: GroupIncreaseNoticeWSMSG): void {
|
|
27
|
-
const config = getWelcomeConfig();
|
|
28
|
-
const entry = config.welcomes.find(item => item.group.includes(msg.group_id));
|
|
29
|
-
if (!entry) return;
|
|
30
|
-
const message = buildWelcomeMessage(msg.user_id, entry.msg);
|
|
31
|
-
bot.sendGroupMsg(msg.group_id, message);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 将欢迎模板渲染成消息段数组:`${at}` 拆分为 @成员 消息段,
|
|
37
|
-
* 其余文本保持文本段(避免以字符串拼接 CQ 码)。
|
|
38
|
-
* `template` 可为字符串或字符串数组(数组按换行拼接为多行文本)。
|
|
39
|
-
*/
|
|
40
|
-
export function buildWelcomeMessage(qq: number, template: string | string[]): import('@/type').Message[] {
|
|
41
|
-
const text = Array.isArray(template) ? template.join('\n') : template;
|
|
42
|
-
const parts = text.split('${at}');
|
|
43
|
-
const messages: import('@/type').Message[] = [];
|
|
44
|
-
parts.forEach((part, index) => {
|
|
45
|
-
if (part) {
|
|
46
|
-
messages.push({ type: 'text', data: { text: part } });
|
|
47
|
-
}
|
|
48
|
-
// 在每段文本之后插入 @(除最后一段)
|
|
49
|
-
if (index < parts.length - 1) {
|
|
50
|
-
messages.push({ type: 'at', data: { qq } });
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
// 模板中无 ${at} 时的兜底:把 QQ 号附在末尾
|
|
54
|
-
if (messages.length === 0) {
|
|
55
|
-
messages.push({ type: 'text', data: { text: `欢迎新成员 ${qq} 加入群聊` } });
|
|
56
|
-
}
|
|
57
|
-
return messages;
|
|
1
|
+
import { QQBot } from '@/index';
|
|
2
|
+
import { GroupIncreaseNoticeWSMSG } from '@/type';
|
|
3
|
+
import { getWelcomeConfig } from '@/config/features';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 新人欢迎模块。
|
|
7
|
+
*
|
|
8
|
+
* 配置(configs/features/welcome.json,v1):
|
|
9
|
+
* ```json
|
|
10
|
+
* {
|
|
11
|
+
* "version": 1,
|
|
12
|
+
* "welcomes": [
|
|
13
|
+
* { "group": [123456, 234567], "msg": "欢迎 ${at} 加入群聊" },
|
|
14
|
+
* { "group": [888888], "msg": ["${at} 欢迎你!", "请查看群公告", "有问题找管理员"] }
|
|
15
|
+
* ]
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
* - `group`:适用群号列表(可多个群共用同一条欢迎语)
|
|
19
|
+
* - `msg`:欢迎语模板(字符串或字符串数组,数组每项一行,\n 拼接),
|
|
20
|
+
* `${at}` 会被替换为 @新成员 消息段
|
|
21
|
+
*/
|
|
22
|
+
export class Welcome {
|
|
23
|
+
/**
|
|
24
|
+
* 处理 group_increase 通知,匹配到该群的欢迎配置后发送欢迎消息。
|
|
25
|
+
*/
|
|
26
|
+
public static handleGroupIncreaseNotice(bot: QQBot, msg: GroupIncreaseNoticeWSMSG): void {
|
|
27
|
+
const config = getWelcomeConfig();
|
|
28
|
+
const entry = config.welcomes.find(item => item.group.includes(msg.group_id));
|
|
29
|
+
if (!entry) return;
|
|
30
|
+
const message = buildWelcomeMessage(msg.user_id, entry.msg);
|
|
31
|
+
bot.sendGroupMsg(msg.group_id, message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 将欢迎模板渲染成消息段数组:`${at}` 拆分为 @成员 消息段,
|
|
37
|
+
* 其余文本保持文本段(避免以字符串拼接 CQ 码)。
|
|
38
|
+
* `template` 可为字符串或字符串数组(数组按换行拼接为多行文本)。
|
|
39
|
+
*/
|
|
40
|
+
export function buildWelcomeMessage(qq: number, template: string | string[]): import('@/type').Message[] {
|
|
41
|
+
const text = Array.isArray(template) ? template.join('\n') : template;
|
|
42
|
+
const parts = text.split('${at}');
|
|
43
|
+
const messages: import('@/type').Message[] = [];
|
|
44
|
+
parts.forEach((part, index) => {
|
|
45
|
+
if (part) {
|
|
46
|
+
messages.push({ type: 'text', data: { text: part } });
|
|
47
|
+
}
|
|
48
|
+
// 在每段文本之后插入 @(除最后一段)
|
|
49
|
+
if (index < parts.length - 1) {
|
|
50
|
+
messages.push({ type: 'at', data: { qq } });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// 模板中无 ${at} 时的兜底:把 QQ 号附在末尾
|
|
54
|
+
if (messages.length === 0) {
|
|
55
|
+
messages.push({ type: 'text', data: { text: `欢迎新成员 ${qq} 加入群聊` } });
|
|
56
|
+
}
|
|
57
|
+
return messages;
|
|
58
58
|
}
|