@koishi-ce/plugin-echo 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 +81 -0
- package/lib/assets/{zh-CN-CrW2M7HM.yml → zh-CN-CKCgP5gq.yml} +3 -0
- package/lib/index.d.ts +6 -7
- package/lib/index.mjs +1 -1
- package/locales/de-DE.yml +11 -8
- package/locales/en-US.yml +3 -0
- package/locales/fr-FR.yml +11 -8
- package/locales/ja-JP.yml +11 -8
- package/locales/ru-RU.yml +11 -8
- package/locales/zh-CN.yml +3 -0
- package/locales/zh-TW.yml +3 -0
- package/package.json +3 -3
- package/src/index.test.ts +46 -10
- package/src/index.ts +21 -5
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# @koishi-ce/plugin-echo
|
|
2
|
+
|
|
3
|
+
**简体中文** | [English](#english)
|
|
4
|
+
|
|
5
|
+
消息复述插件,移植自上游 [koishijs/koishi](https://github.com/koishijs/koishi) 的 `plugins/common/echo`。原样返回输入的文本,常用于测试机器人的消息收发链路。
|
|
6
|
+
|
|
7
|
+
## 指令
|
|
8
|
+
|
|
9
|
+
| 指令 | 权限 | 说明 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `echo <message:text>` | 1 | 原样复述输入的文本 |
|
|
12
|
+
|
|
13
|
+
- 以下选项均要求权限 3:`-e, --escape` 发送转义消息、`-E, --unescape` 发送反转义消息、`-u, --user [user:user]` 发送到用户、`-c, --channel [channel:channel]` 发送到频道、`-g, --guild [guild:string]` 指定群组编号。
|
|
14
|
+
- `-u` / `-c` 的目标按 `platform:id` 形式解析,并改由目标平台的 bot 发送;找不到对应平台时提示「找不到指定的平台。」。
|
|
15
|
+
|
|
16
|
+
## 配置项
|
|
17
|
+
|
|
18
|
+
本插件无需配置。
|
|
19
|
+
|
|
20
|
+
## 用法
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun add @koishi-ce/plugin-echo
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
也可以在控制台的插件市场中直接安装。随后在配置文件中启用:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
plugins:
|
|
30
|
+
echo: {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 备注
|
|
34
|
+
|
|
35
|
+
- 无配置、无服务依赖,开箱即用。
|
|
36
|
+
- 导出工具函数 `parsePlatform`,用于解析 `platform:id` 形式的目标标识。
|
|
37
|
+
|
|
38
|
+
## 许可证
|
|
39
|
+
|
|
40
|
+
[MIT](https://github.com/Koishi-CE/koishi/blob/main/LICENSE)。本包是上游 [koishijs/koishi](https://github.com/koishijs/koishi) 的社区再分发,版权归属见 [NOTICE](https://github.com/Koishi-CE/koishi/blob/main/NOTICE)。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## English
|
|
45
|
+
|
|
46
|
+
A message echo plugin, ported from `plugins/common/echo` of the upstream [koishijs/koishi](https://github.com/koishijs/koishi) repository. It repeats the input text verbatim, which is handy for testing the bot's message pipeline.
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
| Command | Authority | Description |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| `echo <message:text>` | 1 | Repeat the input text verbatim |
|
|
53
|
+
|
|
54
|
+
- The following options all require authority 3: `-e, --escape` send the message escaped, `-E, --unescape` send the message unescaped, `-u, --user [user:user]` send to a user, `-c, --channel [channel:channel]` send to a channel, `-g, --guild [guild:string]` specify the guild ID.
|
|
55
|
+
- Targets of `-u` / `-c` are resolved as `platform:id` and the message is sent by the bot of that platform; a missing platform reports an error.
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
None.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun add @koishi-ce/plugin-echo
|
|
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
|
+
echo: {}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
|
|
76
|
+
- No configuration and no service dependencies.
|
|
77
|
+
- Exports the utility function `parsePlatform` for parsing `platform:id` targets.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
[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
|
@@ -5,11 +5,10 @@ import { Context, Schema } from "@koishi-ce/koishi";
|
|
|
5
5
|
* @param target 形如 `platform:id` 的字符串
|
|
6
6
|
* @returns [平台名, 目标 ID] 二元组
|
|
7
7
|
*/
|
|
8
|
-
declare function parsePlatform(target: string): [platform: string, id: string];
|
|
8
|
+
export declare function parsePlatform(target: string): [platform: string, id: string];
|
|
9
9
|
/** 配置项(当前无可用配置) */
|
|
10
|
-
type Config = Record<never, never>;
|
|
11
|
-
declare const name = "echo";
|
|
12
|
-
declare const Config: Schema<Config>;
|
|
13
|
-
declare function apply(ctx: Context, _config: Config): void;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { Config, apply, name, parsePlatform };
|
|
10
|
+
export type Config = Record<never, never>;
|
|
11
|
+
export declare const name = "echo";
|
|
12
|
+
export declare const Config: Schema<Config>;
|
|
13
|
+
export declare function apply(ctx: Context, _config: Config): 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
|
echo:
|
|
3
|
-
description:
|
|
6
|
+
description: Nachrichten senden
|
|
4
7
|
options:
|
|
5
|
-
escape:
|
|
6
|
-
unescape:
|
|
7
|
-
user:
|
|
8
|
-
channel:
|
|
9
|
-
guild:
|
|
8
|
+
escape: Escapte Nachricht senden
|
|
9
|
+
unescape: Unescapte Nachricht senden
|
|
10
|
+
user: An Benutzer senden
|
|
11
|
+
channel: An Kanal senden
|
|
12
|
+
guild: Gruppen-ID angeben
|
|
10
13
|
messages:
|
|
11
|
-
expect-text:
|
|
12
|
-
platform-not-found:
|
|
14
|
+
expect-text: Bitte geben Sie den zu sendenden Text ein.
|
|
15
|
+
platform-not-found: Die angegebene Plattform wurde nicht gefunden.
|
package/locales/en-US.yml
CHANGED
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
|
echo:
|
|
3
|
-
description:
|
|
6
|
+
description: Envoyer des messages
|
|
4
7
|
options:
|
|
5
|
-
escape:
|
|
6
|
-
unescape:
|
|
7
|
-
user:
|
|
8
|
-
channel:
|
|
9
|
-
guild:
|
|
8
|
+
escape: Envoyer un message échappé
|
|
9
|
+
unescape: Envoyer un message déséchappé
|
|
10
|
+
user: Envoyer à l'utilisateur
|
|
11
|
+
channel: Envoyer au canal
|
|
12
|
+
guild: Indiquer l'identifiant du groupe
|
|
10
13
|
messages:
|
|
11
|
-
expect-text:
|
|
12
|
-
platform-not-found:
|
|
14
|
+
expect-text: Veuillez saisir le texte à envoyer.
|
|
15
|
+
platform-not-found: La plateforme spécifiée est introuvable.
|
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
|
echo:
|
|
3
|
-
description:
|
|
6
|
+
description: メッセージを送信する
|
|
4
7
|
options:
|
|
5
|
-
escape:
|
|
6
|
-
unescape:
|
|
7
|
-
user:
|
|
8
|
-
channel:
|
|
9
|
-
guild:
|
|
8
|
+
escape: エスケープされたメッセージを送信する
|
|
9
|
+
unescape: アンエスケープされたメッセージを送信する
|
|
10
|
+
user: ユーザーに送信する
|
|
11
|
+
channel: チャンネルに送信する
|
|
12
|
+
guild: グループ番号を指定する
|
|
10
13
|
messages:
|
|
11
|
-
expect-text:
|
|
12
|
-
platform-not-found:
|
|
14
|
+
expect-text: 送信するテキストを入力してください。
|
|
15
|
+
platform-not-found: 指定されたプラットフォームが見つかりません。
|
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
|
echo:
|
|
3
|
-
description:
|
|
6
|
+
description: Отправить сообщения
|
|
4
7
|
options:
|
|
5
|
-
escape:
|
|
6
|
-
unescape:
|
|
7
|
-
user:
|
|
8
|
-
channel:
|
|
9
|
-
guild:
|
|
8
|
+
escape: Отправить экранированное сообщение
|
|
9
|
+
unescape: Отправить разэкранированное сообщение
|
|
10
|
+
user: Отправить пользователю
|
|
11
|
+
channel: Отправить в канал
|
|
12
|
+
guild: Указать идентификатор группы
|
|
10
13
|
messages:
|
|
11
|
-
expect-text:
|
|
12
|
-
platform-not-found:
|
|
14
|
+
expect-text: Пожалуйста, введите текст для отправки.
|
|
15
|
+
platform-not-found: Указанная платформа не найдена.
|
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-echo",
|
|
3
3
|
"description": "Echo plugin for 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",
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"koishi": "^
|
|
46
|
+
"@koishi-ce/koishi": "^1.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@koishi-ce/plugin-mock": "^1.0.0",
|
|
50
|
-
"@koishi-ce/koishi": "^1.0.
|
|
50
|
+
"@koishi-ce/koishi": "^1.0.8"
|
|
51
51
|
},
|
|
52
52
|
"exports": {
|
|
53
53
|
".": {
|
package/src/index.test.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2026-present Koishi-CE contributors.
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* echo 插件测试:验证基础复述、CQ 码转义 / 反转义
|
|
3
6
|
* 与定向发送(-u 用户私聊 / -c 频道)的参数形状。
|
|
4
7
|
*/
|
|
5
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
beforeAll,
|
|
10
|
+
describe,
|
|
11
|
+
expect,
|
|
12
|
+
it,
|
|
13
|
+
jest,
|
|
14
|
+
} from "bun:test";
|
|
6
15
|
import { App, type Bot, h } from "@koishi-ce/koishi";
|
|
7
16
|
import * as echo from "@koishi-ce/plugin-echo";
|
|
8
17
|
import mock from "@koishi-ce/plugin-mock";
|
|
@@ -19,19 +28,27 @@ beforeAll(() => app.start());
|
|
|
19
28
|
describe("@koishi-ce/plugin-echo", () => {
|
|
20
29
|
// 覆盖纯文本、转义输入、-E 反转义(拆分为多条消息),以及向用户 / 频道定向发送时的调用参数
|
|
21
30
|
it("basic support", async () => {
|
|
22
|
-
await client.shouldReply(
|
|
31
|
+
await client.shouldReply(
|
|
32
|
+
"echo",
|
|
33
|
+
"请输入要发送的文本。",
|
|
34
|
+
);
|
|
23
35
|
await client.shouldReply("echo foo", "foo");
|
|
24
|
-
await client.shouldReply(
|
|
36
|
+
await client.shouldReply(
|
|
37
|
+
h.escape("echo <>"),
|
|
38
|
+
"<>",
|
|
39
|
+
);
|
|
25
40
|
await client.shouldReply(
|
|
26
41
|
h.escape("echo 1<message>2</message>3"),
|
|
27
42
|
"1<message>2</message>3",
|
|
28
43
|
);
|
|
29
|
-
await client.shouldReply(
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
await client.shouldReply(
|
|
45
|
+
h.escape("echo -E <>"),
|
|
46
|
+
"<>",
|
|
47
|
+
);
|
|
48
|
+
await client.shouldReply(
|
|
49
|
+
h.escape("echo -E 1<message>2</message>3"),
|
|
50
|
+
["1", "2", "3"],
|
|
51
|
+
);
|
|
35
52
|
|
|
36
53
|
const send1 = (app.bots[0]!.sendPrivateMessage =
|
|
37
54
|
jest.fn<Bot["sendPrivateMessage"]>());
|
|
@@ -41,10 +58,29 @@ describe("@koishi-ce/plugin-echo", () => {
|
|
|
41
58
|
expect(send1.mock.calls[0]?.[0]).toBe("100");
|
|
42
59
|
expect(send1.mock.calls[0]?.[1]).toStrictEqual(["foo"]);
|
|
43
60
|
|
|
44
|
-
const send2 = (app.bots[0]!.sendMessage =
|
|
61
|
+
const send2 = (app.bots[0]!.sendMessage =
|
|
62
|
+
jest.fn<Bot["sendMessage"]>());
|
|
45
63
|
await client.shouldNotReply("echo -c #200 foo");
|
|
46
64
|
expect(send1.mock.calls).toHaveLength(1);
|
|
47
65
|
expect(send2.mock.calls[0]?.[0]).toBe("200");
|
|
48
66
|
expect(send2.mock.calls[0]?.[1]).toStrictEqual(["foo"]);
|
|
49
67
|
});
|
|
68
|
+
|
|
69
|
+
// -e 转义:消息中的标签原样输出为转义文本
|
|
70
|
+
it("escape option", async () => {
|
|
71
|
+
// 存量用例曾以 jest.fn 覆盖实例属性,删除后回落到原型上的真实实现
|
|
72
|
+
delete (app.bots[0] as Partial<Bot>).sendMessage;
|
|
73
|
+
await client.shouldReply(
|
|
74
|
+
"echo -e <foo>",
|
|
75
|
+
"<foo/>",
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// -u 指向不存在的平台时提示找不到平台
|
|
80
|
+
it("platform not found", async () => {
|
|
81
|
+
await client.shouldReply(
|
|
82
|
+
"echo -u @nosuch:100 foo",
|
|
83
|
+
"找不到指定的平台。",
|
|
84
|
+
);
|
|
85
|
+
});
|
|
50
86
|
});
|
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
|
* 消息复述插件(echo)。
|
|
3
7
|
*
|
|
@@ -13,7 +17,9 @@ import zhCN from "../locales/zh-CN.yml";
|
|
|
13
17
|
* @param target 形如 `platform:id` 的字符串
|
|
14
18
|
* @returns [平台名, 目标 ID] 二元组
|
|
15
19
|
*/
|
|
16
|
-
export function parsePlatform(
|
|
20
|
+
export function parsePlatform(
|
|
21
|
+
target: string,
|
|
22
|
+
): [platform: string, id: string] {
|
|
17
23
|
const index = target.indexOf(":");
|
|
18
24
|
const platform = target.slice(0, index);
|
|
19
25
|
const id = target.slice(index + 1);
|
|
@@ -34,7 +40,9 @@ export function apply(ctx: Context, _config: Config) {
|
|
|
34
40
|
.option("escape", "-e", { authority: 3 })
|
|
35
41
|
.option("unescape", "-E", { authority: 3 })
|
|
36
42
|
.option("user", "-u [user:user]", { authority: 3 })
|
|
37
|
-
.option("channel", "-c [channel:channel]", {
|
|
43
|
+
.option("channel", "-c [channel:channel]", {
|
|
44
|
+
authority: 3,
|
|
45
|
+
})
|
|
38
46
|
.option("guild", "-g [guild:string]", { authority: 3 })
|
|
39
47
|
.action(async ({ options, session }, message) => {
|
|
40
48
|
if (!session || !options) return;
|
|
@@ -51,12 +59,20 @@ export function apply(ctx: Context, _config: Config) {
|
|
|
51
59
|
// 指定了 -u / -c 时改为向目标发送,而不是回复当前会话
|
|
52
60
|
const target = options.user || options.channel;
|
|
53
61
|
if (target) {
|
|
54
|
-
const [platform, id] = parsePlatform(
|
|
55
|
-
|
|
62
|
+
const [platform, id] = parsePlatform(
|
|
63
|
+
target as string,
|
|
64
|
+
);
|
|
65
|
+
const bot = ctx.bots.find(
|
|
66
|
+
(bot) => bot.platform === platform,
|
|
67
|
+
);
|
|
56
68
|
if (!bot) {
|
|
57
69
|
return session.text(".platform-not-found");
|
|
58
70
|
} else if (options.user) {
|
|
59
|
-
await bot.sendPrivateMessage(
|
|
71
|
+
await bot.sendPrivateMessage(
|
|
72
|
+
id,
|
|
73
|
+
content,
|
|
74
|
+
session.guildId,
|
|
75
|
+
);
|
|
60
76
|
} else {
|
|
61
77
|
await bot.sendMessage(id, content, options.guild);
|
|
62
78
|
}
|