mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-18 20:50:12 +08:00
650 lines
22 KiB
Go
650 lines
22 KiB
Go
// Package wenxin 百度文心AI
|
||
package wenxin
|
||
|
||
import (
|
||
"errors"
|
||
"strconv"
|
||
"strings"
|
||
"sync"
|
||
"time"
|
||
|
||
fcext "github.com/FloatTech/floatbox/ctxext"
|
||
"github.com/FloatTech/floatbox/process"
|
||
ctrl "github.com/FloatTech/zbpctrl"
|
||
"github.com/FloatTech/zbputils/control"
|
||
"github.com/FloatTech/zbputils/ctxext"
|
||
zero "github.com/wdvxdr1123/ZeroBot"
|
||
"github.com/wdvxdr1123/ZeroBot/message"
|
||
|
||
// 数据库
|
||
sql "github.com/FloatTech/sqlite"
|
||
// 百度文心大模型
|
||
model "github.com/FloatTech/AnimeAPI/wenxinAI/erniemodle"
|
||
// 百度文心AI画图API
|
||
wenxin "github.com/FloatTech/AnimeAPI/wenxinAI/ernievilg"
|
||
)
|
||
|
||
const (
|
||
serviceErr = "[wenxinvilg]ERROR:\n"
|
||
modelErr = "[wenxinmodel]ERROR:\n"
|
||
)
|
||
|
||
type keydb struct {
|
||
sync.RWMutex
|
||
db sql.Sqlite
|
||
}
|
||
|
||
// db内容
|
||
type apikey struct {
|
||
ID int64 // 群号
|
||
APIKey string // API Key
|
||
SecretKey string // Secret Key
|
||
Token string // AccessToken
|
||
Updatetime int64 // token的有效时间
|
||
MaxLimit int // 总使用次数
|
||
DayLimit int // 当天的使用次数
|
||
Lasttime string // 记录使用的时间,用于刷新使用次数
|
||
}
|
||
|
||
var (
|
||
name = "椛椛"
|
||
limit int
|
||
vilginfo keydb
|
||
modelinfo keydb
|
||
dtype = [...]string{
|
||
"古风", "油画", "水彩画", "卡通画", "二次元", "浮世绘", "蒸汽波艺术", "low poly", "像素风格", "概念艺术", "未来主义", "赛博朋克", "写实风格", "洛丽塔风格", "巴洛克风格", "超现实主义",
|
||
}
|
||
)
|
||
|
||
func init() { // 插件主体
|
||
go func() {
|
||
process.GlobalInitMutex.Lock()
|
||
defer process.GlobalInitMutex.Unlock()
|
||
name = zero.BotConfig.NickName[0]
|
||
}()
|
||
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||
DisableOnDefault: false,
|
||
Brief: "文心AI画图",
|
||
Help: "基于百度文心的免费AI画图插件,\n因为是免费的,图片质量你懂的。\n" +
|
||
"key申请链接:https://wenxin.baidu.com/moduleApi/key\n" +
|
||
"key和erniemodel插件的key相同。\n" +
|
||
"注意:每个apikey每日上限50次,总上限500次请求。次数超过了请自行更新apikey\n" +
|
||
"- 为[自己/本群/QQ号/群+群号]设置画图key [API Key] [Secret Key]\n" +
|
||
"例:\n为自己设置画图key 123 456\n为10086设置画图key 123 456\n为群10010设置画图key 789 101\n" +
|
||
"- [bot名称]画几张[图片描述]的[图片类型][图片尺寸]\n" +
|
||
"————————————————————\n" +
|
||
"图片描述指南:\n图片主体,细节词(请用逗号连接)\n官方prompt指南:https://wenxin.baidu.com/wenxin/docs#Ol7ece95m\n" +
|
||
"————————————————————\n" +
|
||
"图片类型当前支持:" + strings.Join(dtype[:], "、") +
|
||
"\n————————————————————\n" +
|
||
"图片尺寸当前只支持:方图/长图/横图\n" +
|
||
"————————————————————\n" +
|
||
"指令示例:\n" +
|
||
name + "帮我画几张金凤凰,背景绚烂,高饱和,古风,仙境,高清,4K,古风的油画方图",
|
||
PrivateDataFolder: "wenxinAI",
|
||
}).ApplySingle(ctxext.NewGroupSingle("正在给别人画图,请不要打扰哦"))
|
||
getdb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
|
||
vilginfo.db = sql.New(engine.DataFolder() + "ernieVilg.db")
|
||
err := vilginfo.db.Open(time.Hour)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
// 画图
|
||
engine.OnRegex(`画几张(.*[^的$])的(.*[^\s$])(方图|长图|横图)$`, zero.OnlyToMe, getdb).SetBlock(true).
|
||
Handle(func(ctx *zero.Ctx) {
|
||
uid := -ctx.Event.UserID
|
||
gid := ctx.Event.GroupID
|
||
// 获取个人和群的key
|
||
userinfo, err1 := vilginfo.checkGroup(uid, "vilg")
|
||
info, err2 := vilginfo.checkGroup(gid, "vilg")
|
||
switch {
|
||
// 如果是个人请求且报错
|
||
case gid == 0 && err1 != nil:
|
||
ctx.SendChain(message.Text(serviceErr, err1))
|
||
return
|
||
// 如果群报错而个人没有,就切换成个人的
|
||
case err2 != nil && err1 == nil:
|
||
gid = uid
|
||
info = userinfo
|
||
// 如果都报错就以群为优先级
|
||
case err1 != nil && err2 != nil:
|
||
ctx.SendChain(message.Text(serviceErr, err2))
|
||
return
|
||
}
|
||
// 判断使用次数
|
||
check := false
|
||
switch {
|
||
// 群和个人都没有次数了
|
||
case info.DayLimit == 0 && userinfo.DayLimit == 0:
|
||
ctx.SendChain(message.Text("我已经画了", limit, "张了!我累了!不画不画,就不画!"))
|
||
return
|
||
// 个人还有次数的话
|
||
case info.DayLimit == 0 && userinfo.DayLimit != 0:
|
||
check = true
|
||
}
|
||
switch {
|
||
// 群和个人都没有总次数了
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit == 0:
|
||
ctx.SendChain(message.Text("设置的key使用次数超过了限额,请更换key。"))
|
||
return
|
||
// 个人还有总次数的话
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit != 0:
|
||
check = true
|
||
}
|
||
if check { // 如果只有个人有次数就切换回个人key
|
||
gid = uid
|
||
info = userinfo
|
||
}
|
||
// 创建任务
|
||
keyword := ctx.State["regex_matched"].([]string)[1]
|
||
if len([]rune(keyword)) >= 64 { // 描述不能超过64个字
|
||
ctx.SendChain(message.Text("要求太多了啦!减少点!"))
|
||
return
|
||
}
|
||
picType := ctx.State["regex_matched"].([]string)[2]
|
||
chooseSize := ctx.State["regex_matched"].([]string)[3]
|
||
wtime := 3
|
||
picSize := "1024*1024"
|
||
switch chooseSize {
|
||
case "长图":
|
||
wtime = 5
|
||
picSize = "1024*1536"
|
||
case "横图":
|
||
wtime = 5
|
||
picSize = "1536*1024"
|
||
}
|
||
taskID, err := wenxin.BuildWork(info.Token, keyword, picType, picSize)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return
|
||
}
|
||
if taskID < 1 {
|
||
ctx.SendChain(message.Text("要求太复杂力!想不出来..."))
|
||
return
|
||
}
|
||
// 开始画图
|
||
ctx.SendChain(message.Text(zero.BotConfig.NickName[0], "知道了,我可能需要", time.Duration(wtime*10)*time.Second, "左右才能画好哦,请等待..."))
|
||
i := 0
|
||
for range time.NewTicker(10 * time.Second).C {
|
||
// 等待 wtime * 10秒
|
||
i++
|
||
if i <= wtime {
|
||
continue
|
||
}
|
||
/*
|
||
if i > 60{// 十分钟还不出图就放弃
|
||
ctx.SendChain(message.Text("呜呜呜,要求太复杂力!画不出来..."))
|
||
return
|
||
}
|
||
// 获取结果*/
|
||
picURL, status, err := wenxin.GetPic(info.Token, taskID)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return
|
||
}
|
||
if status == "0" {
|
||
lastTime := time.Duration(i * 10 * int(time.Second))
|
||
msg := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Text("我画好了!\n本次绘画用了", lastTime))}
|
||
for _, imginfo := range picURL {
|
||
msg = append(msg,
|
||
ctxext.FakeSenderForwardNode(ctx,
|
||
message.Image(imginfo.Image)))
|
||
}
|
||
if id := ctx.Send(msg).ID(); id == 0 {
|
||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||
}
|
||
break
|
||
}
|
||
}
|
||
err = vilginfo.update(gid, 1)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
}
|
||
process.SleepAbout1sTo2s()
|
||
ctx.SendChain(message.Text("累死了,今天我最多只能画", info.DayLimit-1, "张图哦"))
|
||
})
|
||
engine.OnRegex(`^为(群)?(自己|本群|\d+)设置画图key\s(.*[^\s$])\s(.+)$`, getdb).SetBlock(true).
|
||
Handle(func(ctx *zero.Ctx) {
|
||
mode := ctx.State["regex_matched"].([]string)[1]
|
||
user := ctx.State["regex_matched"].([]string)[2]
|
||
aKey := ctx.State["regex_matched"].([]string)[3]
|
||
sKey := ctx.State["regex_matched"].([]string)[4]
|
||
dbID := -ctx.Event.UserID // 默认给自己
|
||
switch {
|
||
case mode != "": // 指定群的话
|
||
gid, err := strconv.ParseInt(user, 10, 64)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return
|
||
}
|
||
dbID = gid
|
||
case user == "本群": // 用于本群
|
||
gid := ctx.Event.GroupID
|
||
if gid == 0 {
|
||
ctx.SendChain(message.Text(serviceErr, "请指定群聊,或者使用指令;\n为群xxx设置AI画图key xxx xxx"))
|
||
return
|
||
}
|
||
dbID = gid
|
||
case user != "自己": // 给别人开key
|
||
uid, err := strconv.ParseInt(user, 10, 64)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return
|
||
}
|
||
dbID = -uid
|
||
}
|
||
err := vilginfo.insert(dbID, "vilg", aKey, sKey)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(serviceErr, err))
|
||
return
|
||
}
|
||
ctx.SendChain(message.Text("成功!"))
|
||
})
|
||
/*********************************************************/
|
||
en := control.Register("wenxinmodel", &ctrl.Options[*zero.Ctx]{
|
||
DisableOnDefault: false,
|
||
Brief: "文心AI文本处理",
|
||
Help: "基于百度文心AI的API文本处理\n" +
|
||
"key申请链接:https://wenxin.baidu.com/moduleApi/key\n" +
|
||
"key和ernievilg插件的key相同。\n" +
|
||
"注意:每个apikey每日上限200条,总上限2000条。次数超过了请自行更新apikey\n" +
|
||
"- 为[自己/本群/QQ号/群+群号]设置文心key [API Key] [Secret Key]\n" +
|
||
"例:\n为自己设置文心key 123 456\n为10086设置文心key 123 456\n为群10010设置文心key 789 101\n" +
|
||
"————————————————————\n" +
|
||
"- 文心作文 (x字的)[作文题目]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心提案 (x字的)[文案标题]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心摘要 (x字的)[文章内容]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心小说 (x字的)[小说上文]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心对联 [上联]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心问答 [问题]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心补全 [带“_”的填空题]\n" +
|
||
"————————————————————\n" +
|
||
"- 文心自定义 [prompt]\n\n" +
|
||
"prompt: [问题描述] [问题类型]:[题目] [解答类型]:[解题必带内容]\n" +
|
||
"指令示例:\n" +
|
||
"文心自定义 请写出下面这道题的解题过程。\\n题目:养殖场养鸭376只,养鸡的只数比鸭多258只,这个养殖场一共养鸭和鸡多少只?\\n解:\n\n" +
|
||
"文心自定义 1+1=?\n" +
|
||
"文心自定义 歌曲名:大风车转啊转\\n歌词:",
|
||
}).ApplySingle(ctxext.NewGroupSingle("正在给别人编辑,请不要打扰哦"))
|
||
getmodeldb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
|
||
modelinfo.db = sql.New(engine.DataFolder() + "ernieModel.db")
|
||
err := modelinfo.db.Open(time.Hour)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
en.OnRegex(`^为(群)?(自己|本群|\d+)设置文心key\s(.*[^\s$])\s(.+)$`, getmodeldb).SetBlock(true).
|
||
Handle(func(ctx *zero.Ctx) {
|
||
mode := ctx.State["regex_matched"].([]string)[1]
|
||
user := ctx.State["regex_matched"].([]string)[2]
|
||
aKey := ctx.State["regex_matched"].([]string)[3]
|
||
sKey := ctx.State["regex_matched"].([]string)[4]
|
||
dbID := -ctx.Event.UserID // 默认给自己
|
||
switch {
|
||
case mode != "": // 指定群的话
|
||
gid, err := strconv.ParseInt(user, 10, 64)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
dbID = gid
|
||
case user == "本群": // 用于本群
|
||
gid := ctx.Event.GroupID
|
||
if gid == 0 {
|
||
ctx.SendChain(message.Text(modelErr, "请指定群聊,或者使用指令;\n为群xxx设置AI画图key xxx xxx"))
|
||
return
|
||
}
|
||
dbID = gid
|
||
case user != "自己": // 给别人开key
|
||
uid, err := strconv.ParseInt(user, 10, 64)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
dbID = -uid
|
||
}
|
||
err := modelinfo.insert(dbID, "model", aKey, sKey)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
ctx.SendChain(message.Text("成功!"))
|
||
})
|
||
|
||
var erniemodel = map[string]int{
|
||
"作文": 1,
|
||
"提案": 2,
|
||
"摘要": 3,
|
||
"对联": 4,
|
||
"问答": 5,
|
||
"小说": 6,
|
||
"补全": 7,
|
||
"自定义": 8}
|
||
var erniePrompt = map[string]string{
|
||
"作文": "zuowen",
|
||
"提案": "adtext",
|
||
"摘要": "Summarization",
|
||
"对联": "couplet",
|
||
"问答": "Dialogue",
|
||
"小说": "novel",
|
||
"补全": "cloze"}
|
||
en.OnRegex(`^文心(作文|提案|摘要|小说)\s?((\d+)字的)?(.*)$`, getmodeldb).SetBlock(true).
|
||
Handle(func(ctx *zero.Ctx) {
|
||
uid := -ctx.Event.UserID
|
||
gid := ctx.Event.GroupID
|
||
// 获取个人和群的key
|
||
userinfo, err1 := modelinfo.checkGroup(uid, "model")
|
||
info, err2 := modelinfo.checkGroup(gid, "model")
|
||
switch {
|
||
// 如果是个人请求且报错
|
||
case gid == 0 && err1 != nil:
|
||
ctx.SendChain(message.Text(modelErr, err1))
|
||
return
|
||
// 如果群报错而个人没有,就切换成个人的
|
||
case err2 != nil && err1 == nil:
|
||
gid = uid
|
||
info = userinfo
|
||
// 如果都报错就以群为优先级
|
||
case err1 != nil && err2 != nil:
|
||
ctx.SendChain(message.Text(modelErr, err2))
|
||
return
|
||
}
|
||
// 判断使用次数
|
||
check := false
|
||
switch {
|
||
// 群和个人都没有次数了
|
||
case info.DayLimit == 0 && userinfo.DayLimit == 0:
|
||
ctx.SendChain(message.Text("今日请求次数已到200次了,明天在玩吧"))
|
||
return
|
||
// 个人还有次数的话
|
||
case info.DayLimit == 0 && userinfo.DayLimit != 0:
|
||
check = true
|
||
}
|
||
switch {
|
||
// 群和个人都没有总次数了
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit == 0:
|
||
ctx.SendChain(message.Text("设置的key使用次数超过了限额,请更换key。"))
|
||
return
|
||
// 个人还有总次数的话
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit != 0:
|
||
check = true
|
||
}
|
||
if check { // 如果只有个人有次数就切换回个人key
|
||
gid = uid
|
||
info = userinfo
|
||
}
|
||
// 调用API
|
||
modelStr := ctx.State["regex_matched"].([]string)[1]
|
||
mun := ctx.State["regex_matched"].([]string)[3]
|
||
minlen := 1
|
||
maxlen := 128
|
||
if mun != "" {
|
||
maxNum, err := strconv.Atoi(mun)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
minlen = maxNum
|
||
if maxNum > 128 {
|
||
maxlen = maxNum
|
||
}
|
||
}
|
||
keyword := ctx.State["regex_matched"].([]string)[4]
|
||
if len([]rune(keyword)) >= 1000 { // 描述不能超过1000
|
||
ctx.SendChain(message.Text("是你写作文还是我写?减少点!"))
|
||
return
|
||
}
|
||
result, err := model.GetResult(info.Token, erniemodel[modelStr], keyword, minlen, maxlen, erniePrompt[modelStr])
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
if id := ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(keyword, ",", result))); id.ID() == 0 {
|
||
ctx.SendChain(message.Text("ERROR: 请求超时!"))
|
||
}
|
||
err = modelinfo.update(gid, 1)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
}
|
||
})
|
||
en.OnRegex(`^文心(对联|问答|补全|自定义)\s?(.*)$`, getmodeldb).SetBlock(true).
|
||
Handle(func(ctx *zero.Ctx) {
|
||
uid := -ctx.Event.UserID
|
||
gid := ctx.Event.GroupID
|
||
// 获取个人和群的key
|
||
userinfo, err1 := modelinfo.checkGroup(uid, "model")
|
||
info, err2 := modelinfo.checkGroup(gid, "model")
|
||
switch {
|
||
// 如果是个人请求且报错
|
||
case gid == 0 && err1 != nil:
|
||
ctx.SendChain(message.Text(modelErr, err1))
|
||
return
|
||
// 如果群报错而个人没有,就切换成个人的
|
||
case err2 != nil && err1 == nil:
|
||
gid = uid
|
||
info = userinfo
|
||
// 如果都报错就以群为优先级
|
||
case err1 != nil && err2 != nil:
|
||
ctx.SendChain(message.Text(modelErr, err2))
|
||
return
|
||
}
|
||
// 判断使用次数
|
||
check := false
|
||
switch {
|
||
// 群和个人都没有次数了
|
||
case info.DayLimit == 0 && userinfo.DayLimit == 0:
|
||
ctx.SendChain(message.Text("今日请求次数已到200次了,明天在玩吧"))
|
||
return
|
||
// 个人还有次数的话
|
||
case info.DayLimit == 0 && userinfo.DayLimit != 0:
|
||
check = true
|
||
}
|
||
switch {
|
||
// 群和个人都没有总次数了
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit == 0:
|
||
ctx.SendChain(message.Text("设置的key使用次数超过了限额,请更换key。"))
|
||
return
|
||
// 个人还有总次数的话
|
||
case info.MaxLimit == 0 && userinfo.MaxLimit != 0:
|
||
check = true
|
||
}
|
||
if check { // 如果只有个人有次数就切换回个人key
|
||
gid = uid
|
||
info = userinfo
|
||
}
|
||
// 创建任务
|
||
modelStr := ctx.State["regex_matched"].([]string)[1]
|
||
keyword := ctx.State["regex_matched"].([]string)[2]
|
||
if len([]rune(keyword)) >= 1000 { // 描述不能超过1000
|
||
ctx.SendChain(message.Text("你在写作文吗?减少点!"))
|
||
return
|
||
}
|
||
result, err := model.GetResult(info.Token, erniemodel[modelStr], keyword, 1, 128, erniePrompt[modelStr])
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
return
|
||
}
|
||
if id := ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(result))); id.ID() == 0 {
|
||
ctx.SendChain(message.Text("ERROR: 请求超时!"))
|
||
}
|
||
err = modelinfo.update(gid, 1)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text(modelErr, err))
|
||
}
|
||
})
|
||
}
|
||
|
||
// 登记group的key
|
||
func (sql *keydb) insert(gid int64, model, akey, skey string) error {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
// 给db文件创建表格(没有才创建),表格名称groupinfo,表格结构apikey
|
||
err := sql.db.Create("groupinfo", &apikey{})
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 获取group信息
|
||
groupinfo := apikey{} // 用于暂存数据
|
||
err = sql.db.Find("groupinfo", &groupinfo, "WHERE ID = ?", gid)
|
||
if err != nil {
|
||
// 如果该group没有注册过
|
||
err = sql.db.Find("groupinfo", &groupinfo, "WHERE APIKey = ? and SecretKey = ?", akey, skey)
|
||
if err == nil {
|
||
// 如果key存在过将当前的数据迁移过去
|
||
groupinfo.ID = gid
|
||
} else {
|
||
groupinfo = apikey{
|
||
ID: gid,
|
||
APIKey: akey,
|
||
SecretKey: skey,
|
||
}
|
||
switch model {
|
||
case "vilg":
|
||
groupinfo.MaxLimit = 500
|
||
case "model":
|
||
groupinfo.MaxLimit = 2000
|
||
}
|
||
}
|
||
return sql.db.Insert("groupinfo", &groupinfo)
|
||
}
|
||
// 进行更新
|
||
groupinfo.APIKey = akey
|
||
groupinfo.SecretKey = skey
|
||
groupinfo.Token = ""
|
||
groupinfo.Updatetime = 0
|
||
switch model {
|
||
case "vilg":
|
||
groupinfo.MaxLimit = 500
|
||
case "model":
|
||
groupinfo.MaxLimit = 2000
|
||
}
|
||
return sql.db.Insert("groupinfo", &groupinfo)
|
||
}
|
||
|
||
// 获取group信息
|
||
func (sql *keydb) checkGroup(gid int64, model string) (groupinfo apikey, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
// 给db文件创建表格(没有才创建),表格名称groupinfo,表格结构apikey
|
||
err = sql.db.Create("groupinfo", &apikey{})
|
||
if err != nil {
|
||
return
|
||
}
|
||
switch model {
|
||
case "vilg":
|
||
limit = 50
|
||
model = "画图"
|
||
case "model":
|
||
limit = 200
|
||
model = "文心"
|
||
}
|
||
// 先判断该群是否已经设置过key了
|
||
if ok := sql.db.CanFind("groupinfo", "WHERE ID = ?", gid); !ok {
|
||
if gid > 0 {
|
||
err = errors.New("该群没有设置过apikey,请前往https://wenxin.baidu.com/moduleApi/key获取key值后,发送指令:\n为本群设置" + model + "key [API Key] [Secret Key]\n或\n为自己设置" + model + "key [API Key] [Secret Key]")
|
||
} else {
|
||
err = errors.New("你没有设置过apikey,请前往https://wenxin.baidu.com/moduleApi/key获取key值后,发送指令:\n为自己设置" + model + "key [API Key] [Secret Key]")
|
||
}
|
||
return
|
||
}
|
||
// 获取group信息
|
||
err = sql.db.Find("groupinfo", &groupinfo, "WHERE ID = ?", gid)
|
||
if err != nil {
|
||
return
|
||
}
|
||
// 如果隔天使用刷新次数
|
||
if time.Now().Format("2006/01/02") != groupinfo.Lasttime {
|
||
groupinfo.DayLimit = limit
|
||
groupinfo.Lasttime = time.Now().Format("2006/01/02")
|
||
}
|
||
if err = sql.db.Insert("groupinfo", &groupinfo); err != nil {
|
||
return
|
||
}
|
||
// 如果token有效期过期
|
||
if time.Since(time.Unix(groupinfo.Updatetime, 0)).Hours() > 24 || groupinfo.Token == "" {
|
||
token, err1 := wenxin.GetToken(groupinfo.APIKey, groupinfo.SecretKey)
|
||
if err1 != nil {
|
||
err = err1
|
||
return
|
||
}
|
||
groupinfo.Token = token
|
||
groupinfo.Updatetime = time.Now().Unix()
|
||
err = sql.db.Insert("groupinfo", &groupinfo)
|
||
if err == nil {
|
||
// 更新相同key的他人次数
|
||
otherinfo := apikey{}
|
||
var groups []int64 // 将相同的key的ID暂存
|
||
// 无视没有找到相同的key的err
|
||
_ = sql.db.FindFor("groupinfo", &otherinfo, "WHERE ID <> ? AND APIKey = ? AND SecretKey = ?", func() error {
|
||
groups = append(groups, otherinfo.ID)
|
||
return nil
|
||
}, gid, groupinfo.APIKey, groupinfo.SecretKey)
|
||
if len(groups) != 0 { // 如果有相同的key就更新
|
||
for _, group := range groups {
|
||
err = sql.db.Find("groupinfo", &otherinfo, "WHERE ID = ?", group)
|
||
if err == nil {
|
||
otherinfo.Token = groupinfo.Token
|
||
otherinfo.Updatetime = groupinfo.Updatetime
|
||
err = sql.db.Insert("groupinfo", &otherinfo)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 记录次数(-sub)
|
||
func (sql *keydb) update(gid int64, sub int) error {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
// 给db文件创建表格(没有才创建),表格名称groupinfo,表格结构apikey
|
||
err := sql.db.Create("groupinfo", &apikey{})
|
||
if err != nil {
|
||
return err
|
||
}
|
||
groupinfo := apikey{} // 用于暂存数据
|
||
// 获取group信息
|
||
err = sql.db.Find("groupinfo", &groupinfo, "WHERE ID = ?", gid)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
groupinfo.MaxLimit -= sub
|
||
groupinfo.DayLimit -= sub
|
||
err = sql.db.Insert("groupinfo", &groupinfo)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 更新相同key的他人次数
|
||
otherinfo := apikey{}
|
||
var groups []int64 // 将相同的key的ID暂存
|
||
// 无视没有找到相同的key的err
|
||
_ = sql.db.FindFor("groupinfo", &otherinfo, "WHERE ID <> ? AND APIKey = ? AND SecretKey = ?", func() error {
|
||
groups = append(groups, otherinfo.ID)
|
||
return nil
|
||
}, gid, groupinfo.APIKey, groupinfo.SecretKey)
|
||
if len(groups) != 0 { // 如果有相同的key就更新
|
||
for _, group := range groups {
|
||
err = sql.db.Find("groupinfo", &otherinfo, "WHERE ID = ?", group)
|
||
if err == nil {
|
||
otherinfo.MaxLimit = groupinfo.MaxLimit
|
||
otherinfo.DayLimit = groupinfo.DayLimit
|
||
otherinfo.Lasttime = groupinfo.Lasttime
|
||
err = sql.db.Insert("groupinfo", &otherinfo)
|
||
}
|
||
}
|
||
}
|
||
return err
|
||
}
|