使用Python Flask 開發微信機器人


緣由

由於我個人有個小博客,然后還錄制了一些課程,所有就建立了對應的微信群,但是微信群的二維碼是變化的,總不能經常換了。所以就想搞一個微信機器人,自動加 微信,自動拉群。廢話不多說,先上圖

效果展示

大家可以試試效果,效果相當棒


5.jpg


tiny.jpg


web_tiny.png

需求

  • 其他人可以通過二維碼加我好友 自動通過

  • 好友通過之后 主動發送一些邀請入群鏈接和介紹信

  • 回復 邀請 、加群 可以發送邀請入群鏈接

  • 所有聊天數據都要存儲起來 並且可以通過Web展示

  • 根據用戶輸入信息 回復相關內容

技術選型

  • Python3

  • Flask:輕量級的MVC 框架

  • itchat :實現微信API相關接口

  • MySQL:存儲相關微信內容

  • 圖靈機器人:調用API實現主動場景回復

架構

本人沒有使用flask 默認的MVC方式,使用了我自己實現過后的:結構分層明了的MVC框架 。結構如下

每一個文件夾都有自己明確的作用

├── application.py
├── common
│   ├── libs
│   └── models
├── config
│   ├── base_setting.py
│   ├── local_setting.py
│   ├── production_setting.py
├── controllers
│   ├── index.py
│   ├── member.py
├── interceptors
│   ├── Auth.py
│   ├── errorHandler.py
├── jobs
│   ├── launcher.py
│   ├── movie.py
│   └── tasks
├── manager.py
├── requirement.txt
├── static
│   ├── js
│   └── plugins
├── templates
│   ├── common
│   ├── index.html
│   ├── info.html
│   └── member
├── test
│   └── apsch_test.py
├── tornado_server.py
└── www.py


實現源碼

這里將主要實現源碼如下

# -*- coding: utf-8 -*-
from application import app,db
import itchat,signal,json,time,os,random
import multiprocessing
from ctypes import c_bool, c_int

from common.libs.tuling123.TuLingService import TuLingService
from common.libs.wxbot.WeChatBotService import WeChatBotService
from common.models.queue import QueueList
from common.libs.DateUtil import getCurrentTime
import traceback,requests



'''
python manage.py runjob -m wechatbot/index
'''
class JobTask():
    def __init__(self):
        pass

    def run(self, params):
        try:
            # 增加重試連接次數
            # requests使用了urllib3庫,默認的http connection是keep-alive的,requests設置False關閉。
            s = requests.session()
            s.keep_alive = False

            itchat.auto_login( enableCmdQR=2,hotReload=True )

            threads = []
            t_queue_consumer = multiprocessing.Process(target = syncConsumer, args=("t_queue_consumer",) )
            t_queue_consumer.daemon = True
            threads.append( t_queue_consumer )


            app.logger.info( 'Parent process {0} is Running'.format( os.getpid() ) )
            for i in range( len(threads) ):
                threads[i].start()


            #初始化所有的朋友,存入隊列,然后進程做事情
            queue_msg = {
                'type': 'friends',
                'data': itchat.get_friends( update=True )
            }
            global_queue.put(queue_msg)

            ##必須要把群聊保存到通訊錄才行,不會無法獲取到的
            #https://github.com/littlecodersh/ItChat/issues/480
            queue_msg = {
                'type': 'group',
                'data': itchat.get_chatrooms(update=True)
            }
            global_queue.put(queue_msg)


            itchat.run()
        except Exception as err:
            app.logger.error( "=========itchat:run error========" )
            traceback.print_exc()
            exit( 15 )



    @staticmethod
    def exit( signum, frame ):
        global sendmail_flag
        app.logger.info( "手動退出~~" )
        app.logger.info( "signum:%s,frame:%s,sendmail_flag:%s"%( signum,frame,sendmail_flag ) )
        if not sendmail_flag:
            sendmail_flag = True
            #itchat.logout()#執行這個退出之后下次就必須要在掃碼才能登陸
            from common.libs.queue.QueueListService import QueueListService
            notice_users = QueueListService.getNoticeUsers(ids=[app.config['NOTICE_WECHAT_USER']['family_host_man']])
            data = {
                "msg": "微信機器人 倒了,需要人為干預,修復好~~",
                "title": "【提醒】微信機器人 倒了",
                "notice_users": notice_users
            }
            QueueListService.addQueueMsg(queue_name="reminder", data=data, type=2)
        exit( 15 )


