也許很多人會把wechaty和wechat聯系起來,畢竟名字上只有一個字的區別。這必須從wechaty的起源開始。起初,該項目只是微信的一個工具庫,可以進行一些簡單的自動化操作流程,如定期發送消息、群發消息、朋友申請接受等。
但隨著項目的逐步更新,wechaty已經支持微信、釘釘等主流IM軟件Telegram。
自2016年以來,該項目已獲得8kstar。這是一個非常穩定和龐大的用戶項目。官方介紹如下:
AConversationalAIRPASDKforChatbot
因此,作為IMChatbot的入口工具,wechaty是許多聊天機器人的基本結構組件,并將逐步支持主流聊天機器人的功能。
在2019年底的一次技術沙龍會議上,我意識到原來的六行代碼可以開發出一個足夠靈活的機器人,這給了我很大的震驚。微信作為我們的日常聊天工具之一,如果我們能做一些自動化過程,可以大大減少繁瑣過程的工作量,如:拉人進入小組,定期提醒用戶打卡,提醒女朋友阿姨來等等。而且wechaty能很好地支持上述所有功能,只需幾行簡單的代碼即可完成。回去后,立即開始查閱相關資料,然后逐步進入wechaty社區。
一個巧合的機會小組說可以開發一個go-wechaty。當時我在想為什么不能有python-wechaty,然后自我推薦,成為python-wechaty的聯合作者之一。由于對開源軟件和Devops不太熟悉,在起步階段遇到了很多問題,但在社區老板的耐心指導下,issue和feature的開發和管理已經能夠完成。親身經歷,建議你有機會參加開源項目,讓你學到很多知識點。
使用python-wechaty可以簡單地開發Bot,特別是在使用插件系統后,如下所示:
上述代碼實現了兩個主要功能:當Bot接收到#ding信號時,立即回復dong信息,這是一個基本的ding-dong-bot。當接收到查閱天氣的文本語句時,返回相應的天氣查詢結果,如:今天的天氣如何?
以上兩個插件都是系統內置的,以后會增加更實用的即時插件。當然,用戶也可以創建自己的插件,方法非常簡單。
在知道如何開發插件系統之前,可以先移動Plug-in`,插件系統支持插件的安裝、卸載、自定義配置等內容。至于具體的實現形式,我相信我們也需要面對具體的應用場景。在面部事件和交互邏輯非常簡單的場景中,插件的設計和開發非常簡單。
現在讓我們來看看如何實現系統內置的丁咚插件。
“””basicding-dongbotforthewechatyplugin”””
fromtypingimportUnion
fromwechatyimportMessage,Contact,Room,FileBox
fromwechaty.pluginimportWechatyPlugin
classDingDongPlugin(WechatyPlugin):
“””basicding-dongplugin”””
@property
defname(self):
“””nameoftheplugin”””
return’ding-dong’
asyncdefon_message(self,msg:Message):
“””listenmessageevent”””
from_contact=msg.talker()
text=msg.text()
room=msg.room()
iftext==’#ding’:
conversation:Union[
Room,Contact]=from_contactifroomisNoneelseroom
awaitconversation.ready()
awaitconversation.say(‘dong’)
代碼很簡單,但也需要介紹幾個層次的氛圍。WechatyPluginon_[event_name]init_plugin
這類是抽象類,所有插件都必須繼承這個基類,并重寫函數。name屬性函數為抽象函數,必須重寫。主要是為了識別插件的名稱,作為插件的唯一身份認證。init_plugin初始化函數可以支持插件的初始化過程,如初始化定時器對象、數據庫延遲連接對象等。on_[event_name]該函數主要用于監控系統中的不同事件,如:on_message,on_login,on_friendship等事件的監控只需重寫函數即可完成。不同的插件和不同的事件是獨立的,可以很好地關注不同業務場景的發展。
python-wechaty在很大程度上是由事件驅動的。畢竟很多操作都是基于新聞接收觸發的。因此,事件監控是其基本特征。也許第一感覺是實用的eventemiter模式來監控事件,這樣我就可以注冊不同的函數來監控每個事件,每個函數都會有不同的邏輯處理。這也是一種傳統的事件監控方法,但至少會給開發帶來一些不便:函數參數需要參考文檔才能知道,標準函數編程。
我不是說函數編程不好,但是在這種情況下系統性能提升不了多少,python-wechaty也不能太注重性能。
這擴展了OOP的方式,用戶可以繼承Wechaty或WechatyPlugin來監控不同的事件,并在傳統的代碼編輯器中重寫函數時自動填寫函數參數,從而減少訪問事件函數參數的問題。
監控事件的類型有:error,friendship,heartbeat,login,logout,message,ready,room_invite,room_join,room_leave,room_topic,scan。
上面已經展示了如何開發WechatyPlugin,需要注意。接下來,我將詳細介紹如何開發最基本的日常機器人。
顧名思義,每天在每個固定時間段發送祝福或提醒,具體內容可以自定義。需要注意的是,機器人內部有一個調度器,用于觸發調度時間事件。機器人可以將相應的內容發送給制定的人和組。
我將上述功能封裝成插件,然后注入python-wechaty。
“””dailywordplugin”””
fromdatetimeimportdatetime
fromapscheduler.schedulers.asyncioimportAsyncIOScheduler
fromwechatyimportWechaty
fromwechaty.pluginimportWechatyPlugin
classDailyPlugin(WechatyPlugin):
saysomethingeveryday,like`DailyWords`
@property
defname(self)->str:
“””getthenameoftheplugin”””
return’dayily’
asyncdeftick(self):
“””timetickforthepluginscheduler”””
room_id=get_room_id()
room=self.bot.Room.load(room_id)
awaitroom.ready()
awaitroom.say(f’iloveyou->{datetime.now()}’)
asyncdefinit_plugin(self,wechaty:Wechaty):
“””initplugin”””
awaitsuper().init_plugin(wechaty)
scheduler=AsyncIOScheduler()
scheduler.add_job(self.tick,’cron’,hour=6,minute=16)
scheduler.start()
插件開發完畢,然后注入Wechaty就可以跑了。
asyncdefmain():
bot=Wechaty().use(DailyPlugin())
awaitbot.start()
asyncio.run(main())
是不是超級簡單?插件系統幫助您隔離所有業務場景,使代碼非常容易開發和維護。
現在python-wechaty只完成了基本的chatbot入口工具,離真正的聊天機器人還有很長的路要走,所以未來還有很多工作要做。也歡迎更多研究chatbot和nlp的朋友聯系我,共同開發大家都喜歡使用的開源軟件。