koishi-plugin-nyweather 1.0.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.
@@ -0,0 +1,18 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-node@v4
13
+ with:
14
+ node-version: '22'
15
+ registry-url: 'https://registry.npmjs.org'
16
+ - run: npm publish
17
+ env:
18
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/index.js ADDED
@@ -0,0 +1,71 @@
1
+ const { Schema } = require('koishi')
2
+
3
+ const Config = Schema.object({
4
+ api_key: Schema.string()
5
+ .default('')
6
+ .description('柠柚API密钥(可不填)'),
7
+ default_format: Schema.union(['text', 'image'])
8
+ .default('image')
9
+ .description('默认返回格式:text 文本 / image 图片'),
10
+ })
11
+
12
+ async function queryWeather(ctx, config, city, days) {
13
+ const params = { query: city, format: config.default_format }
14
+ if (config.api_key) params.apikey = config.api_key
15
+ if (days >= 2) {
16
+ params.action = 'forecast'
17
+ params.days = Math.min(days, 8)
18
+ }
19
+
20
+ const url = 'https://api.nycnm.cn/api/v2/weather?' + new URLSearchParams(params).toString()
21
+
22
+ if (config.default_format === 'image') {
23
+ // 图片模式:获取API返回的图片URL,转成QQ可显示的图片消息
24
+ const resp = await ctx.http.get(url, { responseType: 'text' })
25
+ const data = typeof resp === 'string' ? resp : resp.data
26
+ const body = typeof data === 'string' ? JSON.parse(data) : data
27
+
28
+ if (body.success !== false && (body.data || body.url)) {
29
+ const imgUrl = body.data || body.url || data
30
+ // API直接返回图片URL
31
+ if (imgUrl.match(/^https?:\/\/.*\.(png|jpg|jpeg|gif|webp)/i)) {
32
+ return `<image url="${imgUrl}"/>`
33
+ }
34
+ // API返回HTML,可能嵌入了图片
35
+ const imgMatch = imgUrl.match(/https?:\/\/[^"'\s<>]+\.(png|jpg|jpeg|gif|webp)/i)
36
+ if (imgMatch) {
37
+ return `<image url="${imgMatch[0]}"/>`
38
+ }
39
+ }
40
+ // 图片获取失败,降级为文本
41
+ params.format = 'text'
42
+ const fallbackUrl = 'https://api.nycnm.cn/api/v2/weather?' + new URLSearchParams(params).toString()
43
+ const fbResp = await ctx.http.get(fallbackUrl, { responseType: 'text' })
44
+ const fbData = typeof fbResp === 'string' ? fbResp : fbResp.data
45
+ return typeof fbData === 'string' ? fbData : String(fbData)
46
+ }
47
+
48
+ // 文本模式
49
+ const resp = await ctx.http.get(url, { responseType: 'text' })
50
+ const data = typeof resp === 'string' ? resp : resp.data
51
+ return typeof data === 'string' ? data : String(data)
52
+ }
53
+
54
+ function apply(ctx, config) {
55
+ ctx.command('nyweather [city] [days:number]', '查询天气')
56
+ .alias('天气')
57
+ .action(async ({ session }, city, days) => {
58
+ if (!city) {
59
+ return '请输入城市名,例如:天气 北京\n查询多天预报:天气 北京 3(最多8天)'
60
+ }
61
+ if (!days || days <= 0) days = 1
62
+
63
+ try {
64
+ return await queryWeather(ctx, config, city, days)
65
+ } catch (e) {
66
+ return '天气查询失败: ' + (e.message || String(e))
67
+ }
68
+ })
69
+ }
70
+
71
+ module.exports = { Config, apply }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "koishi-plugin-nyweather",
3
+ "version": "1.0.0",
4
+ "description": "天气查询插件,基于柠柚API",
5
+ "main": "index.js",
6
+ "license": "MIT",
7
+ "keywords": ["koishi", "koishi-plugin", "weather", "天气"],
8
+ "peerDependencies": {
9
+ "koishi": "^4.18.0"
10
+ },
11
+ "devDependencies": {
12
+ "koishi": "^4.18.0"
13
+ },
14
+ "koishi": {
15
+ "description": {
16
+ "zh": "天气查询插件,支持文本和图片两种返回格式。命令:天气 <城市> [天数]",
17
+ "en": "Weather query plugin using nyapi, supports text and image output."
18
+ },
19
+ "service": {
20
+ "required": ["http"]
21
+ }
22
+ }
23
+ }