chatgpt-plugin/apps/draw.js
2023-03-14 19:16:21 +08:00

226 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import plugin from '../../../lib/plugins/plugin.js'
import { segment } from 'oicq'
import { createImage, editImage, imageVariation } from '../utils/dalle.js'
import { makeForwardMsg } from '../utils/common.js'
import _ from 'lodash'
import { Config } from '../utils/config.js'
export class dalle extends plugin {
constructor (e) {
super({
name: 'ChatGPT-Plugin Dalle 绘图',
dsc: 'ChatGPT-Plugin基于OpenAI Dalle的绘图插件',
event: 'message',
priority: 500,
rule: [
{
reg: '^#(chatgpt|ChatGPT|dalle|Dalle)(绘图|画图)',
fnc: 'draw'
},
{
reg: '^#(chatgpt|ChatGPT|dalle|Dalle)(修图|图片变形|改图)$',
fnc: 'variation'
},
{
reg: '^#(搞|改)(她|他)头像',
fnc: 'avatarVariation'
},
{
reg: '^#(chatgpt|dalle)编辑图片',
fnc: 'edit'
}
]
})
}
async draw (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ttl = await redis.ttl(`CHATGPT:DRAW:${e.sender.user_id}`)
if (ttl > 0 && !e.isMaster) {
this.reply(`冷却中,请${ttl}秒后再试`)
return false
}
let splits = _.split(e.msg, '图', 2)
if (splits.length < 2) {
this.reply('请带上绘图要求')
return false
}
let rules = _.split(splits[1], '/')
let [prompt = '', num = '1', size = '512x512'] = rules.slice(0, 3)
if (['256x256', '512x512', '1024x1024'].indexOf(size) === -1) {
this.reply('大小不符合要求必须是256x256/512x512/1024x1024中的一个')
return false
}
await redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 })
let priceMap = {
'1024x1024': 0.02,
'512x512': 0.018,
'256x256': 0.016
}
num = parseInt(num, 10)
if (num > 5) {
this.reply('太多啦!你要花光我的余额吗!')
return false
}
await this.reply(`正在为您绘制大小为${size}${num}张图片,预计消耗${priceMap[size] * num}美元余额,请稍候……`)
try {
let images = (await createImage(prompt, num, size)).map(image => segment.image(`base64://${image}`))
if (images.length > 1) {
this.reply(await makeForwardMsg(e, images, prompt))
} else {
this.reply(images[0], true)
}
} catch (err) {
logger.error(err.response?.data?.error?.message)
this.reply(`绘图失败: ${err.response?.data?.error?.message}`, true)
await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`)
}
}
async variation (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ttl = await redis.ttl(`CHATGPT:VARIATION:${e.sender.user_id}`)
if (ttl > 0 && !e.isMaster) {
this.reply(`冷却中,请${ttl}秒后再试`)
return false
}
let imgUrl
if (e.source) {
let reply
if (e.isGroup) {
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message
} else {
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message
}
if (reply) {
for (let val of reply) {
if (val.type === 'image') {
console.log(val)
imgUrl = val.url
break
}
}
}
} else if (e.img) {
console.log(e.img)
imgUrl = e.img[0]
}
if (!imgUrl) {
this.reply('图呢?')
return false
}
await redis.set(`CHATGPT:VARIATION:${e.sender.user_id}`, 'c', { EX: 30 })
await this.reply('正在为您生成图片变形,请稍候……')
try {
let images = (await imageVariation(imgUrl)).map(image => segment.image(`base64://${image}`))
if (images.length > 1) {
this.reply(await makeForwardMsg(e, images))
} else {
this.reply(images[0], true)
}
} catch (err) {
console.log(err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {}))
this.reply(`绘图失败: ${err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {})}`, true)
await redis.del(`CHATGPT:VARIATION:${e.sender.user_id}`)
}
}
async avatarVariation (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ats = e.message.filter(m => m.type === 'at').filter(at => at.qq !== e.self_id)
if (ats.length > 0) {
for (let i = 0; i < ats.length; i++) {
let qq = ats[i].qq
let imgUrl = `https://q1.qlogo.cn/g?b=qq&s=0&nk=${qq}`
try {
let images = (await imageVariation(imgUrl)).map(image => segment.image(`base64://${image}`))
if (images.length > 1) {
this.reply(await makeForwardMsg(e, images))
} else {
this.reply(images[0], true)
}
} catch (err) {
console.log(err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {}))
this.reply(`搞失败了: ${err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {})}`, true)
await redis.del(`CHATGPT:VARIATION:${e.sender.user_id}`)
}
}
}
}
async edit (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ttl = await redis.ttl(`CHATGPT:EDIT:${e.sender.user_id}`)
if (ttl > 0 && !e.isMaster) {
this.reply(`冷却中,请${ttl}秒后再试`)
return false
}
let imgUrl
if (e.source) {
let reply
if (e.isGroup) {
reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message
} else {
reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message
}
if (reply) {
for (let val of reply) {
if (val.type === 'image') {
console.log(val)
imgUrl = val.url
break
}
}
}
} else if (e.img) {
console.log(e.img)
imgUrl = e.img[0]
}
if (!imgUrl) {
this.reply('图呢?')
return false
}
await redis.set(`CHATGPT:EDIT:${e.sender.user_id}`, 'c', { EX: 30 })
await this.reply('正在为您编辑图片,请稍候……')
let command = _.trimStart(e.msg, '#chatgpt编辑图片')
command = _.trimStart(command, '#dalle编辑图片')
// command = 'A bird on it/100,100,300,200/2/512x512'
let args = command.split('/')
let [prompt = '', position = '', num = '1', size = '512x512'] = args.slice(0, 4)
if (!prompt || !position) {
this.reply('编辑图片必须填写prompt和涂抹位置.参考格式A bird on it/100,100,300,200/2/512x512')
return false
}
num = parseInt(num, 10)
if (num > 5) {
this.reply('太多啦!你要花光我的余额吗!')
return false
}
try {
let images = (await editImage(imgUrl, position.split(',').map(p => parseInt(p, 10)), prompt, num, size))
.map(image => segment.image(`base64://${image}`))
if (images.length > 1) {
this.reply(await makeForwardMsg(e, images, prompt))
} else {
this.reply(images[0], true)
}
} catch (err) {
logger.error(err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {}))
this.reply(`图片编辑失败: ${err.response?.data?.error?.message || err.message || JSON.stringify(err.response || {})}`, true)
await redis.del(`CHATGPT:EDIT:${e.sender.user_id}`)
}
}
}