// Package aireply AI 回复 package aireply import ( "os" "regexp" "strconv" "strings" "time" "github.com/FloatTech/AnimeAPI/tts/genshin" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" "github.com/sirupsen/logrus" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) var replmd = replymode([]string{"婧枫", "沫沫", "青云客", "小爱", "ChatGPT"}) var ttsmd = newttsmode() func init() { // 插件主体 ent := control.Register("tts", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: true, Brief: "人工智能语音回复", Help: "- @Bot 任意文本(任意一句话回复)\n" + "- 设置语音模式[原神人物/百度/TTSCN/桑帛云] 数字(百度/TTSCN说话人/桑帛云)\n" + "- 设置默认语音模式[原神人物/百度/TTSCN/桑帛云] 数字(百度/TTSCN说话人/桑帛云)\n" + "- 恢复成默认语音模式\n" + "- 设置语音回复模式[沫沫|婧枫|青云客|小爱|ChatGPT]\n" + "- 设置原神语音 api key xxxxxx (key请加开发群获得)\n" + "- 设置百度语音 api id xxxxxx secret xxxxxx (请自行获得)\n" + "当前适用的原神人物含有以下: \n" + list(genshin.SoundList[:], 5) + "\n当前适用的TTSCN人物含有以下(以数字顺序代表): \n" + list(ttscnspeakers[:], 5), PrivateDataFolder: "tts", }) enr := control.Register("aireply", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, Brief: "人工智能回复", Help: "- @Bot 任意文本(任意一句话回复)\n- 设置文字回复模式[婧枫|沫沫|青云客|小爱|ChatGPT]\n- 设置 ChatGPT api key xxx", PrivateDataFolder: "aireply", }) enr.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { aireply := replmd.getReplyMode(ctx) reply := message.ParseMessageFromString(aireply.Talk(ctx.Event.UserID, ctx.ExtractPlainText(), zero.BotConfig.NickName[0])) // 回复 time.Sleep(time.Second * 1) reply = append(reply, message.Reply(ctx.Event.MessageID)) ctx.Send(reply) }) setReplyMode := func(ctx *zero.Ctx) { param := ctx.State["args"].(string) err := replmd.setReplyMode(ctx, param) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) return } ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功")) } enr.OnPrefix("设置文字回复模式", zero.AdminPermission).SetBlock(true).Handle(setReplyMode) enr.OnRegex(`^设置\s*ChatGPT\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { err := ཆཏ.set(ctx.State["regex_matched"].([]string)[1]) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } ctx.SendChain(message.Text("设置成功")) }) endpre := regexp.MustCompile(`\pP$`) ttscachedir := ent.DataFolder() + "cache/" _ = os.RemoveAll(ttscachedir) err := os.MkdirAll(ttscachedir, 0755) if err != nil { panic(err) } ent.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { msg := ctx.ExtractPlainText() // 获取回复模式 r := replmd.getReplyMode(ctx) // 获取回复的文本 reply := message.ParseMessageFromString(r.TalkPlain(ctx.Event.UserID, msg, zero.BotConfig.NickName[0])) // 过滤掉文字消息 filterMsg := make([]message.MessageSegment, 0, len(reply)) sb := strings.Builder{} for _, v := range reply { if v.Type != "text" { filterMsg = append(filterMsg, v) } else { sb.WriteString(v.Data["text"]) } } // 纯文本 plainReply := sb.String() plainReply = strings.ReplaceAll(plainReply, "\n", "") // 获取语音 speaker, err := ttsmd.getSoundMode(ctx) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } rec, err := speaker.Speak(ctx.Event.UserID, func() string { if !endpre.MatchString(plainReply) { return plainReply + "。" } return plainReply }) // 发送前面的图片 if len(filterMsg) != 0 { filterMsg = append(filterMsg, message.Reply(ctx.Event.MessageID)) ctx.Send(filterMsg) } if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(plainReply)) return } // 发送语音 if id := ctx.SendChain(message.Record(rec)); id.ID() == 0 { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(plainReply)) } }) ent.OnPrefix("设置语音回复模式", zero.AdminPermission).SetBlock(true).Handle(setReplyMode) ent.OnRegex(`^设置语音模式\s*([\S\D]*)\s+(\d*)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { param := ctx.State["regex_matched"].([]string)[1] num := ctx.State["regex_matched"].([]string)[2] n := 0 var err error if num != "" { n, err = strconv.Atoi(num) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } } // 保存设置 logrus.Debugln("[tts] t.setSoundMode( ctx", param, n, ")") err = ttsmd.setSoundMode(ctx, param, n) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) return } banner := genshin.TestRecord[param] if banner == "" { banner = genshin.TestRecord["默认"] } logrus.Debugln("[tts] banner:", banner, "get sound mode...") // 设置验证 speaker, err := ttsmd.getSoundMode(ctx) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } logrus.Debugln("[tts] got sound mode, speaking...") rec, err := speaker.Speak(ctx.Event.UserID, func() string { return banner }) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无法发送测试语音,请重试。")) return } logrus.Debugln("[tts] sending...") if id := ctx.SendChain(message.Record(rec).Add("cache", 0)); id.ID() == 0 { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无法发送测试语音,请重试。")) return } time.Sleep(time.Second * 2) ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", speaker)) }) ent.OnRegex(`^设置默认语音模式\s*([\S\D]*)\s+(\d*)$`, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { param := ctx.State["regex_matched"].([]string)[1] num := ctx.State["regex_matched"].([]string)[2] n := 0 var err error if num != "" { n, err = strconv.Atoi(num) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } } // 保存设置 err = ttsmd.setDefaultSoundMode(param, n) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) return } ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功")) }) ent.OnFullMatch("恢复成默认语音模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { err := ttsmd.resetSoundMode(ctx) if err != nil { ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err)) return } // 设置验证 speaker, err := ttsmd.getSoundMode(ctx) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", speaker)) }) ent.OnRegex(`^设置原神语音\s*api\s*key\s*([0-9a-zA-Z-_]{54}==)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { err := 原.set(ctx.State["regex_matched"].([]string)[1]) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } ctx.SendChain(message.Text("设置成功")) }) ent.OnRegex(`^设置百度语音\s*api\s*id\s*(.*)\s*secret\s*(.*)\s*$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { err := 百.set(ctx.State["regex_matched"].([]string)[1] + "," + ctx.State["regex_matched"].([]string)[2]) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return } ctx.SendChain(message.Text("设置成功")) }) }