1. 程式人生 > >Python-Wechaty: 面向所有IM軟體的聊天機器人框架

Python-Wechaty: 面向所有IM軟體的聊天機器人框架

> Author: [wj-Mcat](https://github.com/wj-Mcat) > Code: [python-wechaty](https://github.com/wechaty/python-wechaty) 個人開發專案,且行且不易,有感興趣的朋友可以去給一波關注,你們的支援就是我最大的動力,謝謝大家。 Python-wechaty能夠使用少量程式碼即可完成一個機器人,使用起來非常簡單,基於OOP的設計思路能夠很好監聽和處理微信內部大量的事件,比如:自動回覆訊息,定時傳送訊息,拉人入群,好友申請同意等等。此外,目前的外掛系統裡面有很多拿來即用的工具,比如拉人入群等。當然開發一個自己的外掛也是非常簡單,無需很高深的概念,只需要你能夠理解事件和OOP即可。 python-wechaty專案源於wechaty,甚至說很大程度上程式碼是直接從其翻譯過來的,然後加上一些python的特性,讓其更加pythonic。作為一個IM的入口工具,未來我們也將新增更多的Chatbot元素進去,讓其能夠成為一個真正的聊天機器人。 在介紹python-wechaty之前,還是簡要介紹一下wechaty。 ## wechaty 或許有很多人會把`wechaty`和`wechat`聯絡起來,畢竟在名稱上面只是一字之差。這個得從`wechaty`的起源開始說起,起初,此專案只是作為微信的一個工具庫,能夠進行一些簡單的自動化操作過程,比如:定時傳送訊息,入群訊息傳送,好友申請接受等。 可隨著專案的逐步更新,`wechaty`已支援主流的IM軟體,比如:微信,釘釘,Telegram。 這個[專案](https://github.com/wechaty/wechaty)從2016年開始,到現在已經獲取8k star,是一個非常穩定且使用者量非常龐大的專案。官方對其給出的介紹是: > A Conversational AI RPA SDK for Chatbot 所以wechaty作為IM ChatBot的入口工具,是很多聊天機器人的基礎架構元件,也將會逐步支援主流聊天機器人的功能。 ## python-wchaty的誕生 與Wechaty的結緣是在2019年底的一次技術沙龍會上,認識到了原來6行程式碼就能夠開發出一款足夠靈活的機器人,當時給我一個很大的震撼。微信作為我們日常聊天工具之一,如果能夠對其做一些自動化的過程,能夠很大程度上減少繁瑣過程的工作量,比如說:辦活動時的拉人入群,定時提醒使用者打卡,提醒女朋友姨媽快來了等等。而wechaty能夠很好的支援以上所有功能,只需要簡單的幾行程式碼即可完成。回去之後就立馬著手相關資料的查閱,然後逐步進入wechaty的社群。 一個很巧的機會群裡面說可以開發一款go-wechaty的開發,當時我就在想,為什麼不能夠有一款python-wechaty呢,然後就毛遂自薦,成為了python-wechaty的聯合作者之一。由於對開源軟體和DevOps不是很熟悉,起步階段遇到了很多的問題,不過經過社群大佬的耐心指導,目前已能夠完成對issue和feature的開發和管理。親身經歷,建議大家有機會一定要參加開源專案,能夠讓你學習到很多知識點。 ## 最簡單的Bot 使用python-wechaty能夠很簡單的開發一款Bot,特別是使用了一個外掛系統之後,如下所示: ![](https://img2020.cnblogs.com/blog/698295/202012/698295-20201209102848284-437364661.png) 以上程式碼中實現了兩個主要的功能: - 當Bot接受到一個`#ding`訊號,就立馬回覆一個`dong`訊息,這就是一個基本的`ding-dong-bot`。 - 當接受到查閱天氣的文字語句時,則返回對應的天氣查詢結果,比如:今天天氣如何? 以上兩個外掛是系統內建的,後續也會增加更多的拿來即用的實用外掛,當然使用者也可建立自己的外掛,方式很簡單。 ## 如何開發外掛系統 在瞭解如何開發外掛系統之前,可先移駕[Plug-in`](https://en.wikipedia.org/wiki/Plug-in_%28computing%29),外掛系統支援對外掛的安裝,解除安裝,自定義配置等內容 ,至於具體的實現形式我相信也是需要面對具體的應用場景。而在Wechaty這個面相事件型且互動邏輯非常簡單的場景下,外掛的設計與開發就非常簡單。 我們現在直接來看看,系統內建的叮咚外掛是如何實現的。 ```python """basic ding-dong bot for the wechaty plugin""" from typing import Union from wechaty import Message, Contact, Room, FileBox from wechaty.plugin import WechatyPlugin class DingDongPlugin(WechatyPlugin): """basic ding-dong plugin""" @property def name(self): """name of the plugin""" return 'ding-dong' async def on_message(self, msg: Message): """listen message event""" from_contact = msg.talker() text = msg.text() room = msg.room() if text == '#ding': conversation: Union[ Room, Contact] = from_contact if room is None else room await conversation.ready() await conversation.say('dong') ``` 程式碼很簡單,不過也是需要氛圍一下幾個層面來介紹。 - WechatyPlugin - on_[event_name] - init_plugin ### WechatyPlugin 此類為一個抽象類,所有的外掛必須要繼承此基類,並重寫其中的函式。 - name 屬性函式 為抽象函式,必須重寫。主要是為了標識外掛的名稱,作為外掛唯一性身份認證。 - init_plugin 初始化函式 能夠支援外掛的初始化過程,比如初始化定時器物件,資料庫延遲連線物件等。 - on_[event_name] 此類函式主要是為了監聽系統中的不同事件,比如:`on_message`, `on_login`, `on_friendship`等事件的監聽都只需要重寫一下函式即可完成。不同外掛之間以及不同事件之間都是獨立的,能夠很好的專注於不同業務場景下的開發。 ### event_name `python-wechaty`很大程度上是由事件驅動,畢竟很多操作都是基於**訊息接受**觸發,由此事件的監聽是其基礎特性,可能第一感覺就是實用`EventEmitter`這種模式來監聽事件,這樣每個事件我都可以註冊不同的函式來監聽,每個函式中會有不同的邏輯處理。這也是傳統的事件監聽方法,可這至少會給開發上帶來一些不方便:函式的引數需要查閱文件才能夠獲知,標準的函數語言程式設計。 > 我不是說函數語言程式設計不好,只是在這種場景下對系統性能並不能提升多少,且`python-wechaty` 也並不能太注重效能。 由此將其擴充套件了OOP的方式,使用者可繼承`Wechaty`或`WechatyPlugin`來監聽不同的事件,且在常規的程式碼編輯器裡面重寫函式時就可以自動填充函式引數,從而減少查閱事件函式引數的問題。 監聽事件的型別有:`error`, `friendship`, `heartbeat`, `login`, `logout`, `message`, `ready`, `room_invite`, `room_join`, `room_leave`, `room_topic`, `scan`。 在上面已經展示了WechatyPlugin如何開發,需要注意的地方,那接下來我將給大家詳細介紹一下最基礎的`每日一說`的機器人如何開發。 ## 每日一說機器人 每日一說,顧名思義每天每個固定時間段傳送一個祝福或提醒,具體內容可自定義。這其中需要注意幾點: - 機器人內部有一個排程器,用於排程時間事件的觸發。 - 機器人可給制定的人和群傳送對應的內容。 以上的功能我封裝成一個外掛,然後注入到`python-wechaty`中即可。 ```python """daily word plugin""" from datetime import datetime from apscheduler.schedulers.asyncio import AsyncIOScheduler from wechaty import Wechaty from wechaty.plugin import WechatyPlugin class DailyPlugin(WechatyPlugin): """ say something everyday, like `Daily Words` """ @property def name(self) -> str: """get the name of the plugin""" return 'dayily' async def tick(self): """time tick for the plugin scheduler""" room_id = get_room_id() room = self.bot.Room.load(room_id) await room.ready() await room.say(f'i love you -> {datetime.now()}') async def init_plugin(self, wechaty: Wechaty): """init plugin""" await super().init_plugin(wechaty) scheduler = AsyncIOScheduler() scheduler.add_job(self.tick, 'cron', hour=6, minute=16) scheduler.start() ``` 外掛就開發完了,然後將其注入到Wechaty中即可跑起來。 ```python async def main(): bot = Wechaty().use(DailyPlugin()) await bot.start() asyncio.run(main()) ``` 是不是超級簡單,外掛系統幫你隔離所有的業務場景,讓程式碼非常易於開發和維護。 ## python-wechaty還可以做更多 現在python-wechaty只完成了基本的Chatbot入口工具,離真正的聊天機器人還距離很遠,所以未來還有很多工作量可以做,也歡迎更多的研究chatbot,nlp的小夥伴聯絡我,共同開發讓大家都喜歡用的開源軟體。 微訊號:`pure-_--love`