@koishi-ce/plugin-callme 1.0.0 → 1.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/README.md +82 -0
- package/lib/assets/{zh-CN-Vuobuf_Z.yml → zh-CN-DvjQLXEL.yml} +3 -0
- package/lib/index.d.ts +6 -7
- package/lib/index.mjs +1 -1
- package/locales/de-DE.yml +12 -9
- package/locales/en-US.yml +12 -9
- package/locales/fr-FR.yml +12 -9
- package/locales/ja-JP.yml +12 -9
- package/locales/ru-RU.yml +12 -9
- package/locales/zh-CN.yml +3 -0
- package/locales/zh-TW.yml +3 -0
- package/package.json +3 -3
- package/src/index.test.ts +143 -0
- package/src/index.ts +18 -3
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @koishi-ce/plugin-callme
|
|
2
|
+
|
|
3
|
+
**简体中文** | [English](#english)
|
|
4
|
+
|
|
5
|
+
用户昵称插件,移植自上游 [koishijs/koishi](https://github.com/koishijs/koishi) 的 `plugins/common/callme`。用户可以查询或设置自己在机器人处的称呼,称呼会显示在部分插件的回复中。
|
|
6
|
+
|
|
7
|
+
## 指令
|
|
8
|
+
|
|
9
|
+
| 指令 | 权限 | 说明 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `callme [name:text]` | 1 | 查询或设置当前用户的称呼,别名 `nn`,并注册快捷调用「叫我 XX」 |
|
|
12
|
+
|
|
13
|
+
- 不带参数时查询当前称呼。
|
|
14
|
+
- 新称呼与其他用户重名时会拒绝修改。
|
|
15
|
+
|
|
16
|
+
## 配置项
|
|
17
|
+
|
|
18
|
+
本插件无需配置。
|
|
19
|
+
|
|
20
|
+
## 用法
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun add @koishi-ce/plugin-callme
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
也可以在控制台的插件市场中直接安装。随后在配置文件中启用:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
plugins:
|
|
30
|
+
callme: {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 备注
|
|
34
|
+
|
|
35
|
+
- 依赖数据库服务(读写内置 `user` 表的 `name` 字段)。
|
|
36
|
+
- 昵称仅保留纯文本,其余消息元素会被自动剥离。
|
|
37
|
+
- 其他插件可以通过 `common/callme` 事件(`ctx.bail`)返回字符串来拦截昵称修改。
|
|
38
|
+
|
|
39
|
+
## 许可证
|
|
40
|
+
|
|
41
|
+
[MIT](https://github.com/Koishi-CE/koishi/blob/main/LICENSE)。本包是上游 koishijs/koishi 的社区再分发,版权归属见 [NOTICE](https://github.com/Koishi-CE/koishi/blob/main/NOTICE)。
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## English
|
|
46
|
+
|
|
47
|
+
A nickname plugin, ported from `plugins/common/callme` of the upstream [koishijs/koishi](https://github.com/koishijs/koishi) repository. Users can query or set the nickname the bot uses for them.
|
|
48
|
+
|
|
49
|
+
## Commands
|
|
50
|
+
|
|
51
|
+
| Command | Authority | Description |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `callme [name:text]` | 1 | Query or set the current user's nickname; alias `nn`, with the shortcut "叫我 XX" (Chinese only) |
|
|
54
|
+
|
|
55
|
+
Calling it without arguments queries the current nickname; duplicate nicknames are rejected.
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
None.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun add @koishi-ce/plugin-callme
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The plugin can also be installed from the console plugin market, then enabled in the config file:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
plugins:
|
|
71
|
+
callme: {}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
|
|
76
|
+
- Requires the database service (reads and writes the `name` field of the built-in `user` table).
|
|
77
|
+
- Nicknames are reduced to plain text; other message elements are stripped.
|
|
78
|
+
- Other plugins may intercept nickname changes by returning a string from the `common/callme` event (`ctx.bail`).
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
[MIT](https://github.com/Koishi-CE/koishi/blob/main/LICENSE). This package is a community redistribution of upstream koishijs/koishi; see [NOTICE](https://github.com/Koishi-CE/koishi/blob/main/NOTICE) for attribution.
|
package/lib/index.d.ts
CHANGED
|
@@ -6,10 +6,9 @@ declare module "@koishi-ce/koishi" {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
/** 配置项(当前无可用配置) */
|
|
9
|
-
type Config = Record<never, never>;
|
|
10
|
-
declare const name = "callme";
|
|
11
|
-
declare const inject: string[];
|
|
12
|
-
declare const Config: Schema<Config>;
|
|
13
|
-
declare function apply(ctx: Context): void;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { Config, apply, inject, name };
|
|
9
|
+
export type Config = Record<never, never>;
|
|
10
|
+
export declare const name = "callme";
|
|
11
|
+
export declare const inject: string[];
|
|
12
|
+
export declare const Config: Schema<Config>;
|
|
13
|
+
export declare function apply(ctx: Context): void;
|
|
14
|
+
//#endregion
|
package/lib/index.mjs
CHANGED
package/locales/de-DE.yml
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
|
|
1
4
|
commands:
|
|
2
5
|
callme:
|
|
3
|
-
description:
|
|
6
|
+
description: Eigenen Spitznamen ändern
|
|
4
7
|
messages:
|
|
5
|
-
current:
|
|
6
|
-
unnamed:
|
|
7
|
-
unchanged:
|
|
8
|
-
empty:
|
|
9
|
-
invalid:
|
|
10
|
-
duplicate:
|
|
11
|
-
updated:
|
|
12
|
-
failed:
|
|
8
|
+
current: Na klar, {0}!
|
|
9
|
+
unnamed: Sie haben sich noch keinen Spitznamen gegeben~
|
|
10
|
+
unchanged: Der Spitzname hat sich nicht geändert.
|
|
11
|
+
empty: Der Spitzname darf nicht leer sein.
|
|
12
|
+
invalid: Der Spitzname darf nur reinen Text enthalten.
|
|
13
|
+
duplicate: Der Spitzname darf nicht bereits von einem anderen Benutzer verwendet werden.
|
|
14
|
+
updated: Alles klar, {0}, freut mich, Sie kennenzulernen!
|
|
15
|
+
failed: Der Spitzname konnte nicht geändert werden.
|
package/locales/en-US.yml
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
|
|
1
4
|
commands:
|
|
2
5
|
callme:
|
|
3
|
-
description:
|
|
6
|
+
description: Change your nickname
|
|
4
7
|
messages:
|
|
5
|
-
current:
|
|
6
|
-
unnamed:
|
|
7
|
-
unchanged:
|
|
8
|
-
empty:
|
|
9
|
-
invalid:
|
|
10
|
-
duplicate:
|
|
11
|
-
updated:
|
|
12
|
-
failed:
|
|
8
|
+
current: Okay, {0}!
|
|
9
|
+
unnamed: You haven't set a nickname for yourself yet~
|
|
10
|
+
unchanged: Nickname unchanged.
|
|
11
|
+
empty: Nickname cannot be empty.
|
|
12
|
+
invalid: The nickname must not contain anything other than plain text.
|
|
13
|
+
duplicate: This nickname is already taken by another user.
|
|
14
|
+
updated: Alright, {0}, nice to meet you!
|
|
15
|
+
failed: Failed to change your nickname.
|
package/locales/fr-FR.yml
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
|
|
1
4
|
commands:
|
|
2
5
|
callme:
|
|
3
|
-
description:
|
|
6
|
+
description: Modifier votre surnom
|
|
4
7
|
messages:
|
|
5
|
-
current:
|
|
6
|
-
unnamed:
|
|
7
|
-
unchanged:
|
|
8
|
-
empty:
|
|
9
|
-
invalid:
|
|
10
|
-
duplicate:
|
|
11
|
-
updated:
|
|
12
|
-
failed:
|
|
8
|
+
current: "Entendu, {0} !"
|
|
9
|
+
unnamed: Vous ne vous êtes pas encore choisi de surnom~
|
|
10
|
+
unchanged: Le surnom n'a pas changé.
|
|
11
|
+
empty: Le surnom ne peut pas être vide.
|
|
12
|
+
invalid: Le surnom ne doit contenir que du texte brut.
|
|
13
|
+
duplicate: Ce surnom est déjà utilisé par un autre utilisateur.
|
|
14
|
+
updated: "Très bien, {0}, ravi de faire votre connaissance !"
|
|
15
|
+
failed: Échec de la modification du surnom.
|
package/locales/ja-JP.yml
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
|
|
1
4
|
commands:
|
|
2
5
|
callme:
|
|
3
|
-
description:
|
|
6
|
+
description: 自分の呼び名を変更する
|
|
4
7
|
messages:
|
|
5
|
-
current:
|
|
6
|
-
unnamed:
|
|
7
|
-
unchanged:
|
|
8
|
-
empty:
|
|
9
|
-
invalid:
|
|
10
|
-
duplicate:
|
|
11
|
-
updated:
|
|
12
|
-
failed:
|
|
8
|
+
current: わかったよ、{0}!
|
|
9
|
+
unnamed: まだ自分の呼び名を設定していないよ〜
|
|
10
|
+
unchanged: 呼び名は変更されていません。
|
|
11
|
+
empty: 呼び名は空にできません。
|
|
12
|
+
invalid: 呼び名にはプレーンテキスト以外の内容を含めることはできません。
|
|
13
|
+
duplicate: 他のユーザーと同じ呼び名は使用できません。
|
|
14
|
+
updated: わかった、{0}、これからよろしく!
|
|
15
|
+
failed: 呼び名の変更に失敗しました。
|
package/locales/ru-RU.yml
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
|
|
1
4
|
commands:
|
|
2
5
|
callme:
|
|
3
|
-
description:
|
|
6
|
+
description: Изменить своё обращение
|
|
4
7
|
messages:
|
|
5
|
-
current:
|
|
6
|
-
unnamed:
|
|
7
|
-
unchanged:
|
|
8
|
-
empty:
|
|
9
|
-
invalid:
|
|
10
|
-
duplicate:
|
|
11
|
-
updated:
|
|
12
|
-
failed:
|
|
8
|
+
current: Конечно, {0}!
|
|
9
|
+
unnamed: Вы ещё не задали себе обращение~
|
|
10
|
+
unchanged: Обращение не изменилось.
|
|
11
|
+
empty: Обращение не может быть пустым.
|
|
12
|
+
invalid: Обращение не должно содержать ничего, кроме простого текста.
|
|
13
|
+
duplicate: Это обращение уже используется другим пользователем.
|
|
14
|
+
updated: Хорошо, {0}, приятно познакомиться!
|
|
15
|
+
failed: Не удалось изменить обращение.
|
package/locales/zh-CN.yml
CHANGED
package/locales/zh-TW.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koishi-ce/plugin-callme",
|
|
3
3
|
"description": "Set User Nickname in Koishi",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.mjs",
|
|
7
7
|
"typings": "lib/index.d.ts",
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
]
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"koishi": "^
|
|
50
|
+
"@koishi-ce/koishi": "^1.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@koishi-ce/plugin-mock": "^1.0.0",
|
|
54
|
-
"@koishi-ce/koishi": "^1.0.
|
|
54
|
+
"@koishi-ce/koishi": "^1.0.8"
|
|
55
55
|
},
|
|
56
56
|
"exports": {
|
|
57
57
|
".": {
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2026-present Koishi-CE contributors.
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
afterAll,
|
|
6
|
+
beforeAll,
|
|
7
|
+
describe,
|
|
8
|
+
expect,
|
|
9
|
+
it,
|
|
10
|
+
} from "bun:test";
|
|
11
|
+
import {
|
|
12
|
+
App,
|
|
13
|
+
Database,
|
|
14
|
+
Logger,
|
|
15
|
+
RuntimeError,
|
|
16
|
+
} from "@koishi-ce/koishi";
|
|
17
|
+
import mock from "@koishi-ce/plugin-mock";
|
|
18
|
+
// 同 admin 既有测试:CJS 实现配 ESM 声明,nodenext 互操作视图多包一层 default,转型取真实插件对象
|
|
19
|
+
import * as memoryModule from "@koishijs/plugin-database-memory";
|
|
20
|
+
import * as callme from "./index.ts";
|
|
21
|
+
|
|
22
|
+
const memory =
|
|
23
|
+
memoryModule.default as unknown as typeof memoryModule.default.default;
|
|
24
|
+
|
|
25
|
+
const app = new App();
|
|
26
|
+
|
|
27
|
+
app.plugin(memory);
|
|
28
|
+
app.plugin(mock);
|
|
29
|
+
app.plugin(callme);
|
|
30
|
+
|
|
31
|
+
const client = app.mock.client("123");
|
|
32
|
+
|
|
33
|
+
beforeAll(async () => {
|
|
34
|
+
await app.start();
|
|
35
|
+
// 预建用户,确保后续会话走 set 更新路径而非自动 createUser
|
|
36
|
+
await app.mock.initUser("123", 1);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
afterAll(async () => {
|
|
40
|
+
await app.stop();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("callme 指令", () => {
|
|
44
|
+
it("未设置称呼时提示未命名", async () => {
|
|
45
|
+
const replies = await client.receive("callme");
|
|
46
|
+
expect(replies[0]).toBe("你还没有给自己起一个称呼呢~");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("设置称呼后回执新称呼并落库", async () => {
|
|
50
|
+
const replies = await client.receive("callme 小明");
|
|
51
|
+
expect(replies[0]).toBe("好的,小明,请多指教!");
|
|
52
|
+
const user = await app.database.getUser("mock", "123");
|
|
53
|
+
expect(user?.name).toBe("小明");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("重复查询显示当前称呼", async () => {
|
|
57
|
+
const replies = await client.receive("nn");
|
|
58
|
+
expect(replies[0]).toBe("好的呢,小明!");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("称呼未变化时提示 unchanged", async () => {
|
|
62
|
+
const replies = await client.receive("callme 小明");
|
|
63
|
+
expect(replies[0]).toBe("称呼未发生变化。");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("纯文本以外的内容剥离后为空时提示 empty", async () => {
|
|
67
|
+
const replies = await client.receive(
|
|
68
|
+
'callme <image url="x"/>',
|
|
69
|
+
);
|
|
70
|
+
expect(replies[0]).toBe("称呼不能为空。");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("common/callme 事件监听者返回字符串可拦截修改", async () => {
|
|
74
|
+
const dispose = app.on(
|
|
75
|
+
"common/callme",
|
|
76
|
+
(name) => `禁止设置称呼:${name}`,
|
|
77
|
+
);
|
|
78
|
+
const replies = await client.receive("callme 小红");
|
|
79
|
+
dispose();
|
|
80
|
+
expect(replies[0]).toBe("禁止设置称呼:小红");
|
|
81
|
+
// 拦截路径不应写入数据库
|
|
82
|
+
const user = await app.database.getUser("mock", "123");
|
|
83
|
+
expect(user?.name).toBe("小明");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("快捷方式「叫我」在称呼机器人后可免指令名调用", async () => {
|
|
87
|
+
// shortcut 带 prefix: true,要求消息以 @机器人 的称呼开头
|
|
88
|
+
const replies = await client.receive(
|
|
89
|
+
'<at id="514"/>叫我小红',
|
|
90
|
+
);
|
|
91
|
+
expect(replies[0]).toBe("好的,小红,请多指教!");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("监听者返回空字符串时不拦截", async () => {
|
|
95
|
+
const dispose = app.on("common/callme", () => "");
|
|
96
|
+
const replies = await client.receive("callme 小刚");
|
|
97
|
+
dispose();
|
|
98
|
+
expect(replies[0]).toBe("好的,小刚,请多指教!");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("落库遇到 duplicate-entry 错误时给出重名提示", async () => {
|
|
102
|
+
const proto = Database.prototype as unknown as Record<
|
|
103
|
+
string,
|
|
104
|
+
(...args: unknown[]) => Promise<unknown>
|
|
105
|
+
>;
|
|
106
|
+
const original = proto["set"];
|
|
107
|
+
// RuntimeError.check 以 message 精确匹配 code 字符串
|
|
108
|
+
proto["set"] = async () => {
|
|
109
|
+
throw new RuntimeError(
|
|
110
|
+
"duplicate-entry",
|
|
111
|
+
"duplicate-entry",
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
const replies = await client
|
|
115
|
+
.receive("callme 小亮")
|
|
116
|
+
.finally(() => {
|
|
117
|
+
proto["set"] = original!;
|
|
118
|
+
});
|
|
119
|
+
expect(replies[0]).toBe("禁止与其他用户重名。");
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("落库遇到其他错误时提示修改失败", async () => {
|
|
123
|
+
// 落库异常的 common 域告警是被测行为的预期伴生输出,静默之
|
|
124
|
+
(Logger.levels as Record<string, number>)["common"] = 0;
|
|
125
|
+
const proto = Database.prototype as unknown as Record<
|
|
126
|
+
string,
|
|
127
|
+
(...args: unknown[]) => Promise<unknown>
|
|
128
|
+
>;
|
|
129
|
+
const original = proto["set"];
|
|
130
|
+
proto["set"] = async () => {
|
|
131
|
+
throw new Error("boom");
|
|
132
|
+
};
|
|
133
|
+
try {
|
|
134
|
+
const replies = await client.receive("callme 小强");
|
|
135
|
+
expect(replies[0]).toBe("修改称呼失败。");
|
|
136
|
+
} finally {
|
|
137
|
+
proto["set"] = original!;
|
|
138
|
+
delete (Logger.levels as Record<string, number>)[
|
|
139
|
+
"common"
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2019-present Shigma and Koishijs contributors.
|
|
3
|
+
// Copyright (c) 2026-present Koishi-CE contributors.
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
6
|
* 称呼设置插件(callme)。
|
|
3
7
|
*
|
|
@@ -5,7 +9,12 @@
|
|
|
5
9
|
* 查询或修改当前用户的昵称(写入数据库 user.name)。
|
|
6
10
|
* 其他插件可监听 `common/callme` 事件校验或拒绝昵称修改。
|
|
7
11
|
*/
|
|
8
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
type Context,
|
|
14
|
+
h,
|
|
15
|
+
RuntimeError,
|
|
16
|
+
Schema,
|
|
17
|
+
} from "@koishi-ce/koishi";
|
|
9
18
|
import zhCN from "../locales/zh-CN.yml";
|
|
10
19
|
|
|
11
20
|
// 模块增强:新增 common/callme 事件,监听者返回字符串即可拦截昵称修改。
|
|
@@ -42,7 +51,9 @@ export function apply(ctx: Context) {
|
|
|
42
51
|
if (!user) return;
|
|
43
52
|
if (!name) {
|
|
44
53
|
if (user.name) {
|
|
45
|
-
return session.text(".current", [
|
|
54
|
+
return session.text(".current", [
|
|
55
|
+
session.username,
|
|
56
|
+
]);
|
|
46
57
|
} else {
|
|
47
58
|
return session.text(".unnamed");
|
|
48
59
|
}
|
|
@@ -63,7 +74,11 @@ export function apply(ctx: Context) {
|
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
// 广播 common/callme 事件:任一监听者返回字符串即视为拦截
|
|
66
|
-
const result = ctx.bail(
|
|
77
|
+
const result = ctx.bail(
|
|
78
|
+
"common/callme",
|
|
79
|
+
name,
|
|
80
|
+
session,
|
|
81
|
+
);
|
|
67
82
|
if (result) return result;
|
|
68
83
|
|
|
69
84
|
// 昵称重名(duplicate-entry)给出专门提示,其余异常记日志并告知失败
|