Skip to content

Commit c8c3cc5

Browse files
committed
✨ 添加AI声聊
1 parent 4e7c0b8 commit c8c3cc5

File tree

3 files changed

+126
-2
lines changed

3 files changed

+126
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w]
282282
<details>
283283
<summary>群应用:AI声聊</summary>
284284

285-
`import _ "github.com/FloatTech/zbputils/airecord"`
285+
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/airecord"`
286286

287287
- [x] 设置AI语音群号1048452984(tips:机器人任意所在群聊即可)
288288

plugin/aichat/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func init() {
144144
logrus.Infoln("[aichat] 回复内容:", t)
145145
recCfg := airecord.GetRecordConfig()
146146
if !cfg.NoRecord {
147-
record := ctx.GetAIRecord(recCfg.ModelID, recCfg.Customgid, t).String()
147+
record := ctx.GetAIRecord(recCfg.ModelID, recCfg.Customgid, t)
148148
if record != "" {
149149
ctx.SendChain(message.Record(record))
150150
} else {

plugin/airecord/record.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Package airecord 群应用:AI声聊
2+
package airecord
3+
4+
import (
5+
"strconv"
6+
"strings"
7+
"time"
8+
9+
"github.com/tidwall/gjson"
10+
11+
zero "github.com/wdvxdr1123/ZeroBot"
12+
"github.com/wdvxdr1123/ZeroBot/message"
13+
14+
ctrl "github.com/FloatTech/zbpctrl"
15+
"github.com/FloatTech/zbputils/airecord"
16+
"github.com/FloatTech/zbputils/control"
17+
)
18+
19+
func init() {
20+
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
21+
DisableOnDefault: false,
22+
Extra: control.ExtraFromString("airecord"),
23+
Brief: "群应用:AI声聊",
24+
Help: "- 设置AI语音群号1048452984(tips:机器人任意所在群聊即可)\n" +
25+
"- 设置AI语音模型\n" +
26+
"- 查看AI语音配置\n" +
27+
"- 发送AI语音xxx",
28+
PrivateDataFolder: "airecord",
29+
})
30+
31+
en.OnPrefix("设置AI语音群号", zero.SuperUserPermission).SetBlock(true).
32+
Handle(func(ctx *zero.Ctx) {
33+
u := strings.TrimSpace(ctx.State["args"].(string))
34+
num, err := strconv.ParseInt(u, 10, 64)
35+
if err != nil {
36+
ctx.SendChain(message.Text("ERROR: parse gid err: ", err))
37+
return
38+
}
39+
airecord.SetCustomGID(num)
40+
ctx.SendChain(message.Text("设置AI语音群号为", num))
41+
})
42+
en.OnFullMatch("设置AI语音模型", zero.SuperUserPermission).SetBlock(true).
43+
Handle(func(ctx *zero.Ctx) {
44+
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession())
45+
recv, cancel := next.Repeat()
46+
defer cancel()
47+
jsonData := ctx.GetAICharacters(0, 1)
48+
49+
// 转换为字符串数组
50+
var names []string
51+
// 初始化两个映射表
52+
nameToID := make(map[string]string)
53+
nameToURL := make(map[string]string)
54+
characters := jsonData.Get("#.characters")
55+
56+
// 遍历每个角色对象
57+
characters.ForEach(func(_, group gjson.Result) bool {
58+
group.ForEach(func(_, character gjson.Result) bool {
59+
// 提取当前角色的三个字段
60+
name := character.Get("character_name").String()
61+
names = append(names, name)
62+
// 存入映射表(重复名称会覆盖,保留最后出现的条目)
63+
nameToID[name] = character.Get("character_id").String()
64+
nameToURL[name] = character.Get("preview_url").String()
65+
return true // 继续遍历
66+
})
67+
return true // 继续遍历
68+
})
69+
var builder strings.Builder
70+
// 写入开头文本
71+
builder.WriteString("请选择语音模型序号:\n")
72+
73+
// 遍历names数组,拼接序号和名称
74+
for i, v := range names {
75+
// 将数字转换为字符串(不依赖fmt)
76+
numStr := strconv.Itoa(i)
77+
// 拼接格式:"序号. 名称\n"
78+
builder.WriteString(numStr)
79+
builder.WriteString(". ")
80+
builder.WriteString(v)
81+
builder.WriteString("\n")
82+
}
83+
// 获取最终字符串
84+
ctx.SendChain(message.Text(builder.String()))
85+
for {
86+
select {
87+
case <-time.After(time.Second * 120):
88+
ctx.SendChain(message.Text("设置AI语音模型指令过期"))
89+
return
90+
case ct := <-recv:
91+
msg := ct.Event.Message.ExtractPlainText()
92+
num, err := strconv.Atoi(msg)
93+
if err != nil {
94+
ctx.SendChain(message.Text("请输入数字!"))
95+
continue
96+
}
97+
if num < 0 || num >= len(names) {
98+
ctx.SendChain(message.Text("序号非法!"))
99+
continue
100+
}
101+
airecord.SetRecordModel(names[num], nameToID[names[num]])
102+
ctx.SendChain(message.Text("已选择语音模型: ", names[num]))
103+
ctx.SendChain(message.Record(nameToURL[names[num]]))
104+
return
105+
}
106+
}
107+
})
108+
en.OnFullMatch("查看AI语音配置").SetBlock(true).
109+
Handle(func(ctx *zero.Ctx) {
110+
recCfg := airecord.GetRecordConfig()
111+
ctx.SendChain(message.Text(airecord.PrintRecordConfig(recCfg)))
112+
})
113+
en.OnPrefix("发送AI语音").SetBlock(true).
114+
Handle(func(ctx *zero.Ctx) {
115+
u := strings.TrimSpace(ctx.State["args"].(string))
116+
recCfg := airecord.GetRecordConfig()
117+
record := ctx.GetAIRecord(recCfg.ModelID, recCfg.Customgid, u)
118+
if record == "" {
119+
ctx.SendChain(message.Text("ERROR: get record err: empty record"))
120+
return
121+
}
122+
ctx.SendChain(message.Record(record))
123+
})
124+
}

0 commit comments

Comments
 (0)