Spring boot+Simbot3.0簡(jiǎn)單使用
前言
Simbot3.0與Mirai皆為開(kāi)源框架,為了更好的學(xué)習(xí)與開(kāi)發(fā)在此記錄。
ForteScarlet/simpler-robot: Simple Robot是一個(gè)通用bot開(kāi)發(fā)框架,以同一種靈活的標(biāo)準(zhǔn)來(lái)編寫不同平臺(tái)的bot應(yīng)用。simpler-robot是用于區(qū)別于舊版本倉(cāng)庫(kù) simple-robot 的新版本命名。 (github.com)
mamoe/mirai: 高效率 QQ 機(jī)器人支持庫(kù) (github.com)

監(jiān)聽(tīng)器
simbot做為一個(gè)bot框架,肯定是要能有發(fā)送消息與接收消息的能力。
首先先創(chuàng)建個(gè)類,名字隨意。
類創(chuàng)建出來(lái)了,那么對(duì)springboot來(lái)說(shuō),它并不清楚這個(gè)類是干什么的,那么我們就給他加上@Controller注解,這個(gè)時(shí)候表示這個(gè)類是個(gè)控制器,同時(shí)將這個(gè)類加入到了spring容器中。因?yàn)槲覀冊(cè)趕pringboot里集成了simbot,而simbot又集成了mirai,所以這個(gè)時(shí)候simbot就可以在spring的容器內(nèi)找到我們剛才創(chuàng)建的這個(gè)類。
既然找到了這個(gè)類了,那么就我們就簡(jiǎn)單寫一個(gè)監(jiān)聽(tīng)器。
在這里為了方便進(jìn)行直觀的看到反饋,加入了@Slf4j注解。
此時(shí),我們寫了兩個(gè)監(jiān)聽(tīng)器
onEvent(GroupMessageEvent event)
onEvent(FriendMessageEvent event)
可以很明顯的看出來(lái)這兩個(gè)方法被重載了,它們的參數(shù)不同。
GroupMessageEvent 類型叫做群消息事件,參數(shù)里寫有這個(gè)的時(shí)候,那么就表示該監(jiān)聽(tīng)器監(jiān)聽(tīng)所有群消息。
FriendMessageEvent 類型叫做好友消息事件,同上
這個(gè)時(shí)候我們還是沒(méi)有寫完,雖然有方法了,而且simbot也可以找到這個(gè)類了,但是simbot不知道這倆方法到底是不是給它用的,所以我們還需要讓這兩個(gè)監(jiān)聽(tīng)器表示為simbot的監(jiān)聽(tīng)器。
添加了@Listener注解,這個(gè)注解就表示這個(gè)方法為simbot的監(jiān)聽(tīng)器,這個(gè)時(shí)候simbot會(huì)去去檢查參數(shù)事件,當(dāng)觸發(fā)了之后,就會(huì)執(zhí)行該事件方法。其他的注解注釋上已經(jīng)寫的很明顯了,在這里就不解釋了。
到了這里,我們就寫出來(lái)了兩個(gè)簡(jiǎn)單的監(jiān)聽(tīng)器。
這個(gè)時(shí)候我們可以啟動(dòng)一下項(xiàng)目來(lái)觀看一下效果。


效果都已經(jīng)實(shí)現(xiàn)了。
持續(xù)會(huì)話
持續(xù)會(huì)話是一個(gè)比較有意思的功能,它可以在父事件方法中再創(chuàng)建一個(gè)子事件方法,在觸發(fā)子事件方法時(shí),父事件會(huì)被阻塞直到子事件釋放才會(huì)繼續(xù)向下執(zhí)行。
那么我們來(lái)簡(jiǎn)單的寫一個(gè)持續(xù)回話事件
要想使用持續(xù)會(huì)話功能,則需要在監(jiān)聽(tīng)事件的參數(shù)上加上ContinuousSessionContext參數(shù),這樣的話就可以使用.waitingFor方法。
waitingFor(ID id,Key<E : Event> event,?BlockingClearTargetResumeListener<E, T> listener);
參數(shù)id可以理解為創(chuàng)建的子事件的唯一id,如果對(duì)代碼敏感的看到這個(gè)應(yīng)該就有點(diǎn)不妙的感覺(jué)了。
參數(shù)event是要監(jiān)聽(tīng)的事件類型,比如GroupMessageEvent
參數(shù)listener是一個(gè)接口,需要實(shí)現(xiàn)其中的invoke方法,表示子事件激活后執(zhí)行的方法
在這里,我們先啟動(dòng)項(xiàng)目測(cè)試一下效果。

在這里可以看出,我們第一次進(jìn)行了一次測(cè)試@Filter的正則過(guò)濾是否成功。
第二次我們進(jìn)行了可以讓正則匹配的消息,并且正式的進(jìn)入了持續(xù)回話事件方法中
因?yàn)槭堑谝淮芜M(jìn)入持續(xù)會(huì)話,所以sessionContext.getProvider(qqId)方法不可能獲得到對(duì)象,如果的第二次進(jìn)入持續(xù)會(huì)話,那么sessionContext.getProvider(qqId)方法會(huì)拿到對(duì)象,那么就不會(huì)繼續(xù)往下執(zhí)行創(chuàng)建出來(lái)一個(gè)子事件。
第三次可以看到程序確實(shí)如我們所想返回了"喝奶茶",緊接可能會(huì)執(zhí)行持續(xù)會(huì)話創(chuàng)建出一個(gè)子事件,然后阻塞當(dāng)前的父事件。
第四次可以看到為了測(cè)試是否已經(jīng)創(chuàng)建了子事件進(jìn)行了一次激活子事件動(dòng)作。
第五次可以看到我們的假設(shè)基本都成功了,成功的執(zhí)行了持續(xù)會(huì)話中我們所寫的方法。
第六次再次測(cè)試。
第七次成功回復(fù)
第八次測(cè)試持續(xù)回話的退出
第九次成功退出子事件,回復(fù)成功退出父事件。
因?yàn)樽邮录喈?dāng)于一個(gè)新的事件,所以如果在群聊的時(shí)候激活持續(xù)會(huì)話的話,會(huì)出現(xiàn)被其余群?jiǎn)T的信息所干擾的情況,為了避免出現(xiàn)這種情況 ,需要在子事件中進(jìn)行判斷是否是激活持續(xù)回話的本人。
關(guān)于退出,并不單單只有provider.push(String);才可以退出,不論是 push、 pushException 還是 cancel, 執(zhí)行后都視為完成。
持續(xù)會(huì)話是個(gè)很有用的功能,甚至我們可以將它封裝起來(lái),當(dāng)做一個(gè)阻塞器使用。