kokkoro-plugin-animetrace 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.
package/README.md CHANGED
@@ -8,13 +8,13 @@
8
8
  bun add kokkoro-plugin-animetrace
9
9
  ```
10
10
 
11
- 发送「/搜角色」时附带图片,插件会识别消息中的第一张图片,并通过 QQ Markdown 展示结果。发送带图的「搜角色」也可以触发识别。
11
+ 发送「/搜角色」指令时附带图片,或引用包含图片的消息回复该指令。插件识别首张图片中的角色,并通过 QQ Markdown 返回结果。「搜角色」与「/搜角色」的用法相同。
12
12
 
13
13
  完整使用说明见 [AnimeTrace 角色识别](https://kokkoro.js.org/plugin/animetrace)。
14
14
 
15
15
  ## 环境变量
16
16
 
17
- 在项目根目录的 `.env` 中设置每个人物展示的候选角色数量上限:
17
+ 在项目根目录的 `.env` 中配置每个人物最多显示的候选角色数量:
18
18
 
19
19
  ```ini
20
20
  ANIMETRACE_LIMIT=3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kokkoro-plugin-animetrace",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "AnimeTrace 角色识别,查找图片中的动漫、游戏角色及所属作品。",
5
5
  "keywords": [
6
6
  "animetrace",
package/src/index.ts CHANGED
@@ -7,19 +7,23 @@ const logger = useLogger();
7
7
 
8
8
  export default () => {
9
9
  useCommand('/搜角色', async context => {
10
- const image = context.attachments?.find(attachment => attachment.content_type?.startsWith('image/'));
10
+ const [reference] = context.msg_elements ?? [];
11
+ const attachments = context.message_type === 103 ? reference?.attachments : context.attachments;
12
+ const images = attachments?.filter(attachment => attachment.content_type?.startsWith('image/')) ?? [];
13
+ const [image] = images;
11
14
 
12
15
  if (!image?.url) {
13
- throw new Error('请在指令中附带需要识别的图片');
16
+ throw new Error('未检测到图片,请在指令消息中附带图片,或引用包含图片的消息后重试。');
14
17
  }
15
18
  const result = await fetchCharacters(image.url, logger);
16
19
  const { data, trace_id } = result;
20
+ const notice = images.length > 1 ? '检测到消息中包含多张图片,已选取首张图片进行识别。' : undefined;
17
21
 
18
22
  logger.info('已识别图片中的角色', { count: data.length, trace_id });
19
23
 
20
24
  await context.reply({
21
25
  msg_type: 2,
22
- markdown: { content: createMarkdown(data) },
26
+ markdown: { content: createMarkdown(data, notice) },
23
27
  });
24
28
  }).shortcut('搜角色');
25
29
  };
package/src/service.ts CHANGED
@@ -53,7 +53,7 @@ export async function fetchCharacters(url: string, logger?: Logger): Promise<Ani
53
53
  const response = await fetch(ANIMETRACE_API, { method: 'POST', body: form });
54
54
 
55
55
  if (!response.ok) {
56
- throw new Error(`接口请求失败,状态码 ${response.status}`);
56
+ throw new Error(`AnimeTrace 请求失败,HTTP 状态码 ${response.status}`);
57
57
  }
58
58
  const result = <AnimeTrace>await response.json();
59
59
 
@@ -64,7 +64,7 @@ export async function fetchCharacters(url: string, logger?: Logger): Promise<Ani
64
64
  }
65
65
 
66
66
  if (result.data.length === 0) {
67
- throw new Error('没有识别到角色');
67
+ throw new Error('未识别到角色');
68
68
  }
69
69
  return result;
70
70
  }
package/src/util.ts CHANGED
@@ -1,18 +1,22 @@
1
1
  import { type CharacterResult } from './service';
2
2
 
3
- const { ANIMETRACE_LIMIT = 3 } = import.meta.env;
3
+ const { ANIMETRACE_LIMIT = '3' } = import.meta.env;
4
4
  const limit = Number(ANIMETRACE_LIMIT);
5
5
 
6
6
  if (!Number.isInteger(limit) || limit <= 0) {
7
7
  throw new Error('ANIMETRACE_LIMIT 必须为正整数');
8
8
  }
9
9
 
10
- /** 将 AnimeTrace 识别结果转换为 QQ Markdown。 */
11
- export function createMarkdown(results: readonly CharacterResult[]): string {
12
- const lines = ['## AnimeTrace 搜索结果'];
10
+ /** 将 AnimeTrace 识别结果转换为 QQ Markdown,可在标题下方展示提示。 */
11
+ export function createMarkdown(results: readonly CharacterResult[], notice?: string): string {
12
+ const lines = ['## AnimeTrace 识别结果'];
13
+
14
+ if (notice) {
15
+ lines.push('', `> ${notice}`);
16
+ }
13
17
 
14
18
  if (results.some(({ not_confident: isNotConfident }) => isNotConfident)) {
15
- lines.push('', '> 带 * 的人物可能识别不准确。');
19
+ lines.push('', '> 标有 * 的识别结果可能不准确,请注意甄别。');
16
20
  }
17
21
 
18
22
  for (const [index, { character: candidates, not_confident: isNotConfident }] of results.entries()) {