koishi-plugin-smmcat-nai-diffusion 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/chatSend.d.ts +17 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +244 -0
- package/package.json +20 -0
- package/readme.md +5 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context, Session } from "koishi";
|
|
2
|
+
import { Config } from ".";
|
|
3
|
+
/** 内容发送模块 */
|
|
4
|
+
export declare const Chat: {
|
|
5
|
+
config: Config;
|
|
6
|
+
ctx: Context;
|
|
7
|
+
chache: {};
|
|
8
|
+
messageIdTemp: {};
|
|
9
|
+
init(config: Config, ctx: Context): Promise<void>;
|
|
10
|
+
/** 发送消息 */
|
|
11
|
+
send(session: Session, content: string): Promise<void>;
|
|
12
|
+
isUseMd(session: Session): boolean;
|
|
13
|
+
/** 清除一条 msgid 记录 */
|
|
14
|
+
clearChache(): void;
|
|
15
|
+
/** 清除一条 messageId 缓存 */
|
|
16
|
+
clearMessageIdTemp(): void;
|
|
17
|
+
};
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "smmcat-nai-diffusion";
|
|
3
|
+
export interface Config {
|
|
4
|
+
token: string;
|
|
5
|
+
deBug: boolean;
|
|
6
|
+
useMd: boolean;
|
|
7
|
+
useGuildId: string[];
|
|
8
|
+
useGuildUser: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare const Config: Schema<Config>;
|
|
11
|
+
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name2 in all)
|
|
8
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
Config: () => Config,
|
|
24
|
+
apply: () => apply,
|
|
25
|
+
name: () => name
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(src_exports);
|
|
28
|
+
var import_koishi = require("koishi");
|
|
29
|
+
|
|
30
|
+
// src/chatSend.ts
|
|
31
|
+
var Chat = {
|
|
32
|
+
config: {},
|
|
33
|
+
ctx: {},
|
|
34
|
+
chache: {},
|
|
35
|
+
messageIdTemp: {},
|
|
36
|
+
async init(config, ctx) {
|
|
37
|
+
Chat.config = config;
|
|
38
|
+
Chat.ctx = ctx;
|
|
39
|
+
ctx.on("message", (session) => {
|
|
40
|
+
if (!Chat.messageIdTemp[session.userId]) {
|
|
41
|
+
Chat.messageIdTemp[session.userId] = {};
|
|
42
|
+
}
|
|
43
|
+
Chat.messageIdTemp[session.userId] = session.messageId;
|
|
44
|
+
Chat.clearMessageIdTemp();
|
|
45
|
+
}, true);
|
|
46
|
+
},
|
|
47
|
+
/** 发送消息 */
|
|
48
|
+
async send(session, content) {
|
|
49
|
+
if (session.platform !== "qq") {
|
|
50
|
+
await session.send(content);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (Chat.config.useMd) {
|
|
54
|
+
const messageId = session.messageId;
|
|
55
|
+
const userId = session.userId;
|
|
56
|
+
if (Chat.chache[messageId] == void 0) {
|
|
57
|
+
Chat.chache[messageId] = 0;
|
|
58
|
+
}
|
|
59
|
+
const mdContent = {
|
|
60
|
+
msg_id: session.messageId,
|
|
61
|
+
msg_type: 2,
|
|
62
|
+
msg_seq: ++Chat.chache[messageId] == 1 ? 0 : Chat.chache[messageId],
|
|
63
|
+
markdown: {
|
|
64
|
+
content
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
if (Chat.chache[messageId] > 1) {
|
|
68
|
+
Chat.config.deBug && console.log(`检测到MD连续发送,尝试递增 msg_seq 再进行再次发送;第${Chat.chache[messageId] + 1}次。`);
|
|
69
|
+
if (Chat.chache[messageId] > 5) {
|
|
70
|
+
if (Chat.messageIdTemp[userId] && mdContent.msg_id != Chat.messageIdTemp[userId]) {
|
|
71
|
+
Chat.config.deBug && console.log("middleware 存在新 mse_id 数据,使用更新数据");
|
|
72
|
+
mdContent.msg_id = Chat.messageIdTemp[userId];
|
|
73
|
+
mdContent.msg_seq = 0;
|
|
74
|
+
} else {
|
|
75
|
+
await session.send(content);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
if (session.guildId) {
|
|
81
|
+
await session.bot.internal.sendMessage(session.channelId, mdContent);
|
|
82
|
+
} else {
|
|
83
|
+
mdContent.markdown.content = mdContent.markdown.content.replace(/<qqbot-at-user[^>]*\/>/g, "");
|
|
84
|
+
await session.bot.internal.sendPrivateMessage(session.userId, mdContent);
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.log(error);
|
|
88
|
+
}
|
|
89
|
+
Chat.clearChache();
|
|
90
|
+
} else {
|
|
91
|
+
await session.send(content);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
// 当前 session 是否可以使用MD
|
|
95
|
+
isUseMd(session) {
|
|
96
|
+
if (session.platform !== "qq") return false;
|
|
97
|
+
if (Chat.chache[session.messageId] == void 0) return true;
|
|
98
|
+
return Chat.chache[session.messageId] <= 5;
|
|
99
|
+
},
|
|
100
|
+
/** 清除一条 msgid 记录 */
|
|
101
|
+
clearChache() {
|
|
102
|
+
const chache = Object.keys(Chat.chache);
|
|
103
|
+
if (chache.length >= 40) {
|
|
104
|
+
delete Chat.chache[chache[0]];
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
/** 清除一条 messageId 缓存 */
|
|
108
|
+
clearMessageIdTemp() {
|
|
109
|
+
const messageIdTempList = Object.keys(Chat.messageIdTemp);
|
|
110
|
+
if (messageIdTempList.length > 150) {
|
|
111
|
+
delete Chat.messageIdTemp[messageIdTempList[0]];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/index.ts
|
|
117
|
+
var name = "smmcat-nai-diffusion";
|
|
118
|
+
var Config = import_koishi.Schema.object({
|
|
119
|
+
deBug: import_koishi.Schema.boolean().default(false).description("获取更多日志消息"),
|
|
120
|
+
useMd: import_koishi.Schema.boolean().default(false).description("使用md发送消息"),
|
|
121
|
+
token: import_koishi.Schema.string().default("").description("[tuercha](https://api.tuercha.com/register) 绘图站提供的令牌"),
|
|
122
|
+
useGuildId: import_koishi.Schema.array(String).role("table").default([]).description("指定可用群"),
|
|
123
|
+
useGuildUser: import_koishi.Schema.array(String).role("table").default([]).description("指定可用人(无视可用群规则)")
|
|
124
|
+
});
|
|
125
|
+
function apply(ctx, config) {
|
|
126
|
+
ctx.on("ready", () => {
|
|
127
|
+
Chat.init(config, ctx);
|
|
128
|
+
});
|
|
129
|
+
const size = [[832, 1216], [1216, 832], [1024, 1024], [512, 768], [768, 512]];
|
|
130
|
+
const naiDiffusion = {
|
|
131
|
+
/** 通过词条获取图片 */
|
|
132
|
+
async getDrawByEntry(text) {
|
|
133
|
+
try {
|
|
134
|
+
const body = {
|
|
135
|
+
model: "nai-diffusion-4-5-full",
|
|
136
|
+
messages: [
|
|
137
|
+
{
|
|
138
|
+
role: "user",
|
|
139
|
+
content: JSON.stringify({
|
|
140
|
+
prompt: text,
|
|
141
|
+
negative_prompt: "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, ugly, deformed, poorly drawn hands, poorly drawn face, mutation, deformed, bad proportions, gross proportions, long neck, missing arms, missing legs, extra arms, extra legs, fused fingers, too many fingers, unclear eyes, bad body, out of focus, chromatic aberration",
|
|
142
|
+
size: size[Math.floor(Math.random() * size.length)],
|
|
143
|
+
steps: 23
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
stream: false,
|
|
148
|
+
max_tokens: 1e5
|
|
149
|
+
};
|
|
150
|
+
const res = await ctx.http.post("https://api.tuercha.com/v1/chat/completions", body, {
|
|
151
|
+
headers: {
|
|
152
|
+
Authorization: "Bearer " + config.token
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const imgList = [];
|
|
156
|
+
if (Array.isArray(res.choices)) {
|
|
157
|
+
for (const data of res.choices) {
|
|
158
|
+
const base64 = naiDiffusion.extractBase64(data.message.content || "");
|
|
159
|
+
if (base64) {
|
|
160
|
+
const imgUrl = await naiDiffusion.base64ToWebUrl(base64);
|
|
161
|
+
imgUrl && imgList.push(imgUrl);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return imgList;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.log(error);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
/** 输入的内容是否存在中文 */
|
|
172
|
+
containsForbiddenChars(str) {
|
|
173
|
+
return /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\uff00-\uffef\u3000\u3001-\u303f]/u.test(str);
|
|
174
|
+
},
|
|
175
|
+
/** 过滤筛选 base64 内容 */
|
|
176
|
+
extractBase64(raw) {
|
|
177
|
+
const match = raw.match(/data:image\/\w+;base64,[A-Za-z0-9+/=]+/);
|
|
178
|
+
return match ? match[0] : null;
|
|
179
|
+
},
|
|
180
|
+
/** 将 base64 图片转为 网络图片地址 */
|
|
181
|
+
async base64ToWebUrl(base64) {
|
|
182
|
+
try {
|
|
183
|
+
const res = await ctx.http.post("https://img.smmcat.top/proxy/image/base64", { base64 });
|
|
184
|
+
if (res.code !== 0) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
return res.localUrl;
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.log(error);
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const use = {
|
|
195
|
+
userId: {},
|
|
196
|
+
isUse(session) {
|
|
197
|
+
return use.userId[session.userId];
|
|
198
|
+
},
|
|
199
|
+
start(session) {
|
|
200
|
+
use.userId[session.userId] = +/* @__PURE__ */ new Date();
|
|
201
|
+
},
|
|
202
|
+
clear(session) {
|
|
203
|
+
delete use.userId[session.userId];
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
ctx.command("测试画 <prompt:text>").action(async ({ session }, prompt) => {
|
|
207
|
+
const { userId, guildId } = session;
|
|
208
|
+
if (!config.useGuildUser.includes(userId)) {
|
|
209
|
+
if (!(guildId && config.useGuildId.includes(guildId))) {
|
|
210
|
+
return `该群暂时不提供该功能...`;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (!prompt) return "请传词条!";
|
|
214
|
+
if (use.isUse(session)) return `正在进行上一个绘画,请等待...`;
|
|
215
|
+
if (naiDiffusion.containsForbiddenChars(prompt)) return `输入的词条包含问题,请检查!`;
|
|
216
|
+
try {
|
|
217
|
+
use.start(session);
|
|
218
|
+
await Chat.send(session, `<qqbot-at-user id="${userId}" /> 稍等,正在给你画...`);
|
|
219
|
+
const imgs = await naiDiffusion.getDrawByEntry(prompt);
|
|
220
|
+
if (config.useMd) {
|
|
221
|
+
const md = `<qqbot-at-user id="${userId}" /> 画完了,请点击下方查看!
|
|
222
|
+
|
|
223
|
+
${imgs.map((item) => {
|
|
224
|
+
return `[查看图片](${item})`;
|
|
225
|
+
}).join("\n")}`;
|
|
226
|
+
await Chat.send(session, md);
|
|
227
|
+
} else {
|
|
228
|
+
await Chat.send(session, imgs.map((item) => {
|
|
229
|
+
return import_koishi.h.image(item);
|
|
230
|
+
}).join("\n"));
|
|
231
|
+
}
|
|
232
|
+
use.clear(session);
|
|
233
|
+
} catch (error) {
|
|
234
|
+
use.clear(session);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
__name(apply, "apply");
|
|
239
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
240
|
+
0 && (module.exports = {
|
|
241
|
+
Config,
|
|
242
|
+
apply,
|
|
243
|
+
name
|
|
244
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-smmcat-nai-diffusion",
|
|
3
|
+
"description": "来自 tuercha.com 公益站的绘图服务",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"chatbot",
|
|
14
|
+
"koishi",
|
|
15
|
+
"plugin"
|
|
16
|
+
],
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"koishi": "^4.18.7"
|
|
19
|
+
}
|
|
20
|
+
}
|