使用Python Flask 开发微信机器人
缘由
由于我个人有个小博客,然后还录制了一些课程,所有就建立了对应的微信群,但是微信群的二维码是变化的,总不能经常换了。所以就想搞一个微信机器人,自动加 微信,自动拉群。废话不多说,先上图
效果展示
大家可以试试效果,效果相当棒
需求
其他人可以通过二维码加我好友 自动通过
好友通过之后 主动发送一些邀请入群链接和介绍信
回复 邀请 、加群 可以发送邀请入群链接
所有聊天数据都要存储起来 并且可以通过Web展示
根据用户输入信息 回复相关内容
技术选型
Python3
Flask:轻量级的MVC 框架
itchat :实现微信API相关接口
MySQL:存储相关微信内容
图灵机器人:调用API实现主动场景回复
架构
本人没有使用flask 默认的MVC方式,使用了我自己实现过后的:结构分层明了的MVC框架 。结构如下
每一个文件夹都有自己明确的作用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ├── 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 |
实现源码
这里将主要实现源码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | # -*- 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 从入门到精通: https://coding.imooc.com/class/399.html
Python Flask构建微信小程序订餐系统: https://coding.imooc.com/class/265.html
原文地址:使用Python Flask 开发微信机器人
标签:微信 wechat 机器人 robot python flask mooc 慕课
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步