koishi-plugin-custom-image-api 0.0.1
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/lib/index.d.ts +44 -0
- package/lib/index.js +206 -0
- package/package.json +42 -0
- package/readme.md +5 -0
- package/src/index.ts +255 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "koishi-plugin-custom-image-api";
|
|
3
|
+
export declare const inject: string[];
|
|
4
|
+
export interface CustomImageApiItem {
|
|
5
|
+
name: string;
|
|
6
|
+
url: string;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface CustomSignApiItem {
|
|
10
|
+
name: string;
|
|
11
|
+
url: string;
|
|
12
|
+
paramName: string;
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface PluginConfig {
|
|
16
|
+
enableTextReply: boolean;
|
|
17
|
+
hsjpEnabled: boolean;
|
|
18
|
+
dmjpEnabled: boolean;
|
|
19
|
+
customImageApis: CustomImageApiItem[];
|
|
20
|
+
customSignApis: CustomSignApiItem[];
|
|
21
|
+
timeout: number;
|
|
22
|
+
successMessages: {
|
|
23
|
+
imageSuccess: string;
|
|
24
|
+
hsjpSuccess: string;
|
|
25
|
+
dmjpSuccess: string;
|
|
26
|
+
customSignSuccess: string;
|
|
27
|
+
};
|
|
28
|
+
tipMessages: {
|
|
29
|
+
noEnabledImageApi: string;
|
|
30
|
+
hsjpMissingMsg: string;
|
|
31
|
+
dmjpMissingText: string;
|
|
32
|
+
customSignMissingParam: string;
|
|
33
|
+
customSignNotFound: string;
|
|
34
|
+
apiListTitle: string;
|
|
35
|
+
imageApiSubtitle: string;
|
|
36
|
+
signApiSubtitle: string;
|
|
37
|
+
noImageApiConfigured: string;
|
|
38
|
+
noSignApiConfigured: string;
|
|
39
|
+
enabled: string;
|
|
40
|
+
disabled: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export declare const Config: Schema<PluginConfig>;
|
|
44
|
+
export declare function apply(ctx: Context, config: PluginConfig): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Config = exports.inject = exports.name = void 0;
|
|
7
|
+
exports.apply = apply;
|
|
8
|
+
const koishi_1 = require("koishi");
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
exports.name = 'koishi-plugin-custom-image-api';
|
|
11
|
+
exports.inject = ['axios'];
|
|
12
|
+
exports.Config = koishi_1.Schema.object({
|
|
13
|
+
enableTextReply: koishi_1.Schema.boolean().default(true),
|
|
14
|
+
hsjpEnabled: koishi_1.Schema.boolean().default(true),
|
|
15
|
+
dmjpEnabled: koishi_1.Schema.boolean().default(true),
|
|
16
|
+
customImageApis: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
17
|
+
name: koishi_1.Schema.string(),
|
|
18
|
+
url: koishi_1.Schema.string(),
|
|
19
|
+
enabled: koishi_1.Schema.boolean().default(true)
|
|
20
|
+
})).default([]),
|
|
21
|
+
customSignApis: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
22
|
+
name: koishi_1.Schema.string(),
|
|
23
|
+
url: koishi_1.Schema.string(),
|
|
24
|
+
paramName: koishi_1.Schema.string(),
|
|
25
|
+
enabled: koishi_1.Schema.boolean().default(true)
|
|
26
|
+
})).default([]),
|
|
27
|
+
timeout: koishi_1.Schema.number().default(10000),
|
|
28
|
+
successMessages: koishi_1.Schema.object({
|
|
29
|
+
imageSuccess: koishi_1.Schema.string().default('成功从「{{apiName}}」获取图片 ✨'),
|
|
30
|
+
hsjpSuccess: koishi_1.Schema.string().default('黑丝举牌图片生成成功 ✨'),
|
|
31
|
+
dmjpSuccess: koishi_1.Schema.string().default('动漫举牌图片生成成功 ✨'),
|
|
32
|
+
customSignSuccess: koishi_1.Schema.string().default('成功调用「{{name}}」举牌API生成图片 ✨')
|
|
33
|
+
}).default({
|
|
34
|
+
imageSuccess: '成功从「{{apiName}}」获取图片 ✨',
|
|
35
|
+
hsjpSuccess: '黑丝举牌图片生成成功 ✨',
|
|
36
|
+
dmjpSuccess: '动漫举牌图片生成成功 ✨',
|
|
37
|
+
customSignSuccess: '成功调用「{{name}}」举牌API生成图片 ✨'
|
|
38
|
+
}),
|
|
39
|
+
tipMessages: koishi_1.Schema.object({
|
|
40
|
+
noEnabledImageApi: koishi_1.Schema.string().default('暂无启用的自定义图片API,请先在配置页面添加并启用!'),
|
|
41
|
+
hsjpMissingMsg: koishi_1.Schema.string().default('缺少必填参数!用法:hsjp <第一行文字> [第二行文字] [第三行文字]'),
|
|
42
|
+
dmjpMissingText: koishi_1.Schema.string().default('缺少必填参数!用法:dmjp <文本内容>'),
|
|
43
|
+
customSignMissingParam: koishi_1.Schema.string().default('缺少必填参数!用法:custom-sign <举牌API名称> <文本内容>'),
|
|
44
|
+
customSignNotFound: koishi_1.Schema.string().default('未找到启用的自定义举牌API「{{name}}」!'),
|
|
45
|
+
apiListTitle: koishi_1.Schema.string().default('已配置的自定义API列表:'),
|
|
46
|
+
imageApiSubtitle: koishi_1.Schema.string().default('--- 自定义图片API ---'),
|
|
47
|
+
signApiSubtitle: koishi_1.Schema.string().default('--- 自定义举牌API ---'),
|
|
48
|
+
noImageApiConfigured: koishi_1.Schema.string().default('暂无配置任何自定义图片API!'),
|
|
49
|
+
noSignApiConfigured: koishi_1.Schema.string().default('暂无配置任何自定义举牌API!'),
|
|
50
|
+
enabled: koishi_1.Schema.string().default('已启用'),
|
|
51
|
+
disabled: koishi_1.Schema.string().default('已禁用')
|
|
52
|
+
}).default({
|
|
53
|
+
noEnabledImageApi: '暂无启用的自定义图片API,请先在配置页面添加并启用!',
|
|
54
|
+
hsjpMissingMsg: '缺少必填参数!用法:hsjp <第一行文字> [第二行文字] [第三行文字]',
|
|
55
|
+
dmjpMissingText: '缺少必填参数!用法:dmjp <文本内容>',
|
|
56
|
+
customSignMissingParam: '缺少必填参数!用法:custom-sign <举牌API名称> <文本内容>',
|
|
57
|
+
customSignNotFound: '未找到启用的自定义举牌API「{{name}}」!',
|
|
58
|
+
apiListTitle: '已配置的自定义API列表:',
|
|
59
|
+
imageApiSubtitle: '--- 自定义图片API ---',
|
|
60
|
+
signApiSubtitle: '--- 自定义举牌API ---',
|
|
61
|
+
noImageApiConfigured: '暂无配置任何自定义图片API!',
|
|
62
|
+
noSignApiConfigured: '暂无配置任何自定义举牌API!',
|
|
63
|
+
enabled: '已启用',
|
|
64
|
+
disabled: '已禁用'
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
function apply(ctx, config) {
|
|
68
|
+
const logger = new koishi_1.Logger('koishi-plugin-custom-image-api');
|
|
69
|
+
ctx.command('random-image')
|
|
70
|
+
.action(async ({ session }) => {
|
|
71
|
+
try {
|
|
72
|
+
const enabledApis = config.customImageApis.filter(api => api.enabled);
|
|
73
|
+
if (enabledApis.length === 0) {
|
|
74
|
+
return config.enableTextReply ? config.tipMessages.noEnabledImageApi : '';
|
|
75
|
+
}
|
|
76
|
+
const randomApi = enabledApis[Math.floor(Math.random() * enabledApis.length)];
|
|
77
|
+
logger.info(`随机选择图片API: ${randomApi.name}, URL: ${randomApi.url}`);
|
|
78
|
+
const response = await (0, axios_1.default)({
|
|
79
|
+
url: randomApi.url,
|
|
80
|
+
method: 'GET',
|
|
81
|
+
timeout: config.timeout,
|
|
82
|
+
responseType: 'arraybuffer'
|
|
83
|
+
});
|
|
84
|
+
const imageBuffer = Buffer.from(response.data);
|
|
85
|
+
const imageElement = koishi_1.segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`);
|
|
86
|
+
if (session)
|
|
87
|
+
await session.send(imageElement);
|
|
88
|
+
const successMsg = config.successMessages.imageSuccess.replace('{{apiName}}', randomApi.name);
|
|
89
|
+
return config.enableTextReply ? successMsg : '';
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.error(`获取图片失败: ${error.message}`);
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
ctx.command('hsjp <msg> [msg1] [msg2]')
|
|
97
|
+
.action(async ({ session }, msg, msg1 = '', msg2 = '') => {
|
|
98
|
+
if (!config.hsjpEnabled)
|
|
99
|
+
return '';
|
|
100
|
+
if (!msg) {
|
|
101
|
+
return config.enableTextReply ? config.tipMessages.hsjpMissingMsg : '';
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const apiUrl = `https://api.suyanw.cn/api/hsjp/?rgb1=0&rgb2=0&rgb3=0&msg=${encodeURIComponent(msg)}&msg1=${encodeURIComponent(msg1)}&msg2=${encodeURIComponent(msg2)}`;
|
|
105
|
+
logger.info(`调用黑丝举牌API: ${apiUrl}`);
|
|
106
|
+
const response = await (0, axios_1.default)({
|
|
107
|
+
url: apiUrl,
|
|
108
|
+
method: 'GET',
|
|
109
|
+
timeout: config.timeout,
|
|
110
|
+
responseType: 'arraybuffer'
|
|
111
|
+
});
|
|
112
|
+
const imageBuffer = Buffer.from(response.data);
|
|
113
|
+
const imageElement = koishi_1.segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`);
|
|
114
|
+
if (session)
|
|
115
|
+
await session.send(imageElement);
|
|
116
|
+
return config.enableTextReply ? config.successMessages.hsjpSuccess : '';
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logger.error(`黑丝举牌API调用失败: ${error.message}`);
|
|
120
|
+
return '';
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
ctx.command('dmjp <text>')
|
|
124
|
+
.action(async ({ session }, text) => {
|
|
125
|
+
if (!config.dmjpEnabled)
|
|
126
|
+
return '';
|
|
127
|
+
if (!text) {
|
|
128
|
+
return config.enableTextReply ? config.tipMessages.dmjpMissingText : '';
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const apiUrl = `https://api.suyanw.cn/api/dmjp.php?text=${encodeURIComponent(text)}`;
|
|
132
|
+
logger.info(`调用动漫举牌API: ${apiUrl}`);
|
|
133
|
+
const response = await (0, axios_1.default)({
|
|
134
|
+
url: apiUrl,
|
|
135
|
+
method: 'GET',
|
|
136
|
+
timeout: config.timeout,
|
|
137
|
+
responseType: 'arraybuffer'
|
|
138
|
+
});
|
|
139
|
+
const imageBuffer = Buffer.from(response.data);
|
|
140
|
+
const imageElement = koishi_1.segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`);
|
|
141
|
+
if (session)
|
|
142
|
+
await session.send(imageElement);
|
|
143
|
+
return config.enableTextReply ? config.successMessages.dmjpSuccess : '';
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
logger.error(`动漫举牌API调用失败: ${error.message}`);
|
|
147
|
+
return '';
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
ctx.command('custom-sign <name> <text>')
|
|
151
|
+
.action(async ({ session }, name, text) => {
|
|
152
|
+
if (!name || !text) {
|
|
153
|
+
return config.enableTextReply ? config.tipMessages.customSignMissingParam : '';
|
|
154
|
+
}
|
|
155
|
+
const targetApi = config.customSignApis.find(api => api.name === name && api.enabled);
|
|
156
|
+
if (!targetApi) {
|
|
157
|
+
const notFoundMsg = config.tipMessages.customSignNotFound.replace('{{name}}', name);
|
|
158
|
+
return config.enableTextReply ? notFoundMsg : '';
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const apiUrl = `${targetApi.url}?${targetApi.paramName}=${encodeURIComponent(text)}`;
|
|
162
|
+
logger.info(`调用自定义举牌API: ${targetApi.name}, URL: ${apiUrl}`);
|
|
163
|
+
const response = await (0, axios_1.default)({
|
|
164
|
+
url: apiUrl,
|
|
165
|
+
method: 'GET',
|
|
166
|
+
timeout: config.timeout,
|
|
167
|
+
responseType: 'arraybuffer'
|
|
168
|
+
});
|
|
169
|
+
const imageBuffer = Buffer.from(response.data);
|
|
170
|
+
const imageElement = koishi_1.segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`);
|
|
171
|
+
if (session)
|
|
172
|
+
await session.send(imageElement);
|
|
173
|
+
const successMsg = config.successMessages.customSignSuccess.replace('{{name}}', targetApi.name);
|
|
174
|
+
return config.enableTextReply ? successMsg : '';
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
logger.error(`自定义举牌API调用失败: ${error.message}`);
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
ctx.command('image-api list', '列出所有已配置的自定义API')
|
|
182
|
+
.action(({ session }) => {
|
|
183
|
+
if (!config.enableTextReply)
|
|
184
|
+
return '';
|
|
185
|
+
let list = config.tipMessages.apiListTitle + '\n';
|
|
186
|
+
list += config.tipMessages.imageApiSubtitle + '\n';
|
|
187
|
+
if (config.customImageApis.length === 0) {
|
|
188
|
+
list += config.tipMessages.noImageApiConfigured + '\n';
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
config.customImageApis.forEach((api, index) => {
|
|
192
|
+
list += `${index + 1}. ${api.name} - ${api.enabled ? config.tipMessages.enabled : config.tipMessages.disabled} - ${api.url}\n`;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
list += '\n' + config.tipMessages.signApiSubtitle + '\n';
|
|
196
|
+
if (config.customSignApis.length === 0) {
|
|
197
|
+
list += config.tipMessages.noSignApiConfigured + '\n';
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
config.customSignApis.forEach((api, index) => {
|
|
201
|
+
list += `${index + 1}. ${api.name} - ${api.enabled ? config.tipMessages.enabled : config.tipMessages.disabled} - ${api.url} (参数: ${api.paramName})\n`;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return list;
|
|
205
|
+
});
|
|
206
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-custom-image-api",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Koishi插件:自定义图片API随机调用 + 内置黑丝/动漫举牌 + 自定义举牌功能",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"src"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc -w"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"koishi",
|
|
17
|
+
"plugin",
|
|
18
|
+
"image",
|
|
19
|
+
"api",
|
|
20
|
+
"sign",
|
|
21
|
+
"举牌"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/Minecraft-1314/koishi-plugin-custom-image-api.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/Minecraft-1314/koishi-plugin-custom-image-api/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/Minecraft-1314/koishi-plugin-custom-image-api#readme",
|
|
31
|
+
"author": "",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"koishi": "^4.0.0",
|
|
35
|
+
"axios": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"typescript": "^5.3.3",
|
|
39
|
+
"@types/node": "^20.11.17",
|
|
40
|
+
"@koishijs/typings": "^4.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/readme.md
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { Context, Schema, segment, Logger, Session } from 'koishi'
|
|
2
|
+
import axios from 'axios'
|
|
3
|
+
|
|
4
|
+
export const name = 'koishi-plugin-custom-image-api'
|
|
5
|
+
export const inject = ['axios']
|
|
6
|
+
|
|
7
|
+
export interface CustomImageApiItem {
|
|
8
|
+
name: string
|
|
9
|
+
url: string
|
|
10
|
+
enabled: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface CustomSignApiItem {
|
|
14
|
+
name: string
|
|
15
|
+
url: string
|
|
16
|
+
paramName: string
|
|
17
|
+
enabled: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PluginConfig {
|
|
21
|
+
enableTextReply: boolean
|
|
22
|
+
hsjpEnabled: boolean
|
|
23
|
+
dmjpEnabled: boolean
|
|
24
|
+
customImageApis: CustomImageApiItem[]
|
|
25
|
+
customSignApis: CustomSignApiItem[]
|
|
26
|
+
timeout: number
|
|
27
|
+
successMessages: {
|
|
28
|
+
imageSuccess: string
|
|
29
|
+
hsjpSuccess: string
|
|
30
|
+
dmjpSuccess: string
|
|
31
|
+
customSignSuccess: string
|
|
32
|
+
}
|
|
33
|
+
tipMessages: {
|
|
34
|
+
noEnabledImageApi: string
|
|
35
|
+
hsjpMissingMsg: string
|
|
36
|
+
dmjpMissingText: string
|
|
37
|
+
customSignMissingParam: string
|
|
38
|
+
customSignNotFound: string
|
|
39
|
+
apiListTitle: string
|
|
40
|
+
imageApiSubtitle: string
|
|
41
|
+
signApiSubtitle: string
|
|
42
|
+
noImageApiConfigured: string
|
|
43
|
+
noSignApiConfigured: string
|
|
44
|
+
enabled: string
|
|
45
|
+
disabled: string
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const Config: Schema<PluginConfig> = Schema.object({
|
|
50
|
+
enableTextReply: Schema.boolean().default(true),
|
|
51
|
+
hsjpEnabled: Schema.boolean().default(true),
|
|
52
|
+
dmjpEnabled: Schema.boolean().default(true),
|
|
53
|
+
customImageApis: Schema.array(Schema.object({
|
|
54
|
+
name: Schema.string(),
|
|
55
|
+
url: Schema.string(),
|
|
56
|
+
enabled: Schema.boolean().default(true)
|
|
57
|
+
})).default([]),
|
|
58
|
+
customSignApis: Schema.array(Schema.object({
|
|
59
|
+
name: Schema.string(),
|
|
60
|
+
url: Schema.string(),
|
|
61
|
+
paramName: Schema.string(),
|
|
62
|
+
enabled: Schema.boolean().default(true)
|
|
63
|
+
})).default([]),
|
|
64
|
+
timeout: Schema.number().default(10000),
|
|
65
|
+
successMessages: Schema.object({
|
|
66
|
+
imageSuccess: Schema.string().default('成功从「{{apiName}}」获取图片 ✨'),
|
|
67
|
+
hsjpSuccess: Schema.string().default('黑丝举牌图片生成成功 ✨'),
|
|
68
|
+
dmjpSuccess: Schema.string().default('动漫举牌图片生成成功 ✨'),
|
|
69
|
+
customSignSuccess: Schema.string().default('成功调用「{{name}}」举牌API生成图片 ✨')
|
|
70
|
+
}).default({
|
|
71
|
+
imageSuccess: '成功从「{{apiName}}」获取图片 ✨',
|
|
72
|
+
hsjpSuccess: '黑丝举牌图片生成成功 ✨',
|
|
73
|
+
dmjpSuccess: '动漫举牌图片生成成功 ✨',
|
|
74
|
+
customSignSuccess: '成功调用「{{name}}」举牌API生成图片 ✨'
|
|
75
|
+
}),
|
|
76
|
+
tipMessages: Schema.object({
|
|
77
|
+
noEnabledImageApi: Schema.string().default('暂无启用的自定义图片API,请先在配置页面添加并启用!'),
|
|
78
|
+
hsjpMissingMsg: Schema.string().default('缺少必填参数!用法:hsjp <第一行文字> [第二行文字] [第三行文字]'),
|
|
79
|
+
dmjpMissingText: Schema.string().default('缺少必填参数!用法:dmjp <文本内容>'),
|
|
80
|
+
customSignMissingParam: Schema.string().default('缺少必填参数!用法:custom-sign <举牌API名称> <文本内容>'),
|
|
81
|
+
customSignNotFound: Schema.string().default('未找到启用的自定义举牌API「{{name}}」!'),
|
|
82
|
+
apiListTitle: Schema.string().default('已配置的自定义API列表:'),
|
|
83
|
+
imageApiSubtitle: Schema.string().default('--- 自定义图片API ---'),
|
|
84
|
+
signApiSubtitle: Schema.string().default('--- 自定义举牌API ---'),
|
|
85
|
+
noImageApiConfigured: Schema.string().default('暂无配置任何自定义图片API!'),
|
|
86
|
+
noSignApiConfigured: Schema.string().default('暂无配置任何自定义举牌API!'),
|
|
87
|
+
enabled: Schema.string().default('已启用'),
|
|
88
|
+
disabled: Schema.string().default('已禁用')
|
|
89
|
+
}).default({
|
|
90
|
+
noEnabledImageApi: '暂无启用的自定义图片API,请先在配置页面添加并启用!',
|
|
91
|
+
hsjpMissingMsg: '缺少必填参数!用法:hsjp <第一行文字> [第二行文字] [第三行文字]',
|
|
92
|
+
dmjpMissingText: '缺少必填参数!用法:dmjp <文本内容>',
|
|
93
|
+
customSignMissingParam: '缺少必填参数!用法:custom-sign <举牌API名称> <文本内容>',
|
|
94
|
+
customSignNotFound: '未找到启用的自定义举牌API「{{name}}」!',
|
|
95
|
+
apiListTitle: '已配置的自定义API列表:',
|
|
96
|
+
imageApiSubtitle: '--- 自定义图片API ---',
|
|
97
|
+
signApiSubtitle: '--- 自定义举牌API ---',
|
|
98
|
+
noImageApiConfigured: '暂无配置任何自定义图片API!',
|
|
99
|
+
noSignApiConfigured: '暂无配置任何自定义举牌API!',
|
|
100
|
+
enabled: '已启用',
|
|
101
|
+
disabled: '已禁用'
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
export function apply(ctx: Context, config: PluginConfig) {
|
|
106
|
+
const logger = new Logger('koishi-plugin-custom-image-api')
|
|
107
|
+
|
|
108
|
+
ctx.command('random-image')
|
|
109
|
+
.action(async ({ session }: { session?: Session }) => {
|
|
110
|
+
try {
|
|
111
|
+
const enabledApis = config.customImageApis.filter(api => api.enabled)
|
|
112
|
+
if (enabledApis.length === 0) {
|
|
113
|
+
return config.enableTextReply ? config.tipMessages.noEnabledImageApi : ''
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const randomApi = enabledApis[Math.floor(Math.random() * enabledApis.length)]
|
|
117
|
+
logger.info(`随机选择图片API: ${randomApi.name}, URL: ${randomApi.url}`)
|
|
118
|
+
|
|
119
|
+
const response = await axios({
|
|
120
|
+
url: randomApi.url,
|
|
121
|
+
method: 'GET',
|
|
122
|
+
timeout: config.timeout,
|
|
123
|
+
responseType: 'arraybuffer'
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
const imageBuffer = Buffer.from(response.data)
|
|
127
|
+
const imageElement = segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`)
|
|
128
|
+
if (session) await session.send(imageElement)
|
|
129
|
+
|
|
130
|
+
const successMsg = config.successMessages.imageSuccess.replace('{{apiName}}', randomApi.name)
|
|
131
|
+
return config.enableTextReply ? successMsg : ''
|
|
132
|
+
} catch (error) {
|
|
133
|
+
logger.error(`获取图片失败: ${(error as Error).message}`)
|
|
134
|
+
return ''
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
ctx.command('hsjp <msg> [msg1] [msg2]')
|
|
139
|
+
.action(async ({ session }: { session?: Session }, msg: string, msg1: string = '', msg2: string = '') => {
|
|
140
|
+
if (!config.hsjpEnabled) return ''
|
|
141
|
+
if (!msg) {
|
|
142
|
+
return config.enableTextReply ? config.tipMessages.hsjpMissingMsg : ''
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const apiUrl = `https://api.suyanw.cn/api/hsjp/?rgb1=0&rgb2=0&rgb3=0&msg=${encodeURIComponent(msg)}&msg1=${encodeURIComponent(msg1)}&msg2=${encodeURIComponent(msg2)}`
|
|
147
|
+
logger.info(`调用黑丝举牌API: ${apiUrl}`)
|
|
148
|
+
|
|
149
|
+
const response = await axios({
|
|
150
|
+
url: apiUrl,
|
|
151
|
+
method: 'GET',
|
|
152
|
+
timeout: config.timeout,
|
|
153
|
+
responseType: 'arraybuffer'
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
const imageBuffer = Buffer.from(response.data)
|
|
157
|
+
const imageElement = segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`)
|
|
158
|
+
if (session) await session.send(imageElement)
|
|
159
|
+
return config.enableTextReply ? config.successMessages.hsjpSuccess : ''
|
|
160
|
+
} catch (error) {
|
|
161
|
+
logger.error(`黑丝举牌API调用失败: ${(error as Error).message}`)
|
|
162
|
+
return ''
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
ctx.command('dmjp <text>')
|
|
167
|
+
.action(async ({ session }: { session?: Session }, text: string) => {
|
|
168
|
+
if (!config.dmjpEnabled) return ''
|
|
169
|
+
if (!text) {
|
|
170
|
+
return config.enableTextReply ? config.tipMessages.dmjpMissingText : ''
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
const apiUrl = `https://api.suyanw.cn/api/dmjp.php?text=${encodeURIComponent(text)}`
|
|
175
|
+
logger.info(`调用动漫举牌API: ${apiUrl}`)
|
|
176
|
+
|
|
177
|
+
const response = await axios({
|
|
178
|
+
url: apiUrl,
|
|
179
|
+
method: 'GET',
|
|
180
|
+
timeout: config.timeout,
|
|
181
|
+
responseType: 'arraybuffer'
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
const imageBuffer = Buffer.from(response.data)
|
|
185
|
+
const imageElement = segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`)
|
|
186
|
+
if (session) await session.send(imageElement)
|
|
187
|
+
return config.enableTextReply ? config.successMessages.dmjpSuccess : ''
|
|
188
|
+
} catch (error) {
|
|
189
|
+
logger.error(`动漫举牌API调用失败: ${(error as Error).message}`)
|
|
190
|
+
return ''
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
ctx.command('custom-sign <name> <text>')
|
|
195
|
+
.action(async ({ session }: { session?: Session }, name: string, text: string) => {
|
|
196
|
+
if (!name || !text) {
|
|
197
|
+
return config.enableTextReply ? config.tipMessages.customSignMissingParam : ''
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const targetApi = config.customSignApis.find(api => api.name === name && api.enabled)
|
|
201
|
+
if (!targetApi) {
|
|
202
|
+
const notFoundMsg = config.tipMessages.customSignNotFound.replace('{{name}}', name)
|
|
203
|
+
return config.enableTextReply ? notFoundMsg : ''
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const apiUrl = `${targetApi.url}?${targetApi.paramName}=${encodeURIComponent(text)}`
|
|
208
|
+
logger.info(`调用自定义举牌API: ${targetApi.name}, URL: ${apiUrl}`)
|
|
209
|
+
|
|
210
|
+
const response = await axios({
|
|
211
|
+
url: apiUrl,
|
|
212
|
+
method: 'GET',
|
|
213
|
+
timeout: config.timeout,
|
|
214
|
+
responseType: 'arraybuffer'
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
const imageBuffer = Buffer.from(response.data)
|
|
218
|
+
const imageElement = segment.image(`data:image/jpeg;base64,${imageBuffer.toString('base64')}`)
|
|
219
|
+
if (session) await session.send(imageElement)
|
|
220
|
+
|
|
221
|
+
const successMsg = config.successMessages.customSignSuccess.replace('{{name}}', targetApi.name)
|
|
222
|
+
return config.enableTextReply ? successMsg : ''
|
|
223
|
+
} catch (error) {
|
|
224
|
+
logger.error(`自定义举牌API调用失败: ${(error as Error).message}`)
|
|
225
|
+
return ''
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
ctx.command('image-api list', '列出所有已配置的自定义API')
|
|
230
|
+
.action(({ session }: { session?: Session }) => {
|
|
231
|
+
if (!config.enableTextReply) return ''
|
|
232
|
+
|
|
233
|
+
let list = config.tipMessages.apiListTitle + '\n'
|
|
234
|
+
|
|
235
|
+
list += config.tipMessages.imageApiSubtitle + '\n'
|
|
236
|
+
if (config.customImageApis.length === 0) {
|
|
237
|
+
list += config.tipMessages.noImageApiConfigured + '\n'
|
|
238
|
+
} else {
|
|
239
|
+
config.customImageApis.forEach((api, index) => {
|
|
240
|
+
list += `${index + 1}. ${api.name} - ${api.enabled ? config.tipMessages.enabled : config.tipMessages.disabled} - ${api.url}\n`
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
list += '\n' + config.tipMessages.signApiSubtitle + '\n'
|
|
245
|
+
if (config.customSignApis.length === 0) {
|
|
246
|
+
list += config.tipMessages.noSignApiConfigured + '\n'
|
|
247
|
+
} else {
|
|
248
|
+
config.customSignApis.forEach((api, index) => {
|
|
249
|
+
list += `${index + 1}. ${api.name} - ${api.enabled ? config.tipMessages.enabled : config.tipMessages.disabled} - ${api.url} (参数: ${api.paramName})\n`
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return list
|
|
254
|
+
})
|
|
255
|
+
}
|