Python-Wechaty: 面向全部IM軟件的聊天機器人框架

Author: wj-Mcat
Code: python-wechatypython

我的開發項目,且行且不易,有感興趣的朋友能夠去給一波關注,大家的支持就是我最大的動力,謝謝你們。git

Python-wechaty可以使用少許代碼便可完成一個機器人,使用起來很是簡單,基於OOP的設計思路可以很好監聽和處理微信內部大量的事件,好比:自動回覆消息,定時發送消息,拉人入羣,好友申請贊成等等。此外,目前的插件系統裏面有不少拿來即用的工具,好比拉人入羣等。固然開發一個本身的插件也是很是簡單,無需很高深的概念,只須要你可以理解事件和OOP便可。github

python-wechaty項目源於wechaty,甚至說很大程度上代碼是直接從其翻譯過來的,而後加上一些python的特性,讓其更加pythonic。做爲一個IM的入口工具,將來咱們也將添加更多的Chatbot元素進去,讓其可以成爲一個真正的聊天機器人。數據庫

在介紹python-wechaty以前,仍是簡要介紹一下wechaty。編程

wechaty

或許有不少人會把wechatywechat聯繫起來,畢竟在名稱上面只是一字之差。這個得從wechaty的起源開始提及,起初,此項目只是做爲微信的一個工具庫,可以進行一些簡單的自動化操做過程,好比:定時發送消息,入羣消息發送,好友申請接受等。微信

可隨着項目的逐步更新,wechaty已支持主流的IM軟件,好比:微信,釘釘,Telegram。架構

這個項目從2016年開始,到如今已經獲取8k star,是一個很是穩定且用戶量很是龐大的項目。官方對其給出的介紹是:async

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,特別是使用了一個插件系統以後,以下所示:

以上代碼中實現了兩個主要的功能:

  • 當Bot接受到一個#ding信號,就立馬回覆一個dong消息,這就是一個基本的ding-dong-bot
  • 當接受到查閱天氣的文本語句時,則返回對應的天氣查詢結果,好比:今每天氣如何?

以上兩個插件是系統內置的,後續也會增長更多的拿來即用的實用插件,固然用戶也可建立本身的插件,方式很簡單。

如何開發插件系統

在瞭解如何開發插件系統以前,可先移駕Plug-in`,插件系統支持對插件的安裝,卸載,自定義配置等內容 ,至於具體的實現形式我相信也是須要面對具體的應用場景。而在Wechaty這個面相事件型且交互邏輯很是簡單的場景下,插件的設計與開發就很是簡單。

咱們如今直接來看看,系統內置的叮咚插件是如何實現的。

"""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的方式,用戶可繼承WechatyWechatyPlugin來監聽不一樣的事件,且在常規的代碼編輯器裏面重寫函數時就能夠自動填充函數參數,從而減小查閱事件函數參數的問題。

監聽事件的類型有:error, friendship, heartbeat, login, logout, message, ready, room_invite, room_join, room_leave, room_topic, scan

在上面已經展現了WechatyPlugin如何開發,須要注意的地方,那接下來我將給你們詳細介紹一下最基礎的每日一說的機器人如何開發。

每日一說機器人

每日一說,顧名思義天天每一個固定時間段發送一個祝福或提醒,具體內容可自定義。這其中須要注意幾點:

  • 機器人內部有一個調度器,用於調度時間事件的觸發。
  • 機器人可給制定的人和羣發送對應的內容。

以上的功能我封裝成一個插件,而後注入到python-wechaty中便可。

"""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中便可跑起來。

async def main():
    bot = Wechaty().use(DailyPlugin())
    await bot.start()
asyncio.run(main())

是否是超級簡單,插件系統幫你隔離全部的業務場景,讓代碼很是易於開發和維護。

python-wechaty還能夠作更多

如今python-wechaty只完成了基本的Chatbot入口工具,離真正的聊天機器人還距離很遠,因此將來還有不少工做量能夠作,也歡迎更多的研究chatbot,nlp的小夥伴聯繫我,共同開發讓你們都喜歡用的開源軟件。

微信號:pure-_--love

相關文章
相關標籤/搜索