@zhin.js/plugin-60s 3.0.0 → 3.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/agent/tools/60s_news.ts +13 -0
- package/agent/tools/bing_image.ts +13 -0
- package/agent/tools/douyin_hot.ts +13 -0
- package/agent/tools/duanzi.ts +13 -0
- package/agent/tools/exchange_rate.ts +13 -0
- package/agent/tools/fuel_price.ts +13 -0
- package/agent/tools/gold_price.ts +13 -0
- package/agent/tools/history_today.ts +13 -0
- package/agent/tools/hitokoto.ts +13 -0
- package/agent/tools/ip_query.ts +13 -0
- package/agent/tools/kfc.ts +13 -0
- package/agent/tools/moyu.ts +13 -0
- package/agent/tools/toutiao_hot.ts +13 -0
- package/agent/tools/translate_60s.ts +13 -0
- package/agent/tools/weather.ts +13 -0
- package/agent/tools/weibo_hot.ts +13 -0
- package/agent/tools/zhihu_hot.ts +13 -0
- package/lib/agent/tools/60s_news.js +13 -0
- package/lib/agent/tools/60s_news.js.map +1 -0
- package/lib/agent/tools/bing_image.js +13 -0
- package/lib/agent/tools/bing_image.js.map +1 -0
- package/lib/agent/tools/douyin_hot.js +13 -0
- package/lib/agent/tools/douyin_hot.js.map +1 -0
- package/lib/agent/tools/duanzi.js +13 -0
- package/lib/agent/tools/duanzi.js.map +1 -0
- package/lib/agent/tools/exchange_rate.js +13 -0
- package/lib/agent/tools/exchange_rate.js.map +1 -0
- package/lib/agent/tools/fuel_price.js +13 -0
- package/lib/agent/tools/fuel_price.js.map +1 -0
- package/lib/agent/tools/gold_price.js +13 -0
- package/lib/agent/tools/gold_price.js.map +1 -0
- package/lib/agent/tools/history_today.js +13 -0
- package/lib/agent/tools/history_today.js.map +1 -0
- package/lib/agent/tools/hitokoto.js +13 -0
- package/lib/agent/tools/hitokoto.js.map +1 -0
- package/lib/agent/tools/ip_query.js +13 -0
- package/lib/agent/tools/ip_query.js.map +1 -0
- package/lib/agent/tools/kfc.js +13 -0
- package/lib/agent/tools/kfc.js.map +1 -0
- package/lib/agent/tools/moyu.js +13 -0
- package/lib/agent/tools/moyu.js.map +1 -0
- package/lib/agent/tools/toutiao_hot.js +13 -0
- package/lib/agent/tools/toutiao_hot.js.map +1 -0
- package/lib/agent/tools/translate_60s.js +13 -0
- package/lib/agent/tools/translate_60s.js.map +1 -0
- package/lib/agent/tools/weather.js +13 -0
- package/lib/agent/tools/weather.js.map +1 -0
- package/lib/agent/tools/weibo_hot.js +13 -0
- package/lib/agent/tools/weibo_hot.js.map +1 -0
- package/lib/agent/tools/zhihu_hot.js +13 -0
- package/lib/agent/tools/zhihu_hot.js.map +1 -0
- package/lib/{index.js → src/index.js} +1 -1
- package/lib/src/index.js.map +1 -0
- package/lib/tools/60s-news/handler.js +12 -0
- package/lib/tools/60s-news/handler.js.map +1 -0
- package/lib/tools/api.js +45 -0
- package/lib/tools/api.js.map +1 -0
- package/lib/tools/bing-image/handler.js +18 -0
- package/lib/tools/bing-image/handler.js.map +1 -0
- package/lib/tools/douyin-hot/handler.js +6 -0
- package/lib/tools/douyin-hot/handler.js.map +1 -0
- package/lib/tools/duanzi/handler.js +6 -0
- package/lib/tools/duanzi/handler.js.map +1 -0
- package/lib/tools/exchange-rate/handler.js +28 -0
- package/lib/tools/exchange-rate/handler.js.map +1 -0
- package/lib/tools/fuel-price/handler.js +21 -0
- package/lib/tools/fuel-price/handler.js.map +1 -0
- package/lib/tools/gold-price/handler.js +24 -0
- package/lib/tools/gold-price/handler.js.map +1 -0
- package/lib/tools/history-today/handler.js +16 -0
- package/lib/tools/history-today/handler.js.map +1 -0
- package/lib/tools/hitokoto/handler.js +16 -0
- package/lib/tools/hitokoto/handler.js.map +1 -0
- package/lib/tools/ip-query/handler.js +17 -0
- package/lib/tools/ip-query/handler.js.map +1 -0
- package/lib/tools/kfc/handler.js +6 -0
- package/lib/tools/kfc/handler.js.map +1 -0
- package/lib/tools/moyu/handler.js +39 -0
- package/lib/tools/moyu/handler.js.map +1 -0
- package/lib/tools/toutiao-hot/handler.js +6 -0
- package/lib/tools/toutiao-hot/handler.js.map +1 -0
- package/lib/tools/translate/handler.js +26 -0
- package/lib/tools/translate/handler.js.map +1 -0
- package/lib/tools/weather/handler.js +22 -0
- package/lib/tools/weather/handler.js.map +1 -0
- package/lib/tools/weibo-hot/handler.js +6 -0
- package/lib/tools/weibo-hot/handler.js.map +1 -0
- package/lib/tools/zhihu-hot/handler.js +6 -0
- package/lib/tools/zhihu-hot/handler.js.map +1 -0
- package/package.json +19 -9
- package/src/index.ts +1 -1
- package/tools/60s-news/handler.ts +1 -1
- package/tools/api.ts +35 -6
- package/tools/bing-image/handler.ts +4 -4
- package/tools/douyin-hot/handler.ts +2 -2
- package/tools/duanzi/handler.ts +1 -1
- package/tools/exchange-rate/handler.ts +8 -6
- package/tools/fuel-price/handler.ts +5 -4
- package/tools/gold-price/handler.ts +8 -7
- package/tools/history-today/handler.ts +8 -7
- package/tools/hitokoto/handler.ts +1 -1
- package/tools/ip-query/handler.ts +1 -1
- package/tools/kfc/handler.ts +1 -1
- package/tools/moyu/handler.ts +23 -16
- package/tools/toutiao-hot/handler.ts +2 -2
- package/tools/translate/handler.ts +13 -7
- package/tools/weather/handler.ts +13 -13
- package/tools/weibo-hot/handler.ts +2 -2
- package/tools/zhihu-hot/handler.ts +2 -2
- package/lib/index.d.ts +0 -2
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/tools/60s-news/60s-news.tool.md +0 -8
- package/tools/bing-image/bing-image.tool.md +0 -8
- package/tools/douyin-hot/douyin-hot.tool.md +0 -12
- package/tools/duanzi/duanzi.tool.md +0 -8
- package/tools/exchange-rate/exchange-rate.tool.md +0 -14
- package/tools/fuel-price/fuel-price.tool.md +0 -11
- package/tools/gold-price/gold-price.tool.md +0 -8
- package/tools/history-today/history-today.tool.md +0 -8
- package/tools/hitokoto/hitokoto.tool.md +0 -12
- package/tools/ip-query/ip-query.tool.md +0 -12
- package/tools/kfc/kfc.tool.md +0 -8
- package/tools/moyu/moyu.tool.md +0 -8
- package/tools/toutiao-hot/toutiao-hot.tool.md +0 -12
- package/tools/translate/translate.tool.md +0 -15
- package/tools/weather/weather.tool.md +0 -12
- package/tools/weibo-hot/weibo-hot.tool.md +0 -12
- package/tools/zhihu-hot/zhihu-hot.tool.md +0 -12
- /package/{skills/60s/SKILL.md → agent/skills/60s.md} +0 -0
package/lib/tools/api.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 60s API 共享模块 — 供 *.tool.md handler 使用
|
|
3
|
+
*/
|
|
4
|
+
const API_BASE = process.env.ZHIN_60S_API || 'https://60s.viki.moe';
|
|
5
|
+
export async function fetchApi(endpoint, params) {
|
|
6
|
+
const url = new URL(`${API_BASE}/v2${endpoint}`);
|
|
7
|
+
if (params) {
|
|
8
|
+
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
|
|
9
|
+
}
|
|
10
|
+
const res = await fetch(url.toString());
|
|
11
|
+
const data = (await res.json());
|
|
12
|
+
if (data.error)
|
|
13
|
+
throw new Error(data.error);
|
|
14
|
+
if (data.code !== undefined && data.code !== 200 && data.code !== 0) {
|
|
15
|
+
throw new Error(data.message || data.msg || `API 错误: ${data.code}`);
|
|
16
|
+
}
|
|
17
|
+
return (data.data ?? data);
|
|
18
|
+
}
|
|
19
|
+
/** Coerce nested API JSON objects for property access in handlers. */
|
|
20
|
+
export function asRecord(value) {
|
|
21
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
22
|
+
? value
|
|
23
|
+
: {};
|
|
24
|
+
}
|
|
25
|
+
export function asString(value) {
|
|
26
|
+
return value == null ? '' : String(value);
|
|
27
|
+
}
|
|
28
|
+
export function asArray(value) {
|
|
29
|
+
return Array.isArray(value) ? value : [];
|
|
30
|
+
}
|
|
31
|
+
export function formatList(items, limit = 10) {
|
|
32
|
+
return items
|
|
33
|
+
.slice(0, limit)
|
|
34
|
+
.map((item, i) => {
|
|
35
|
+
const obj = typeof item === 'string' ? null : item;
|
|
36
|
+
const title = obj
|
|
37
|
+
? String(obj.title ?? obj.name ?? obj.word ?? item)
|
|
38
|
+
: item;
|
|
39
|
+
const hot = obj ? obj.hot_value ?? obj.hot : undefined;
|
|
40
|
+
const hotStr = hot ? ` 🔥${hot}` : '';
|
|
41
|
+
return `${i + 1}. ${title}${hotStr}`;
|
|
42
|
+
})
|
|
43
|
+
.join('\n');
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../tools/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,sBAAsB,CAAC;AAOpE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,QAAgB,EAChB,MAA+B;IAE/B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,QAAQ,MAAM,QAAQ,EAAE,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAM7B,CAAC;IACF,IAAI,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAM,CAAC;AAClC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAoB;QACvB,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,KAAK,GAAG,EAAE;IACtD,OAAO,KAAK;SACT,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,MAAM,KAAK,GAAG,GAAG;YACf,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;YACnD,CAAC,CAAC,IAAI,CAAC;QACT,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QACvD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,GAAG,MAAM,EAAE,CAAC;IACvC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function () {
|
|
3
|
+
const data = await fetchApi('/bing');
|
|
4
|
+
const lines = ['🖼️ Bing 每日壁纸', ''];
|
|
5
|
+
if (data.title)
|
|
6
|
+
lines.push(`📌 ${data.title}`);
|
|
7
|
+
if (data.headline)
|
|
8
|
+
lines.push(`💡 ${data.headline}`);
|
|
9
|
+
if (data.copyright)
|
|
10
|
+
lines.push(`📝 ${data.copyright}`);
|
|
11
|
+
if (data.description)
|
|
12
|
+
lines.push('', asString(data.description));
|
|
13
|
+
const imgUrl = data.cover || data.cover_4k || data.url || data.image;
|
|
14
|
+
if (imgUrl)
|
|
15
|
+
lines.push('', asString(imgUrl));
|
|
16
|
+
return lines.join('\n');
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/bing-image/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrD,IAAI,IAAI,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACvD,IAAI,IAAI,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;IACrE,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/douyin-hot/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAEhE,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAa,SAAS,CAAC,CAAC;IACnD,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/duanzi/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvC,OAAO,YAAY,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1G,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { asArray, asRecord, asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const params = {};
|
|
4
|
+
if (args.from)
|
|
5
|
+
params.from = args.from.toUpperCase();
|
|
6
|
+
if (args.to)
|
|
7
|
+
params.to = args.to.toUpperCase();
|
|
8
|
+
const data = await fetchApi('/exchange-rate', Object.keys(params).length ? params : undefined);
|
|
9
|
+
const lines = ['💱 汇率查询', ''];
|
|
10
|
+
const base = data.base_code || args.from || 'CNY';
|
|
11
|
+
lines.push(`基准货币: ${base}`);
|
|
12
|
+
if (data.updated)
|
|
13
|
+
lines.push(`更新时间: ${data.updated}`);
|
|
14
|
+
lines.push('');
|
|
15
|
+
const rates = asArray(data.rates);
|
|
16
|
+
const targetCurrencies = args.to
|
|
17
|
+
? [args.to.toUpperCase()]
|
|
18
|
+
: ['USD', 'EUR', 'JPY', 'GBP', 'HKD', 'KRW', 'AUD', 'CAD', 'SGD', 'CHF'];
|
|
19
|
+
rates.forEach((item) => {
|
|
20
|
+
const row = asRecord(item);
|
|
21
|
+
const currency = asString(row.currency);
|
|
22
|
+
if (targetCurrencies.includes(currency) && currency !== base) {
|
|
23
|
+
lines.push(`${base} → ${currency}: ${row.rate}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return lines.join('\n');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/exchange-rate/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAElE,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAoC;IACjE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,IAAI;QAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACrD,IAAI,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CACzB,gBAAgB,EAChB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAChD,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC5B,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,IAAI,CAAC,EAAE;QAC9B,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3E,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { asRecord, asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const params = args.province
|
|
4
|
+
? { province: args.province }
|
|
5
|
+
: undefined;
|
|
6
|
+
const data = await fetchApi('/fuel-price', params);
|
|
7
|
+
const lines = ['⛽ 今日油价', ''];
|
|
8
|
+
if (data.region)
|
|
9
|
+
lines.push(`📍 ${data.region}`);
|
|
10
|
+
if (data.items && Array.isArray(data.items)) {
|
|
11
|
+
data.items.forEach((item) => {
|
|
12
|
+
lines.push(`${item.name}: ${item.price_desc || `¥${item.price}/升`}`);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (data.trend) {
|
|
16
|
+
const trend = asRecord(data.trend);
|
|
17
|
+
lines.push('', `📊 ${asString(trend.description)}`);
|
|
18
|
+
}
|
|
19
|
+
return lines.join('\n');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/fuel-price/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAA2B;IACxD,MAAM,MAAM,GAAuC,IAAI,CAAC,QAAQ;QAC9D,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;QAC7B,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAA6B,EAAE,EAAE;YACnD,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { asArray, asRecord, fetchApi } from '../api.js';
|
|
2
|
+
export default async function () {
|
|
3
|
+
const data = await fetchApi('/gold-price');
|
|
4
|
+
const lines = ['💰 今日金价', ''];
|
|
5
|
+
if (data.date)
|
|
6
|
+
lines.push(`📅 ${data.date}`);
|
|
7
|
+
const metals = asArray(data.metals);
|
|
8
|
+
if (metals.length > 0) {
|
|
9
|
+
lines.push('');
|
|
10
|
+
metals.forEach((item) => {
|
|
11
|
+
const row = asRecord(item);
|
|
12
|
+
const name = row.name || '黄金';
|
|
13
|
+
const price = row.today_price || row.sell_price || row.price || 'N/A';
|
|
14
|
+
const unit = row.unit || '元/克';
|
|
15
|
+
if (price !== 'N/A')
|
|
16
|
+
lines.push(`${name}: ¥${price} ${unit}`);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
else if (data.price) {
|
|
20
|
+
lines.push(`当前金价: ¥${data.price}/克`);
|
|
21
|
+
}
|
|
22
|
+
return lines.join('\n');
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/gold-price/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC9B,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;YAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC;YACtE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC;YAC/B,IAAI,KAAK,KAAK,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { asArray, asRecord, fetchApi } from '../api.js';
|
|
2
|
+
export default async function () {
|
|
3
|
+
const data = await fetchApi('/today-in-history');
|
|
4
|
+
const dateStr = data.date || `${data.month || ''}月${data.day || ''}日`;
|
|
5
|
+
const lines = [`📅 历史上的今天 (${dateStr})`, ''];
|
|
6
|
+
const items = asArray(data.items);
|
|
7
|
+
items.slice(0, 10).forEach((item, i) => {
|
|
8
|
+
const row = asRecord(item);
|
|
9
|
+
const year = row.year || '';
|
|
10
|
+
const title = row.title || row.event || row.content || item;
|
|
11
|
+
const typeIcon = row.event_type === 'birth' ? '👶' : row.event_type === 'death' ? '🕊️' : '📌';
|
|
12
|
+
lines.push(`${typeIcon} ${i + 1}. ${year ? `[${year}] ` : ''}${title}`);
|
|
13
|
+
});
|
|
14
|
+
return lines.join('\n');
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/history-today/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC;IACtE,MAAM,KAAK,GAAG,CAAC,cAAc,OAAO,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAS,EAAE,EAAE;QAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;QAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/F,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const params = args.type
|
|
4
|
+
? { c: args.type }
|
|
5
|
+
: undefined;
|
|
6
|
+
const data = await fetchApi('/hitokoto', params);
|
|
7
|
+
const text = data.hitokoto || data.content || (typeof data === 'string' ? data : '');
|
|
8
|
+
const lines = ['💬 一言', '', `「${text}」`];
|
|
9
|
+
if (data.from || data.source || data.from_who || data.author) {
|
|
10
|
+
const author = data.from_who || data.author || '';
|
|
11
|
+
const source = data.from || data.source || '';
|
|
12
|
+
lines.push(`——${author}${source ? `《${source}》` : ''}`);
|
|
13
|
+
}
|
|
14
|
+
return lines.join('\n');
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/hitokoto/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAuB;IACpD,MAAM,MAAM,GAAuC,IAAI,CAAC,IAAI;QAC1D,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE;QAClB,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACrF,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const params = args.ip
|
|
4
|
+
? { ip: args.ip }
|
|
5
|
+
: undefined;
|
|
6
|
+
const data = await fetchApi('/ip', params);
|
|
7
|
+
const lines = ['🌐 IP 查询', '', `IP: ${data.ip || args.ip || '当前 IP'}`];
|
|
8
|
+
if (data.country || data.region || data.city) {
|
|
9
|
+
lines.push(`位置: ${[data.country, data.region, data.city].filter(Boolean).join(' ')}`);
|
|
10
|
+
}
|
|
11
|
+
if (data.location)
|
|
12
|
+
lines.push(`位置: ${data.location}`);
|
|
13
|
+
if (data.isp)
|
|
14
|
+
lines.push(`运营商: ${data.isp}`);
|
|
15
|
+
return lines.join('\n');
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/ip-query/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAqB;IAClD,MAAM,MAAM,GAAuC,IAAI,CAAC,EAAE;QACxD,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;IACvE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtD,IAAI,IAAI,CAAC,GAAG;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/kfc/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,eAAe,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1G,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { asArray, asRecord, asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function () {
|
|
3
|
+
const data = await fetchApi('/moyu');
|
|
4
|
+
if (typeof data === 'string')
|
|
5
|
+
return `🐟 摸鱼日历\n\n${data}`;
|
|
6
|
+
const lines = ['🐟 摸鱼日历', ''];
|
|
7
|
+
const date = asRecord(data.date);
|
|
8
|
+
if (date.gregorian)
|
|
9
|
+
lines.push(`📅 ${date.gregorian} ${asString(date.weekday)}`);
|
|
10
|
+
const lunar = asRecord(date.lunar);
|
|
11
|
+
if (lunar.monthCN || lunar.dayCN) {
|
|
12
|
+
lines.push(`🌙 农历${asString(lunar.monthCN)}${asString(lunar.dayCN)} ${asString(lunar.yearGanZhi)}年`);
|
|
13
|
+
}
|
|
14
|
+
const today = asRecord(data.today);
|
|
15
|
+
if (today.holidayName)
|
|
16
|
+
lines.push(`🎉 ${today.holidayName}`);
|
|
17
|
+
if (today.solarTerm)
|
|
18
|
+
lines.push(`🌿 ${today.solarTerm}`);
|
|
19
|
+
if (today.isWorkday !== undefined) {
|
|
20
|
+
lines.push(today.isWorkday ? '💼 今天是工作日' : '🎮 今天不上班');
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(data.festivals)) {
|
|
23
|
+
data.festivals.forEach((f) => {
|
|
24
|
+
lines.push(`🎊 ${typeof f === 'string' ? f : asString(asRecord(f).name ?? f)}`);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const countdown = asArray(data.countdown);
|
|
28
|
+
if (countdown.length > 0) {
|
|
29
|
+
lines.push('');
|
|
30
|
+
countdown.forEach((c) => {
|
|
31
|
+
const row = asRecord(c);
|
|
32
|
+
if (typeof row.name === 'string' && typeof row.days === 'number') {
|
|
33
|
+
lines.push(`⏳ 距 ${row.name} 还有 ${row.days} 天`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return lines.join('\n');
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/moyu/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAmB,MAAM,WAAW,CAAC;AAEnF,MAAM,CAAC,OAAO,CAAC,KAAK;IAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAsB,OAAO,CAAC,CAAC;IAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,cAAc,IAAI,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACvG,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7D,IAAI,KAAK,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAU,EAAE,EAAE;YACpC,KAAK,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,SAAS,CAAC,OAAO,CAAC,CAAC,CAAU,EAAE,EAAE;YAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjE,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/toutiao-hot/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAEhE,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAa,UAAU,CAAC,CAAC;IACpD,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { asRecord, asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const params = { text: args.text };
|
|
4
|
+
if (args.to)
|
|
5
|
+
params.to = args.to;
|
|
6
|
+
const data = await fetchApi('/fanyi', params);
|
|
7
|
+
const source = asRecord(data.source);
|
|
8
|
+
const target = asRecord(data.target);
|
|
9
|
+
const srcText = asString(source.text) || args.text;
|
|
10
|
+
const srcLang = asString(source.type_desc) || asString(source.type);
|
|
11
|
+
const tgtText = asString(target.text) ||
|
|
12
|
+
asString(data.result) ||
|
|
13
|
+
asString(data.translation) ||
|
|
14
|
+
(typeof data === 'string' ? data : '');
|
|
15
|
+
const tgtLang = asString(target.type_desc) || asString(target.type);
|
|
16
|
+
const lines = [
|
|
17
|
+
'🌐 翻译结果',
|
|
18
|
+
'',
|
|
19
|
+
`原文${srcLang ? ` (${srcLang})` : ''}: ${srcText}`,
|
|
20
|
+
`译文${tgtLang ? ` (${tgtLang})` : ''}: ${tgtText}`,
|
|
21
|
+
];
|
|
22
|
+
if (target.pronounce)
|
|
23
|
+
lines.push(`发音: ${asString(target.pronounce)}`);
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/translate/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAmC;IAChE,MAAM,MAAM,GAA2B,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3D,IAAI,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;IACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpE,MAAM,OAAO,GACX,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG;QACZ,SAAS;QACT,EAAE;QACF,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE;QACjD,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE;KAClD,CAAC;IACF,IAAI,MAAM,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACtE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { asRecord, asString, fetchApi } from '../api.js';
|
|
2
|
+
export default async function (args) {
|
|
3
|
+
const data = await fetchApi('/weather', { query: args.city });
|
|
4
|
+
const w = asRecord(data.weather);
|
|
5
|
+
const aq = asRecord(data.air_quality);
|
|
6
|
+
const loc = asRecord(data.location);
|
|
7
|
+
const cityName = asString(loc.city) || asString(loc.name) || args.city;
|
|
8
|
+
const lines = [
|
|
9
|
+
`🌤️ ${cityName} 天气`,
|
|
10
|
+
'',
|
|
11
|
+
`🌡️ 温度: ${asString(w.temperature)}°C`,
|
|
12
|
+
`☁️ 天气: ${asString(w.condition)}`,
|
|
13
|
+
`💧 湿度: ${asString(w.humidity)}%`,
|
|
14
|
+
`💨 风: ${asString(w.wind_direction)} ${asString(w.wind_power)}`,
|
|
15
|
+
];
|
|
16
|
+
if (Object.keys(aq).length > 0) {
|
|
17
|
+
const quality = asString(aq.quality);
|
|
18
|
+
lines.push(`🌬️ 空气: ${quality}${aq.aqi ? ` (AQI ${asString(aq.aqi)})` : ''}`);
|
|
19
|
+
}
|
|
20
|
+
return lines.join('\n');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/weather/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAsB;IACnD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC;IACvE,MAAM,KAAK,GAAG;QACZ,OAAO,QAAQ,KAAK;QACpB,EAAE;QACF,WAAW,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI;QACtC,UAAU,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;QACjC,UAAU,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG;QACjC,SAAS,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;KAChE,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/weibo-hot/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAEhE,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAa,QAAQ,CAAC,CAAC;IAClD,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../tools/zhihu-hot/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAEhE,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAa,QAAQ,CAAC,CAAC;IAClD,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/plugin-60s",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "60s API aggregation plugin for Zhin.js — news, weather, hot searches, utilities and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"src",
|
|
18
18
|
"lib",
|
|
19
|
-
"
|
|
20
|
-
"dist",
|
|
21
|
-
"skills",
|
|
19
|
+
"agent",
|
|
22
20
|
"tools",
|
|
23
21
|
"plugin.yml",
|
|
24
22
|
"README.md"
|
|
@@ -45,13 +43,16 @@
|
|
|
45
43
|
"url": "https://github.com/lc-cn"
|
|
46
44
|
},
|
|
47
45
|
"license": "MIT",
|
|
48
|
-
"dependencies": {},
|
|
49
46
|
"devDependencies": {
|
|
50
47
|
"typescript": "^6.0.3",
|
|
51
|
-
"
|
|
48
|
+
"zod": "^4.4.3",
|
|
49
|
+
"zhin.js": "4.1.2",
|
|
50
|
+
"@zhin.js/agent": "1.0.3"
|
|
52
51
|
},
|
|
53
52
|
"peerDependencies": {
|
|
54
|
-
"
|
|
53
|
+
"zod": "^4.0.0",
|
|
54
|
+
"zhin.js": "4.1.2",
|
|
55
|
+
"@zhin.js/agent": "1.0.3"
|
|
55
56
|
},
|
|
56
57
|
"repository": {
|
|
57
58
|
"type": "git",
|
|
@@ -62,8 +63,17 @@
|
|
|
62
63
|
"access": "public",
|
|
63
64
|
"registry": "https://registry.npmjs.org"
|
|
64
65
|
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"@zhin.js/agent": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"zod": {
|
|
71
|
+
"optional": true
|
|
72
|
+
}
|
|
73
|
+
},
|
|
65
74
|
"scripts": {
|
|
66
|
-
"build": "tsc
|
|
67
|
-
"clean": "rimraf lib"
|
|
75
|
+
"build": "tsc",
|
|
76
|
+
"clean": "rimraf lib",
|
|
77
|
+
"test": "sh -c 'cd ../../.. && vitest run plugins/utils/60s/tests'"
|
|
68
78
|
}
|
|
69
79
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchApi } from '../api.js';
|
|
2
2
|
|
|
3
3
|
export default async function () {
|
|
4
|
-
const data = await fetchApi
|
|
4
|
+
const data = await fetchApi('/60s');
|
|
5
5
|
const lines = [`📰 今日60秒新闻 (${data.date || ''})`, ''];
|
|
6
6
|
if (data.news && Array.isArray(data.news)) {
|
|
7
7
|
lines.push(...data.news.map((n: string, i: number) => `${i + 1}. ${n}`));
|
package/tools/api.ts
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
const API_BASE = process.env.ZHIN_60S_API || 'https://60s.viki.moe';
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export type ListItem = string | Record<string, unknown>;
|
|
8
|
+
|
|
9
|
+
/** Untyped 60s API JSON payload (handlers narrow fields at runtime). */
|
|
10
|
+
export type ApiPayload = Record<string, unknown>;
|
|
11
|
+
|
|
12
|
+
export async function fetchApi<T = ApiPayload>(
|
|
8
13
|
endpoint: string,
|
|
9
14
|
params?: Record<string, string>,
|
|
10
15
|
): Promise<T> {
|
|
@@ -13,20 +18,44 @@ export async function fetchApi<T = any>(
|
|
|
13
18
|
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
|
|
14
19
|
}
|
|
15
20
|
const res = await fetch(url.toString());
|
|
16
|
-
const data = (await res.json()) as
|
|
21
|
+
const data = (await res.json()) as {
|
|
22
|
+
error?: string;
|
|
23
|
+
code?: number;
|
|
24
|
+
message?: string;
|
|
25
|
+
msg?: string;
|
|
26
|
+
data?: T;
|
|
27
|
+
};
|
|
17
28
|
if (data.error) throw new Error(data.error);
|
|
18
29
|
if (data.code !== undefined && data.code !== 200 && data.code !== 0) {
|
|
19
30
|
throw new Error(data.message || data.msg || `API 错误: ${data.code}`);
|
|
20
31
|
}
|
|
21
|
-
return data.data ?? data;
|
|
32
|
+
return (data.data ?? data) as T;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Coerce nested API JSON objects for property access in handlers. */
|
|
36
|
+
export function asRecord(value: unknown): ApiPayload {
|
|
37
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
38
|
+
? (value as ApiPayload)
|
|
39
|
+
: {};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function asString(value: unknown): string {
|
|
43
|
+
return value == null ? '' : String(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function asArray(value: unknown): unknown[] {
|
|
47
|
+
return Array.isArray(value) ? value : [];
|
|
22
48
|
}
|
|
23
49
|
|
|
24
|
-
export function formatList(items:
|
|
50
|
+
export function formatList(items: ListItem[], limit = 10): string {
|
|
25
51
|
return items
|
|
26
52
|
.slice(0, limit)
|
|
27
53
|
.map((item, i) => {
|
|
28
|
-
const
|
|
29
|
-
const
|
|
54
|
+
const obj = typeof item === 'string' ? null : item;
|
|
55
|
+
const title = obj
|
|
56
|
+
? String(obj.title ?? obj.name ?? obj.word ?? item)
|
|
57
|
+
: item;
|
|
58
|
+
const hot = obj ? obj.hot_value ?? obj.hot : undefined;
|
|
30
59
|
const hotStr = hot ? ` 🔥${hot}` : '';
|
|
31
60
|
return `${i + 1}. ${title}${hotStr}`;
|
|
32
61
|
})
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { fetchApi } from '../api.js';
|
|
1
|
+
import { asString, fetchApi } from '../api.js';
|
|
2
2
|
|
|
3
3
|
export default async function () {
|
|
4
|
-
const data = await fetchApi
|
|
4
|
+
const data = await fetchApi('/bing');
|
|
5
5
|
const lines = ['🖼️ Bing 每日壁纸', ''];
|
|
6
6
|
if (data.title) lines.push(`📌 ${data.title}`);
|
|
7
7
|
if (data.headline) lines.push(`💡 ${data.headline}`);
|
|
8
8
|
if (data.copyright) lines.push(`📝 ${data.copyright}`);
|
|
9
|
-
if (data.description) lines.push('', data.description);
|
|
9
|
+
if (data.description) lines.push('', asString(data.description));
|
|
10
10
|
const imgUrl = data.cover || data.cover_4k || data.url || data.image;
|
|
11
|
-
if (imgUrl) lines.push('', imgUrl);
|
|
11
|
+
if (imgUrl) lines.push('', asString(imgUrl));
|
|
12
12
|
return lines.join('\n');
|
|
13
13
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { fetchApi, formatList } from '../api.js';
|
|
1
|
+
import { fetchApi, formatList, type ListItem } from '../api.js';
|
|
2
2
|
|
|
3
3
|
export default async function (args: { limit?: number }) {
|
|
4
|
-
const data = await fetchApi<
|
|
4
|
+
const data = await fetchApi<ListItem[]>('/douyin');
|
|
5
5
|
return ['🔥 抖音热搜', '', formatList(data, args.limit || 10)].join('\n');
|
|
6
6
|
}
|
package/tools/duanzi/handler.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fetchApi } from '../api.js';
|
|
2
2
|
|
|
3
3
|
export default async function () {
|
|
4
|
-
const data = await fetchApi
|
|
4
|
+
const data = await fetchApi('/duanzi');
|
|
5
5
|
return `😂 段子\n\n${data.duanzi || data.content || data.text || (typeof data === 'string' ? data : '')}`;
|
|
6
6
|
}
|