# http://itchat.readthedocs.io/zh/latest/
# 加入圖靈機器人:https://www.kancloud.cn/turing/web_api/522992
# 關於進程的文章:https://mozillazg.com/2017/07/python-how-to-generate-kill-clean-zombie-process.html
@itchat.msg_register(itchat.content.INCOME_MSG)
def handle_msg(msg):
    queue_msg = {
        'type':'msg',
        'data':msg
    }
    global_queue.put( queue_msg )

    if msg.Type == itchat.content.TEXT and msg.FromUserName != "newsapp":

        if msg.Type == itchat.content.TEXT and ( "邀請" in msg.Text or "加群" in msg.Text ) :
            # 同時發送加群邀請鏈接
            itchat.add_member_into_chatroom( get_group_id("編程浪子小天地"), [{'UserName':msg.FromUserName }],
                                            useInvitation=True )
            return None
        '''
        需要過濾掉幾種情況,例如自己發送的不要自己回復自己了
        '''
        tmp_msg = []
        tmp_msg.append( TuLingService.getRobotAnswer( msg.Text ) )
        tmp_msg.extend( getAd() )
        msg.user.send( "\n".join( tmp_msg  ) )

    elif msg.Type == itchat.content.FRIENDS:
        msg.user.verify()
        tmp_msg = [
            "歡迎進入編程浪子機器人世界~~",
            "你可以輸入想對我說的話,會有彩蛋",
            "個人博客:http://www.54php.cn",
            "回復 邀請 、 加群 關鍵字 可以加入群",
            "獲取慕課課程賬號,請關注公眾號"
        ]
        tmp_msg.extend( getAd( is_rand = False ) )
        msg.user.send( "\n".join( tmp_msg ) )
        itchat.send_image( app.root_path + "/web/static/images/wechat/coderonin.jpg" ,msg['RecommendInfo']['UserName'] )
        itchat.send_image( app.root_path + "/web/static/images/wechat/mina.jpg" ,msg['RecommendInfo']['UserName'] )
        #同時發送加群邀請鏈接
        itchat.add_member_into_chatroom( get_group_id("編程浪子小天地"), [{'UserName': msg['RecommendInfo']['UserName'] }], useInvitation=True)
    elif msg.Type in [ itchat.content.SYSTEM, itchat.content.NOTE ]:
        #note表示添加好友通過后的備注內容
        pass
    else:
        if msg.Type == "Sharing" and msg.Text == "邀請你加入群聊":
            return None

        tmp_msg = [  "我還是個孩子~~無法識別你的發的什么哦" ]
        tmp_msg.extend(getAd())
        msg.user.send( "\n".join( tmp_msg ) )
    return None


@itchat.msg_register(itchat.content.INCOME_MSG, isGroupChat=True)
def handle_group_msg(msg):
    app.logger.info("type:{0},text:{1}".format(msg.Type, msg.Text))
    app.logger.info(msg)
    return None

def getAd( is_rand = True ):
    ad_urls = [
        "http://t.cn/AiK3JhDK",
        "http://t.cn/AiK3JLD5",
        "http://t.cn/AiK3JqKX",
        "http://t.cn/AiK3JfqQ",
        "http://t.cn/AiK3JXWa",
        "http://t.cn/AiK3JNvY",
        "http://t.cn/AiKS9XZR",
        "http://t.cn/AiK3JQe3",
        "http://t.cn/AiK3JuJi",
        "http://t.cn/AiK3JeOC",
        "http://t.cn/AiK3ivyk",
        "http://t.cn/AiK3izxl",
        "http://t.cn/AiK3iLVH"
    ]

    tmp_msg = [
        "",
        "==================",
        "望大家多多支持,關注公眾號:CodeRonin",
        "支持浪子點擊文章最下面AD:" + ad_urls[ random.randint(1, len( ad_urls ) ) - 1 ]
    ]

    if is_rand and random.randint(1,10) < 8:
        tmp_msg = []

    return tmp_msg

# 獲得群聊id
def get_group_id(group_name):
    group_list = itchat.search_chatrooms(name=group_name)
    return group_list[0]['UserName']

#捕獲退出信號,例如control + c

signal.signal(signal.SIGINT, JobTask.exit )
signal.signal(signal.SIGTERM, JobTask.exit )

'''
存儲到數據庫我使用線程處理,這樣異步不影響返回
queue模塊有三種隊列及構造函數:
Python queue模塊的FIFO隊列先進先出。 class queue.Queue(maxsize)
LIFO類似於堆,即先進后出。 class queue.LifoQueue(maxsize)
還有一種是優先級隊列級別越低越先出來。 class queue.PriorityQueue(maxsize)
'''
manager = multiprocessing.Manager()
global_queue = multiprocessing.Queue()
sendmail_flag = multiprocessing.Value( c_bool,False )
def syncConsumer(name):
    with app.app_context():  # http://flask-sqlalchemy.pocoo.org/2.3/contexts/
        while True:
            try:
                app.logger.info( "syncConsumer,pid:%s"%( os.getpid() ) )
                queue_msg = global_queue.get()
                # get_nowait()不會阻塞等待
                app.logger.info('[%s]取到了[%s]' % (name, queue_msg['type']))
                if queue_msg['type'] in [ "friends","group" ]:
                    type = 2 if queue_msg['type'] == "group" else 1
                    WeChatBotService.initContact( queue_msg['data'],type )

                elif queue_msg['type'] == "msg":
                    WeChatBotService.addHistory(queue_msg['data'])
                time.sleep(1)
            except Exception as err:
                traceback.print_exc()
                exit( 15 )


總結

通過借助於 itchat 和圖片機器人 ,然后基於 Python3 + Flask MVC + MySQL 就可以實現一個自己的微信機器人 ,過程其實相當簡單,但是需要大家對 Python3 + Flask MVC 有一定的了解,並且本人根據項目經驗總結出來了一套個性化的 :結構分層明了、高並發 MVC框架。

廣告

如果您對Python Flask學習感興趣 ,而您整好基礎薄弱,可以看看我的兩個課程,僅供您參考



原文地址: 使用Python Flask 開發微信機器人
標簽: 微信    wechat    機器人    robot    python    flask    mooc    慕課   

智能推薦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM