上一篇完成了項(xiàng)目搭建,并實(shí)現(xiàn)了私聊機(jī)器人復(fù)讀機(jī)的功能。
本文主要實(shí)現(xiàn)一些群聊的功能:
- 當(dāng)群聊有人@機(jī)器人的時(shí)候,解析@消息的內(nèi)容踊谋,并通過(guò)聊天機(jī)器人接口獲取聊天應(yīng)答的內(nèi)容進(jìn)行應(yīng)答。
- 添加一個(gè)定時(shí)任務(wù)旋讹,在每天7點(diǎn)及23點(diǎn)發(fā)送早安和晚安褪子。
- 一些特定指令的解析。
技術(shù)方案
- 聊天機(jī)器人這里使用青云客免費(fèi)機(jī)器人接口骗村,無(wú)需注冊(cè)申請(qǐng)嫌褪,簡(jiǎn)單粗暴
- 定時(shí)功能則使用一個(gè)開(kāi)源庫(kù)cron
- 部分指令解析等則使用一般正則
功能開(kāi)發(fā)
聊天功能
-
判斷消息是否有@自己,at消息的格式==[CQ:at,qq=對(duì)方QQ]==胚股,這里簡(jiǎn)單正則判斷即可
//是否@自己 func hasAtSelf(msg string) bool { reg := regexp.MustCompile(`\[CQ:at,qq=(\d+)\]`) match := reg.FindStringSubmatch(msg) for _, v := range match { if strconv.FormatInt(cqp.GetLoginQQ(), 10) == v { return true } } return false }
-
從機(jī)器人接口獲取應(yīng)答內(nèi)容并進(jìn)行回復(fù)
//機(jī)器人智能回復(fù) func robotAnswer(fromGroup, fromQQ int64, msg string) { //get請(qǐng)求 //http.Get的參數(shù)必須是帶http://協(xié)議頭的完整url,不然請(qǐng)求結(jié)果為空 cqp.AddLog(cqp.Debug, "robotAnswer-msg", msg) resp, _ := http.Get(RobotUrl + msg) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) cqp.AddLog(cqp.Debug, "robotAnswer-body", string(body)) var robotMsg RobotMsg var jsonIterator = jsoniter.ConfigCompatibleWithStandardLibrary if err := jsonIterator.Unmarshal(body, &robotMsg); err == nil { cqp.SendGroupMsg(fromGroup, util.CQCode("at", "qq", fromQQ)+util.Escape(robotMsg.Content)) } else { cqp.AddLog(cqp.Debug, "robotAnswer-answer", err.Error()) } }
其他消息處理
-
普通指令笼痛。如菜單、幫助這種單一詞匯琅拌,只需要簡(jiǎn)單判斷消息內(nèi)容即可缨伊。
if strings.Contains(msg, "幫助") { code = 1 cqp.SendGroupMsg(fromGroup, "幫助菜單:\n"+"巴拉巴拉~") }
-
組合指令。先判斷前綴进宝,然后截取后面的內(nèi)容刻坊。
//一個(gè)搜題功能,不知接口是否還能正常工作 if strings.HasPrefix(msg, "搜題 ") && len(strings.Split(msg, " ")) > 1 { split := strings.Split(msg, " ") cqp.AddLog(cqp.Debug, "搜題", split[1]) resp, _ := http.Post("https://ninja.yua.im/ninja/qa", "application/x-www-form-urlencoded", strings.NewReader("search="+split[1])) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) response := string(body) msg := "搜題出錯(cuò),請(qǐng)稍后再試~" var exam Exam if err := json.Unmarshal([]byte(response), &exam); err == nil { if exam.IsSuc && exam.Data.Total > 0 { all := make([]string, exam.Data.Total+1) all[0] = "小改改為你找到以下結(jié)果:" for index, v := range exam.Data.Rows { title := strconv.Itoa(index+1) + ". " + v.Title s1 := make([]string, len(v.Answers)+1) s1[0] = title for k, v := range v.Answers { if v.IsCorrect { //正確 s1[k+1] = v.Content + " √" } else { s1[k+1] = v.Content } } //一條題目及回答 all[index+1] = strings.Join(s1, "\n") } msg = strings.TrimSpace(strings.Join(all, "\n")) } else { msg = "沒(méi)有找到你要的題目哦~" } } cqp.SendGroupMsg(fromGroup, msg)
定時(shí)功能
這個(gè)比較簡(jiǎn)單,具體用法可參戰(zhàn)相關(guān)文檔党晋。
//定時(shí)任務(wù)
func initJob() {
//早晨播報(bào)
err = c.AddFunc("5 0 7 * * ?", func() {
cqp.SendGroupMsg(816440954, "早上好,今天也是充滿(mǎn)希望的一天(●'?'●)?")
})
//晚上播報(bào)
err = c.AddFunc("5 0 23 * * ?", func() {
cqp.SendGroupMsg(816440954, "【碎覺(jué)碎覺(jué)】")
})
if err != nil {
cqp.AddLog(cqp.Debug, "job", err.Error())
return
}
c.Start()
}
測(cè)試截圖
群聊截圖谭胚。這里某個(gè)接口可能失效了,實(shí)現(xiàn)方式可供參考未玻。