koishi-plugin-group-verification 1.0.36 → 1.0.37
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/lib/index.js +42 -26
- package/package.json +1 -1
- package/src/index.ts +45 -28
package/lib/index.js
CHANGED
|
@@ -60,19 +60,23 @@ function clogV(msg, ...args) {
|
|
|
60
60
|
if (pluginLogLevel === "详细") logger.debug(msg, ...args);
|
|
61
61
|
}
|
|
62
62
|
__name(clogV, "clogV");
|
|
63
|
+
function renderMsg(tmpl) {
|
|
64
|
+
return tmpl.replace(/\\\\n/g, "").replace(/\\n/g, "\n").replace(/\x01/g, "\\n");
|
|
65
|
+
}
|
|
66
|
+
__name(renderMsg, "renderMsg");
|
|
63
67
|
var Config = import_koishi.Schema.object({
|
|
64
68
|
defaultReminderMessage: import_koishi.Schema.string().description("默认提醒消息模板(使用 \\n 表示换行,可包含下方变量)").default("{user}({id}) 申请入群\\n申请理由: {question}\\n匹配情况: {answer}/{threshold}\\n使用 gva 同意或 gvr 拒绝申请"),
|
|
65
69
|
enableStrictGroupCheck: import_koishi.Schema.boolean().description("是否启用严格的群号检查(检查群号长度)").default(false),
|
|
66
70
|
logLevel: import_koishi.Schema.union(["debug", "info", "warn"]).description("日志详细程度").default("info"),
|
|
67
71
|
// debug=详细, info=中等, warn=简洁
|
|
68
|
-
permissionDeniedMessage: import_koishi.Schema.string().description("
|
|
69
|
-
invalidGroupMessage: import_koishi.Schema.string().description("
|
|
70
|
-
parameterConflictMessage: import_koishi.Schema.string().description("
|
|
71
|
-
noKeywordsMessage: import_koishi.Schema.string().description("
|
|
72
|
-
blacklistAddSuccess: import_koishi.Schema.string().description(
|
|
73
|
-
blacklistRemoveSuccess: import_koishi.Schema.string().description(
|
|
74
|
-
blacklistListEmpty: import_koishi.Schema.string().description("
|
|
75
|
-
blacklistInfoTemplate: import_koishi.Schema.string().description("查询指定用户状态时的模板,可用 {global},{group}").default("全局黑名单: {global}
|
|
72
|
+
permissionDeniedMessage: import_koishi.Schema.string().description("权限不足时返回给调用者的提示,支持 \\n 换行").default("权限不足: 需要群主/管理员权限或koishi三级以上权限"),
|
|
73
|
+
invalidGroupMessage: import_koishi.Schema.string().description("无效群号或机器人未在该群时的提示,可用 {group},支持 \\n 换行").default("群号 {group} 格式不合法或机器人不在该群中"),
|
|
74
|
+
parameterConflictMessage: import_koishi.Schema.string().description("参数冲突时提示,支持 \\n 换行").default("参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)"),
|
|
75
|
+
noKeywordsMessage: import_koishi.Schema.string().description("未提供关键词且无法从现有配置继承时的提示,支持 \\n 换行").default("请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置"),
|
|
76
|
+
blacklistAddSuccess: import_koishi.Schema.string().description('将用户加入黑名单后的提示,可用 {user},{group},{reason};{group} 含"群"前缀(all时为"全局"),支持 \\n 换行').default("已将用户 {user} 加入{group}黑名单{reason}"),
|
|
77
|
+
blacklistRemoveSuccess: import_koishi.Schema.string().description('从黑名单移除用户后的提示,可用 {user},{group};{group} 含"群"前缀,支持 \\n 换行').default("已从{group}的黑名单中移除用户 {user}"),
|
|
78
|
+
blacklistListEmpty: import_koishi.Schema.string().description('黑名单为空时提示,可用 {group};{group} 含"群"前缀,支持 \\n 换行').default("{group}的黑名单为空"),
|
|
79
|
+
blacklistInfoTemplate: import_koishi.Schema.string().description("查询指定用户状态时的模板,可用 {global},{group},支持 \\n 换行").default("全局黑名单: {global}\\n本群黑名单: {group}")
|
|
76
80
|
}).description("群组验证插件配置");
|
|
77
81
|
var inject = ["database"];
|
|
78
82
|
var ESC_QUOTE = "\0";
|
|
@@ -442,6 +446,18 @@ async function handleGuildMemberRequestEvent(ctx, session) {
|
|
|
442
446
|
} catch (e) {
|
|
443
447
|
logger.warn("黑名单检查失败", e);
|
|
444
448
|
}
|
|
449
|
+
{
|
|
450
|
+
let resolvedName;
|
|
451
|
+
try {
|
|
452
|
+
const userInfo = await session.bot.getUser(userId);
|
|
453
|
+
if (userInfo?.name) resolvedName = userInfo.name;
|
|
454
|
+
} catch (_) {
|
|
455
|
+
}
|
|
456
|
+
if (!resolvedName && session.username && session.username !== userId) {
|
|
457
|
+
resolvedName = session.username;
|
|
458
|
+
}
|
|
459
|
+
session.username = resolvedName || userId;
|
|
460
|
+
}
|
|
445
461
|
const { isValid, matchedCount, requiredThreshold } = await verifyApplication(config, message, session);
|
|
446
462
|
clogV(`验证结果 guild=${guildId} user=${userId} msg="${message}" matched=${matchedCount} threshold=${requiredThreshold} valid=${isValid}`);
|
|
447
463
|
if (isValid) {
|
|
@@ -604,7 +620,7 @@ async function handleFailedVerification(ctx, session, config, matchedCount, requ
|
|
|
604
620
|
logger.warn("handleFailedVerification invoked without guildId, aborting");
|
|
605
621
|
return;
|
|
606
622
|
}
|
|
607
|
-
const username = session.username ||
|
|
623
|
+
const username = session.username || userId;
|
|
608
624
|
const message = session.content || "";
|
|
609
625
|
clog(
|
|
610
626
|
"debug",
|
|
@@ -716,7 +732,7 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
716
732
|
} else {
|
|
717
733
|
if (config?.enableStrictGroupCheck) {
|
|
718
734
|
if (!/^\d{5,15}$/.test(group)) {
|
|
719
|
-
return (config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group);
|
|
735
|
+
return renderMsg((config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group));
|
|
720
736
|
}
|
|
721
737
|
}
|
|
722
738
|
const [ok, err] = await checkPermission(session, group);
|
|
@@ -746,8 +762,9 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
746
762
|
logger.warn(`踢出用户 ${targetUser} 失败`, e);
|
|
747
763
|
}
|
|
748
764
|
}
|
|
749
|
-
const tmpl = config && config.blacklistAddSuccess || "已将用户 {user}
|
|
750
|
-
|
|
765
|
+
const tmpl = config && config.blacklistAddSuccess || "已将用户 {user} 加入{group}黑名单{reason}";
|
|
766
|
+
const groupLabelA = group.toLowerCase() === "all" ? "全局" : "群 " + group;
|
|
767
|
+
return renderMsg(tmpl.replace("{user}", targetUser).replace("{group}", groupLabelA).replace("{reason}", reason ? `,原因: ${reason}` : ""));
|
|
751
768
|
}
|
|
752
769
|
if (op === "r") {
|
|
753
770
|
targetUser = parts[1];
|
|
@@ -760,7 +777,7 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
760
777
|
} else {
|
|
761
778
|
if (config?.enableStrictGroupCheck) {
|
|
762
779
|
if (!/^\d{5,15}$/.test(group)) {
|
|
763
|
-
return (config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group);
|
|
780
|
+
return renderMsg((config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group));
|
|
764
781
|
}
|
|
765
782
|
}
|
|
766
783
|
const [ok, err] = await checkPermission(session, group);
|
|
@@ -773,8 +790,9 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
773
790
|
delete entries[targetUser];
|
|
774
791
|
await ctx.database.set("group_verification_blacklist", { id: row.id }, { entries });
|
|
775
792
|
}
|
|
776
|
-
const tmpl = config && config.blacklistRemoveSuccess || "
|
|
777
|
-
|
|
793
|
+
const tmpl = config && config.blacklistRemoveSuccess || "已从{group}的黑名单中移除用户 {user}";
|
|
794
|
+
const groupLabelR = group.toLowerCase() === "all" ? "全局" : "群 " + group;
|
|
795
|
+
return renderMsg(tmpl.replace("{user}", targetUser).replace("{group}", groupLabelR));
|
|
778
796
|
}
|
|
779
797
|
if (op === "l") {
|
|
780
798
|
group = parts[1] || getCurrentGroup();
|
|
@@ -785,7 +803,7 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
785
803
|
} else {
|
|
786
804
|
if (config?.enableStrictGroupCheck) {
|
|
787
805
|
if (!/^\d{5,15}$/.test(group)) {
|
|
788
|
-
return (config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group);
|
|
806
|
+
return renderMsg((config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", group));
|
|
789
807
|
}
|
|
790
808
|
}
|
|
791
809
|
const [ok, err] = await checkPermission(session, group);
|
|
@@ -793,11 +811,9 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
793
811
|
}
|
|
794
812
|
const rows = await ctx.database.get("group_verification_blacklist", { groupId: group });
|
|
795
813
|
if (rows.length === 0) {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
}
|
|
799
|
-
const tmpl = config && config.blacklistListEmpty || "群 {group} 的黑名单为空";
|
|
800
|
-
return tmpl.replace("{group}", group);
|
|
814
|
+
const tmpl = config && config.blacklistListEmpty || "{group}的黑名单为空";
|
|
815
|
+
const groupLabelL = group && group.toLowerCase() === "all" ? "全局" : "群 " + group;
|
|
816
|
+
return renderMsg(tmpl.replace("{group}", groupLabelL));
|
|
801
817
|
}
|
|
802
818
|
const entries = rows[0].entries || {};
|
|
803
819
|
let prefix = group && group.toLowerCase() === "all" ? "全局黑名单: \n" : `群 ${group} 黑名单:
|
|
@@ -815,7 +831,7 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
815
831
|
const groupArg = parts[2];
|
|
816
832
|
const globalRows = await ctx.database.get("group_verification_blacklist", { groupId: "all" });
|
|
817
833
|
const globalHit = globalRows.length > 0 && (globalRows[0].entries || {})[targetUser] !== void 0;
|
|
818
|
-
const tmpl = config && config.blacklistInfoTemplate || "全局黑名单: {global}
|
|
834
|
+
const tmpl = (config && config.blacklistInfoTemplate || "全局黑名单: {global}\\n本群黑名单: {group}").replace(/\\\\n/g, "").replace(/\\n/g, "\n").replace(/\x01/g, "\\n");
|
|
819
835
|
const formatReply = /* @__PURE__ */ __name((localHit, groupsList) => {
|
|
820
836
|
if (groupsList) {
|
|
821
837
|
return tmpl.replace("{global}", globalHit ? "有" : "无").replace(
|
|
@@ -860,7 +876,7 @@ async function processBlacklistCommand(ctx, session, rawArgs, config) {
|
|
|
860
876
|
const groupId = groupArg;
|
|
861
877
|
if (config?.enableStrictGroupCheck && groupId.toLowerCase() !== "all") {
|
|
862
878
|
if (!/^\d{5,15}$/.test(groupId)) {
|
|
863
|
-
return (config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", groupId);
|
|
879
|
+
return renderMsg((config.invalidGroupMessage || "群号 {group} 格式不合法或机器人不在该群中").replace("{group}", groupId));
|
|
864
880
|
}
|
|
865
881
|
}
|
|
866
882
|
const [ok, err] = await checkPermission(session, groupId);
|
|
@@ -1008,7 +1024,7 @@ function apply(ctx, config) {
|
|
|
1008
1024
|
return [false, `无法获取群 ${groupId} 的成员信息,请确认机器人已在该群中`];
|
|
1009
1025
|
}
|
|
1010
1026
|
clogV(`权限检查 - 权限不足`);
|
|
1011
|
-
return [false, config.permissionDeniedMessage || "权限不足: 需要群主/管理员权限或koishi三级以上权限"];
|
|
1027
|
+
return [false, renderMsg(config.permissionDeniedMessage || "权限不足: 需要群主/管理员权限或koishi三级以上权限")];
|
|
1012
1028
|
}
|
|
1013
1029
|
__name(checkPermission2, "checkPermission");
|
|
1014
1030
|
const groupVerify = ctx.command("group-verify", "群组验证管理命令").alias("gv", "gverify");
|
|
@@ -1046,7 +1062,7 @@ function apply(ctx, config) {
|
|
|
1046
1062
|
clogV(`合并后options: ${JSON.stringify(cleanedOptions, null, 2)}
|
|
1047
1063
|
`);
|
|
1048
1064
|
if ((cleanedOptions.query || cleanedOptions.remove) && (parsedKeywords.length > 0 || cleanedOptions.method !== void 0 || cleanedOptions.threshold !== void 0 || cleanedOptions.message !== void 0 || cleanedOptions.enableMessage || cleanedOptions.disableMessage)) {
|
|
1049
|
-
return config.parameterConflictMessage || "参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)";
|
|
1065
|
+
return renderMsg(config.parameterConflictMessage || "参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)");
|
|
1050
1066
|
}
|
|
1051
1067
|
const hasRealMessageParam = cleanedOptions.message !== void 0;
|
|
1052
1068
|
const hasRealEnableMessageParam = cleanedOptions.enableMessage === true;
|
|
@@ -1160,7 +1176,7 @@ ${displayMsg}
|
|
|
1160
1176
|
}
|
|
1161
1177
|
if (keywordList.length === 0 && !cleanedOptions.query && !cleanedOptions.remove) {
|
|
1162
1178
|
if (!existingConfig) {
|
|
1163
|
-
return config.noKeywordsMessage || "请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置";
|
|
1179
|
+
return renderMsg(config.noKeywordsMessage || "请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置");
|
|
1164
1180
|
}
|
|
1165
1181
|
keywordList = existingConfig.keywords;
|
|
1166
1182
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -35,6 +35,11 @@ function clogV(msg: string, ...args: any[]): void {
|
|
|
35
35
|
if (pluginLogLevel === '详细') logger.debug(msg, ...args)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** 处理配置文本中的换行转义:\n→换行,\\n→字面量 \n */
|
|
39
|
+
function renderMsg(tmpl: string): string {
|
|
40
|
+
return tmpl.replace(/\\\\n/g, '\x01').replace(/\\n/g, '\n').replace(/\x01/g, '\\n')
|
|
41
|
+
}
|
|
42
|
+
|
|
38
43
|
// 数据库模型定义
|
|
39
44
|
declare module 'koishi' {
|
|
40
45
|
interface Tables {
|
|
@@ -114,14 +119,14 @@ export const Config: Schema<Config> = Schema.object({
|
|
|
114
119
|
.default('{user}({id}) 申请入群\\n申请理由: {question}\\n匹配情况: {answer}/{threshold}\\n使用 gva 同意或 gvr 拒绝申请'),
|
|
115
120
|
enableStrictGroupCheck: Schema.boolean().description('是否启用严格的群号检查(检查群号长度)').default(false),
|
|
116
121
|
logLevel: Schema.union(['debug', 'info', 'warn']).description('日志详细程度').default('info'), // debug=详细, info=中等, warn=简洁
|
|
117
|
-
permissionDeniedMessage: Schema.string().description('
|
|
118
|
-
invalidGroupMessage: Schema.string().description('
|
|
119
|
-
parameterConflictMessage: Schema.string().description('
|
|
120
|
-
noKeywordsMessage: Schema.string().description('
|
|
121
|
-
blacklistAddSuccess: Schema.string().description('
|
|
122
|
-
blacklistRemoveSuccess: Schema.string().description('
|
|
123
|
-
blacklistListEmpty: Schema.string().description('
|
|
124
|
-
blacklistInfoTemplate: Schema.string().description('查询指定用户状态时的模板,可用 {global},{group}').default('全局黑名单: {global}
|
|
122
|
+
permissionDeniedMessage: Schema.string().description('权限不足时返回给调用者的提示,支持 \\n 换行').default('权限不足: 需要群主/管理员权限或koishi三级以上权限'),
|
|
123
|
+
invalidGroupMessage: Schema.string().description('无效群号或机器人未在该群时的提示,可用 {group},支持 \\n 换行').default('群号 {group} 格式不合法或机器人不在该群中'),
|
|
124
|
+
parameterConflictMessage: Schema.string().description('参数冲突时提示,支持 \\n 换行').default('参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)'),
|
|
125
|
+
noKeywordsMessage: Schema.string().description('未提供关键词且无法从现有配置继承时的提示,支持 \\n 换行').default('请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置'),
|
|
126
|
+
blacklistAddSuccess: Schema.string().description('将用户加入黑名单后的提示,可用 {user},{group},{reason};{group} 含"群"前缀(all时为"全局"),支持 \\n 换行').default('已将用户 {user} 加入{group}黑名单{reason}'),
|
|
127
|
+
blacklistRemoveSuccess: Schema.string().description('从黑名单移除用户后的提示,可用 {user},{group};{group} 含"群"前缀,支持 \\n 换行').default('已从{group}的黑名单中移除用户 {user}'),
|
|
128
|
+
blacklistListEmpty: Schema.string().description('黑名单为空时提示,可用 {group};{group} 含"群"前缀,支持 \\n 换行').default('{group}的黑名单为空'),
|
|
129
|
+
blacklistInfoTemplate: Schema.string().description('查询指定用户状态时的模板,可用 {global},{group},支持 \\n 换行').default('全局黑名单: {global}\\n本群黑名单: {group}')
|
|
125
130
|
})
|
|
126
131
|
.description('群组验证插件配置')
|
|
127
132
|
|
|
@@ -604,6 +609,19 @@ export async function handleGuildMemberRequestEvent(ctx: Context, session: any)
|
|
|
604
609
|
logger.warn('黑名单检查失败', e);
|
|
605
610
|
}
|
|
606
611
|
|
|
612
|
+
// 解析用户昵称优先级:1) API拉取昵称 2) session.username(若非userId) 3) userId
|
|
613
|
+
{
|
|
614
|
+
let resolvedName: string | undefined
|
|
615
|
+
try {
|
|
616
|
+
const userInfo = await session.bot.getUser(userId)
|
|
617
|
+
if (userInfo?.name) resolvedName = userInfo.name
|
|
618
|
+
} catch (_) {}
|
|
619
|
+
if (!resolvedName && session.username && session.username !== userId) {
|
|
620
|
+
resolvedName = session.username
|
|
621
|
+
}
|
|
622
|
+
session.username = resolvedName || userId
|
|
623
|
+
}
|
|
624
|
+
|
|
607
625
|
const { isValid, matchedCount, requiredThreshold } = await verifyApplication(config, message, session);
|
|
608
626
|
clogV(`验证结果 guild=${guildId} user=${userId} msg="${message}" matched=${matchedCount} threshold=${requiredThreshold} valid=${isValid}`);
|
|
609
627
|
|
|
@@ -803,7 +821,7 @@ export async function handleFailedVerification(
|
|
|
803
821
|
logger.warn('handleFailedVerification invoked without guildId, aborting')
|
|
804
822
|
return
|
|
805
823
|
}
|
|
806
|
-
const username = session.username ||
|
|
824
|
+
const username = session.username || userId
|
|
807
825
|
const message = session.content || ''
|
|
808
826
|
clog('debug', `待审核: guild=${guildId} user=${userId} matched=${matchedCount}/${requiredThreshold}`,
|
|
809
827
|
`处理失败验证 guild=${guildId} user=${userId} msg="${session.content || ''}" matched=${matchedCount} threshold=${requiredThreshold}`)
|
|
@@ -955,7 +973,7 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
955
973
|
// 严格群号检查(若开启)
|
|
956
974
|
if (config?.enableStrictGroupCheck) {
|
|
957
975
|
if (!/^\d{5,15}$/.test(group)) {
|
|
958
|
-
return (config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group)
|
|
976
|
+
return renderMsg((config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group))
|
|
959
977
|
}
|
|
960
978
|
}
|
|
961
979
|
const [ok, err] = await checkPermission(session, group)
|
|
@@ -988,8 +1006,9 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
988
1006
|
logger.warn(`踢出用户 ${targetUser} 失败`, e)
|
|
989
1007
|
}
|
|
990
1008
|
}
|
|
991
|
-
const tmpl = (config && config.blacklistAddSuccess) || '已将用户 {user}
|
|
992
|
-
|
|
1009
|
+
const tmpl = (config && config.blacklistAddSuccess) || '已将用户 {user} 加入{group}黑名单{reason}'
|
|
1010
|
+
const groupLabelA = group.toLowerCase() === 'all' ? '全局' : '群 ' + group
|
|
1011
|
+
return renderMsg(tmpl.replace('{user}', targetUser).replace('{group}', groupLabelA).replace('{reason}', reason ? `,原因: ${reason}` : ''))
|
|
993
1012
|
}
|
|
994
1013
|
if (op === 'r') {
|
|
995
1014
|
targetUser = parts[1]
|
|
@@ -1002,7 +1021,7 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1002
1021
|
} else {
|
|
1003
1022
|
if (config?.enableStrictGroupCheck) {
|
|
1004
1023
|
if (!/^\d{5,15}$/.test(group)) {
|
|
1005
|
-
return (config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group)
|
|
1024
|
+
return renderMsg((config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group))
|
|
1006
1025
|
}
|
|
1007
1026
|
}
|
|
1008
1027
|
const [ok, err] = await checkPermission(session, group)
|
|
@@ -1015,8 +1034,9 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1015
1034
|
delete entries[targetUser]
|
|
1016
1035
|
await ctx.database.set('group_verification_blacklist', { id: row.id }, { entries })
|
|
1017
1036
|
}
|
|
1018
|
-
const tmpl = (config && config.blacklistRemoveSuccess) || '
|
|
1019
|
-
|
|
1037
|
+
const tmpl = (config && config.blacklistRemoveSuccess) || '已从{group}的黑名单中移除用户 {user}'
|
|
1038
|
+
const groupLabelR = group.toLowerCase() === 'all' ? '全局' : '群 ' + group
|
|
1039
|
+
return renderMsg(tmpl.replace('{user}', targetUser).replace('{group}', groupLabelR))
|
|
1020
1040
|
}
|
|
1021
1041
|
if (op === 'l') {
|
|
1022
1042
|
group = parts[1] || getCurrentGroup()
|
|
@@ -1027,7 +1047,7 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1027
1047
|
} else {
|
|
1028
1048
|
if (config?.enableStrictGroupCheck) {
|
|
1029
1049
|
if (!/^\d{5,15}$/.test(group)) {
|
|
1030
|
-
return (config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group)
|
|
1050
|
+
return renderMsg((config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', group))
|
|
1031
1051
|
}
|
|
1032
1052
|
}
|
|
1033
1053
|
const [ok, err] = await checkPermission(session, group)
|
|
@@ -1035,13 +1055,9 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1035
1055
|
}
|
|
1036
1056
|
const rows = await ctx.database.get('group_verification_blacklist', { groupId: group })
|
|
1037
1057
|
if (rows.length === 0) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
return '全局黑名单为空'
|
|
1042
|
-
}
|
|
1043
|
-
const tmpl = (config && config.blacklistListEmpty) || '群 {group} 的黑名单为空'
|
|
1044
|
-
return tmpl.replace('{group}', group)
|
|
1058
|
+
const tmpl = (config && config.blacklistListEmpty) || '{group}的黑名单为空'
|
|
1059
|
+
const groupLabelL = group && group.toLowerCase() === 'all' ? '全局' : '群 ' + group
|
|
1060
|
+
return renderMsg(tmpl.replace('{group}', groupLabelL))
|
|
1045
1061
|
}
|
|
1046
1062
|
const entries = rows[0].entries || {}
|
|
1047
1063
|
// 构造列表消息,all 也是专用前缀
|
|
@@ -1060,7 +1076,8 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1060
1076
|
const globalHit = globalRows.length > 0 && (globalRows[0].entries || {})[targetUser] !== undefined
|
|
1061
1077
|
|
|
1062
1078
|
// 使用模板格式化回复的辅助函数
|
|
1063
|
-
const tmpl = (config && config.blacklistInfoTemplate) || '全局黑名单: {global}
|
|
1079
|
+
const tmpl = ((config && config.blacklistInfoTemplate) || '全局黑名单: {global}\\n本群黑名单: {group}')
|
|
1080
|
+
.replace(/\\\\n/g, '\x01').replace(/\\n/g, '\n').replace(/\x01/g, '\\n')
|
|
1064
1081
|
const formatReply = (localHit: boolean, groupsList?: string[]) => {
|
|
1065
1082
|
if (groupsList) {
|
|
1066
1083
|
return tmpl.replace('{global}', globalHit ? '有' : '无').replace(
|
|
@@ -1109,7 +1126,7 @@ export async function processBlacklistCommand(ctx: Context, session: any, rawArg
|
|
|
1109
1126
|
const groupId = groupArg
|
|
1110
1127
|
if (config?.enableStrictGroupCheck && groupId.toLowerCase() !== 'all') {
|
|
1111
1128
|
if (!/^\d{5,15}$/.test(groupId)) {
|
|
1112
|
-
return (config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', groupId)
|
|
1129
|
+
return renderMsg((config.invalidGroupMessage || '群号 {group} 格式不合法或机器人不在该群中').replace('{group}', groupId))
|
|
1113
1130
|
}
|
|
1114
1131
|
}
|
|
1115
1132
|
const [ok, err] = await checkPermission(session, groupId)
|
|
@@ -1294,7 +1311,7 @@ export function apply(ctx: Context, config: Config) {
|
|
|
1294
1311
|
}
|
|
1295
1312
|
|
|
1296
1313
|
clogV(`权限检查 - 权限不足`)
|
|
1297
|
-
return [false, config.permissionDeniedMessage || '权限不足: 需要群主/管理员权限或koishi三级以上权限']
|
|
1314
|
+
return [false, renderMsg(config.permissionDeniedMessage || '权限不足: 需要群主/管理员权限或koishi三级以上权限')]
|
|
1298
1315
|
}
|
|
1299
1316
|
|
|
1300
1317
|
// 创建主命令及别名
|
|
@@ -1355,7 +1372,7 @@ export function apply(ctx: Context, config: Config) {
|
|
|
1355
1372
|
if ((cleanedOptions.query || cleanedOptions.remove) &&
|
|
1356
1373
|
(parsedKeywords.length > 0 || cleanedOptions.method !== undefined || cleanedOptions.threshold !== undefined ||
|
|
1357
1374
|
cleanedOptions.message !== undefined || cleanedOptions.enableMessage || cleanedOptions.disableMessage)) {
|
|
1358
|
-
return config.parameterConflictMessage || '参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)'
|
|
1375
|
+
return renderMsg(config.parameterConflictMessage || '参数冲突: -? 或 -r 不能与其他参数或关键词一起使用(仅可搭配 -i)')
|
|
1359
1376
|
}
|
|
1360
1377
|
|
|
1361
1378
|
// 检查消息参数冲突
|
|
@@ -1511,7 +1528,7 @@ export function apply(ctx: Context, config: Config) {
|
|
|
1511
1528
|
// 处理关键词: 如果没有关键词但有其他参数,从现有配置中获取
|
|
1512
1529
|
if (keywordList.length === 0 && !cleanedOptions.query && !cleanedOptions.remove) {
|
|
1513
1530
|
if (!existingConfig) {
|
|
1514
|
-
return config.noKeywordsMessage || '请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置'
|
|
1531
|
+
return renderMsg(config.noKeywordsMessage || '请先提供关键词创建配置,或使用 -? 查询配置,-r 删除配置')
|
|
1515
1532
|
}
|
|
1516
1533
|
keywordList = existingConfig.keywords
|
|
1517
1534
|
}
|