kokkoro-plugin-hitokoto 3.0.3 → 3.0.4

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
@@ -27,20 +27,14 @@ bun add kokkoro-plugin-hitokoto
27
27
 
28
28
  ## 快捷方式
29
29
 
30
- 快捷方式匹配以下正则表达式:
31
-
32
- ```regexp
33
- /^来点(?<types>.+)?骚话$/
34
- ```
35
-
36
- 其中的 `types` 表示「来点」和「骚话」之间可选的类型名称。以下消息都能触发快捷方式:
30
+ 发送「来点骚话」获取随机语句,也可以在「来点」和「骚话」之间加入类型名称:
37
31
 
38
32
  ```text
39
33
  来点骚话
40
34
  来点诗词骚话
41
35
  ```
42
36
 
43
- 要让普通群消息触发快捷方式,需要在对应群聊中开启「获取群内全部消息」权限。未开启时,插件只能处理 @ 机器人的群消息。
37
+ 要让普通群消息触发快捷方式,需要开启「获取群内全部消息」权限。
44
38
 
45
39
  ## API
46
40
 
@@ -54,7 +48,9 @@ const sentence = await fetchSentence('i');
54
48
 
55
49
  `fetchSentence()` 接收一言接口的类型代码或代码数组。`'i'` 表示诗词,`['a', 'b']` 表示动画和漫画。传入空数组时,函数不限制语句类型。
56
50
 
57
- 请求失败时,`fetchSentence()` 会抛出 `Error`。一言错误响应使用上游的 `message`,其他请求错误使用 HTTP 状态码。包同时导出 `Sentence`、`SentenceType` 和 `ErrorResponse` 类型,以及 `isErrorResponse()` 类型守卫。
51
+ 收到非 2xx 响应时,`fetchSentence()` 会抛出 `Error`,优先使用一言错误响应中的 `message`,否则使用 HTTP 状态码。网络请求或成功响应的 JSON 解析失败时,函数直接传播原始错误。
52
+
53
+ 包同时导出 `Sentence`、`SentenceType` 和 `ErrorResponse` 类型,以及 `isErrorResponse()` 类型守卫。
58
54
 
59
55
  ## 环境变量
60
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kokkoro-plugin-hitokoto",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "description": "Hitokoto 一言,随机获取动漫、小说、诗词等类型的语句。",
5
5
  "keywords": [
6
6
  "bot",
package/src/index.ts CHANGED
@@ -1,23 +1,15 @@
1
1
  import { useCommand, useLogger } from '@kokkoro/core';
2
2
 
3
- import { fetchSentence, HITOKOTO_API, resolveTypeCodes } from './service';
3
+ import { fetchSentence, resolveTypeCodes } from './service';
4
4
 
5
5
  const logger = useLogger();
6
6
 
7
7
  export default () => {
8
8
  useCommand('/一言 [types]...', async context => {
9
- const payload = { c: resolveTypeCodes(context.args.types) };
10
-
11
- logger.debug('发送 Hitokoto 请求', {
12
- method: 'GET',
13
- url: HITOKOTO_API,
14
- payload,
15
- });
16
-
17
- const sentence = await fetchSentence(payload.c);
9
+ const types = resolveTypeCodes(context.args.types);
10
+ const sentence = await fetchSentence(types, logger);
18
11
  const { from, hitokoto, id, type } = sentence;
19
12
 
20
- logger.debug('收到 Hitokoto 响应', sentence);
21
13
  logger.info('已获取一言', { id, type });
22
14
 
23
15
  return `『${hitokoto}』——「${from}」`;
package/src/service.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { type Logger } from '@kokkoro/core';
2
+
1
3
  /** 一言 v1 语句接口的请求地址。 */
2
4
  export const HITOKOTO_API = 'https://v1.hitokoto.cn';
3
5
 
@@ -151,6 +153,7 @@ export function isErrorResponse(value: unknown): value is ErrorResponse {
151
153
  * 显式传入空数组时,不会读取环境变量,也不会发送 `c` 查询参数。
152
154
  *
153
155
  * @param types - 单个句子类型代码或句子类型代码数组。
156
+ * @param logger - 在 debug 日志中记录实际请求参数和解析后的接口响应。
154
157
  * @returns 一个 Promise,成功时返回完整的 {@link Sentence}。
155
158
  * @throws 收到非 2xx 响应时抛出 `Error`。如果响应体符合 {@link ErrorResponse},错误信息使用其 `message`,
156
159
  * 否则错误信息包含 HTTP 状态码。
@@ -165,18 +168,27 @@ export function isErrorResponse(value: unknown): value is ErrorResponse {
165
168
  *
166
169
  * @see {@link https://developer.hitokoto.cn/sentence/ | 一言语句接口}
167
170
  */
168
- export async function fetchSentence(types?: SentenceType | SentenceType[]): Promise<Sentence> {
171
+ export async function fetchSentence(types?: SentenceType | SentenceType[], logger?: Logger): Promise<Sentence> {
172
+ const payload = { c: resolveTypes(types) };
169
173
  const url = new URL(HITOKOTO_API);
170
174
 
171
- for (const type of resolveTypes(types)) {
175
+ for (const type of payload.c) {
172
176
  url.searchParams.append('c', type);
173
177
  }
178
+ logger?.debug('发送 Hitokoto 请求', {
179
+ method: 'GET',
180
+ url: HITOKOTO_API,
181
+ payload,
182
+ });
183
+
174
184
  const response = await fetch(url);
185
+ const body = response.ok ? await response.json() : await response.json().catch(() => null);
186
+
187
+ logger?.debug('收到 Hitokoto 响应', body);
175
188
 
176
189
  if (response.ok) {
177
- return <Sentence>await response.json();
190
+ return <Sentence>body;
178
191
  }
179
- const body = await response.json().catch(() => null);
180
192
 
181
193
  if (isErrorResponse(body)) {
182
194
  throw new Error(body.message);