利用wxpy快速實現微信自動回覆
阿新 • • 發佈:2019-01-03
最近發現一個關於微信的python庫(wxpy),可以對微信進行很多操作。於是就寫了一個微信自動回覆的整人小程式,分享上來記錄一下
以下是登入以及回覆的主要程式碼,wxpy的官方文件寫的很全,很有參考價值。
from wxpy import * import TuLing SourceSavePath = '.\\RecieveFile\\' bot = Bot(cache_path = True) myFriend = bot.friends() #被處理訊息的物件或物件集合 #myFriend += bot.groups().search('GroupName') #新增群 @bot.register(myFriend) #註冊訊息處理方法 def Del_GroupMsg(msg): print (msg.sender.name,':',msg.text,'Msg Type:',msg.type) msg.sender.mark_as_read() if msg.type == TEXT: #如果是文字,就利用圖靈機器人api回覆,return和msg.reply_msg效果一樣 return TuLing.getAutoRecieve(msg.text) elif msg.type == PICTURE: #如果接受到圖片,就自動回覆同樣的圖片 print ('this is PICTURE:{}'.format(msg.file_name)) savaPath = SourceSavePath+msg.file_name msg.get_file(savaPath) msg.reply_image(savaPath) else:#其它的就轉發回給傳送人 msg.forward(msg.sender) embed()
以下是圖靈機器人api呼叫的程式碼(wxpy中也有結合圖靈機器人的介面,後來才發現的):
# coding=utf-8 import urllib.request import json from urllib.parse import quote import string key = '#########################' #key要自己去註冊 api = 'http://www.tuling123.com/openapi/api?key=' + key + '&info=' def gethtml(url): url = quote(url, safe=string.printable) return urllib.request.urlopen(url).read() def getAutoRecieve(msg): request = api + msg response = gethtml(request) dicJson = json.loads(response) return dicJson['text']
為了方便使用,看了一點tkinter程式設計,亂七八糟的寫了一個ui介面(對python是真的不熟,現在努力在學習),程式碼如下:
import tkinter as tk from tkinter import * import wxpy_api as wxapi from wxpy import * import chardet import re import TuLing SourceSavePath = '.\\RecieveFile\\' def filter_emoji(desstr,restr=''): if desstr is None or len(desstr) == 0: return '沒名字的狗東西???' try: co = re.compile(u'[\U00010000-\U0010ffff]') except re.error: co = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]') return co.sub(restr, desstr) class WeixinMainUI(tk.Frame): class WeiXinFuction(object): """docstring for WeiXinFuction""" def __init__(self): self.autoRecieveCommon = False self.autoRecieveTuling = False self.autoRecieveCustom = False self.autoRecievePicture = False self.autoRecieveCustom_Content = '' def __init__(self,master=None): tk.Frame.__init__(self,master) self.pack() self.checkValue = [BooleanVar() for i in range(4)] self.createWidgets() self.bot = None self.isLogin = False self.chatRecordDict = {} # key:puid value : record self.fuctionDict = {} #key:puid value :WeiXinFuction self.puidIndexDict={} #key:puid value: ListBox Index self.curFriends = None self.loadFriendsGroup = [] #載入的好友和群列表 def createWidgets(self): TopFrame = tk.Frame(self.master,borderwidth = 0) tk.Label(TopFrame,text='當前登入使用者名稱:').pack(side = tk.LEFT) self.__userNameLabel = tk.Label(TopFrame,text='None',padx = 10) self.__userNameLabel.pack(side = tk.LEFT) self.__loginorexitBtn = tk.Button(TopFrame,text='登入',command = self.LogionOrExit,width = 10) self.__loginorexitBtn.pack(side = tk.RIGHT) TopFrame.pack(side= tk.TOP,pady = 10) OptFram = tk.Frame(self.master) friscroll = Scrollbar(OptFram) self.__FriendsList = tk.Listbox(OptFram,height =30,width = 20,yscrollcommand = friscroll.set,selectmode=SINGLE) friscroll.pack(side = tk.LEFT,fill = Y) friscroll.config( command = self.__FriendsList.yview ) self.__FriendsList.pack(side = tk.LEFT) self.__FriendsList.bind('<Button-1>',self.OnFriendsClick) self.__CurFriendsInfo = tk.Label(OptFram,height = 1,width = 78,bg = 'green') self.__CurFriendsInfo.pack(side = TOP) chatscroll = Scrollbar(OptFram) chatscroll.pack(side = RIGHT,fill = Y) self.__chatMsg = tk.Listbox(OptFram,height = 27,width = 80,background='#DCDCDC',yscrollcommand = chatscroll.set) self.__chatMsg.pack(side = TOP) chatscroll.config( command = self.__chatMsg.yview ) ChatFram = tk.Frame(OptFram) SendMsgFram = tk.Frame(ChatFram) self.__SendMsg = tk.Entry(SendMsgFram,width = 64) self.__SendMsg.pack(side = tk.LEFT,padx=5,fill = X) self.__SendMsg.bind('<Return>',self.OnKeyDown) self.__SendButton = tk.Button(SendMsgFram,text = '傳送訊息',width = 10,command = self.SendMsg) self.__SendButton.pack(side = tk.RIGHT) SendMsgFram.pack(side = BOTTOM) ChatFram.pack(padx = 5) FucFram = tk.Frame(self.master) self.__check1 = tk.Checkbutton(FucFram,text = '自動回覆相同資訊',width = 20,variable = self.checkValue[0],command = self.FuctionChange) self.__check1.pack(side = tk.TOP) self.__check2 = tk.Checkbutton(FucFram,text = '自動回覆相同圖片',width = 20,variable = self.checkValue[1],command = self.FuctionChange) self.__check2.pack(side = tk.TOP) self.__check3 = tk.Checkbutton(FucFram,text = '機器人陪聊',width = 20,variable = self.checkValue[2],command = self.FuctionChange) self.__check3.pack(side = tk.TOP) self.__check4 = tk.Checkbutton(FucFram,text = '自定義回覆',width = 20,variable = self.checkValue[3],command = self.FuctionChange) self.__check4 .pack(side = tk.TOP) self.__AutoRecieveCustom = tk.Entry(FucFram,width = 20,state = tk.DISABLED) self.__AutoRecieveCustom.pack(side = tk.TOP) self.__AutoRecieveCustom.bind('<Leave>',self.autoRecieveCustomChange) FucFram.pack(side = tk.RIGHT) OptFram.pack(padx= 10) def LogionOrExit(self): if self.__loginorexitBtn['text'] == '登入': self.bot = Bot(cache_path = True,login_callback = self._LoginCallBack, logout_callback = self._LogoutCallBack) self.bot.enable_puid() self.loadFriendsGroup +=self.bot.friends() + self.bot.groups() self.RefreshUI() @self.bot.register(self.loadFriendsGroup) def msg_Recieve(msg): #print (filter_emoji(sender.name,'⊙')+':'+msg.text) msg.sender.mark_as_read() sender = msg.sender if sender.puid not in self.chatRecordDict: self.chatRecordDict[sender.puid] = [] senderName = sender.name if type(sender) == Group: senderName = msg.member.name if msg.type == TEXT: self.chatRecordDict[sender.puid].append(filter_emoji(senderName,'⊙')+' : '+msg.text) else: self.chatRecordDict[sender.puid].append(filter_emoji(senderName,'⊙')+' : '+'不可接收型別的資訊(除文字外的資訊)!') if self.curFriends is not None and sender.puid == self.curFriends.puid: self.RefreshChatRecord(self.curFriends) else : if sender.puid in self.puidIndexDict: index = self.puidIndexDict[sender.puid] self.__FriendsList.itemconfig(index,{'bg':'red'}) if sender.puid in self.fuctionDict: fuc = self.fuctionDict[sender.puid] print(msg.type) if msg.type == TEXT: if fuc.autoRecieveTuling: msg.reply_msg(TuLing.getAutoRecieve(msg.text)) if fuc.autoRecieveCommon: msg.reply_msg(msg.text) if fuc.autoRecieveCustom: msg.reply_msg(fuc.autoRecieveCustom_Content) elif msg.type == PICTURE: if fuc.autoRecievePicture: savaPath = SourceSavePath+msg.file_name msg.get_file(savaPath) msg.reply_image(savaPath) ''' else: msg.forward(sender) ''' elif self.bot is not None: self.bot.logout() self.master.quit() def SendMsg(self): if self.curFriends is not None: msg = self.curFriends.send_msg(self.__SendMsg.get()) if self.curFriends.puid not in self.chatRecordDict: self.chatRecordDict[self.curFriends.puid] = [] self.chatRecordDict[self.curFriends.puid].append(' 我:'+msg.text) self.__SendMsg.delete(0,len(self.__SendMsg.get())) self.RefreshChatRecord(self.curFriends) else: print ('No curFriends') def _LoginCallBack(self): self.isLogin = True self.__loginorexitBtn['text'] = '退出' def _LogoutCallBack(self): self.isLogin = False self.__loginorexitBtn['text'] = '登入' self.bot = None def RefreshUI(self): if self.bot is not None: #print ('name:',self.bot.self.nick_name) self.__userNameLabel['text'] = filter_emoji(self.bot.self.nick_name,'⊙') i = 0 for friend in self.loadFriendsGroup: print ('friend name :',friend.name) if type(friend) == Friend: self.__FriendsList.insert(tk.END,filter_emoji(friend.name,'⊙')) if friend.sex== MALE: self.__FriendsList.itemconfig(i,{'fg':'#00BFFF'}) else: self.__FriendsList.itemconfig(i,{'fg':'#f08080'}) else: self.__FriendsList.insert(tk.END,filter_emoji(friend.name,'⊙')+ '(群聊)') self.__FriendsList.itemconfig(i,{'fg':'green'}) self.puidIndexDict[friend.puid] = i i+=1 def RefreshCurFriendsInfo(self,friend): nick_name = filter_emoji(friend.nick_name,'⊙') if type(friend) == Friend: nick_name = filter_emoji(friend.nick_name,'⊙') remark_name = filter_emoji(friend.name,'⊙') sex = '男' if friend.sex!= MALE: sex = '女' self.__CurFriendsInfo['text'] = '暱稱:%s 備註:%s 性別:%s' % (nick_name,remark_name,sex) else: self.__CurFriendsInfo['text'] = '群名:%s 群人數:%d' % (nick_name,len(friend)) def OnFriendsClick(self,event): #index = self.__FriendsList.curselection()[0] #雙擊可以,單擊不行,若繼承Listbox則可以根據此得到 index = event.widget.nearest(event.y) self.curFriends = self.loadFriendsGroup[index] if self.curFriends.puid in self.puidIndexDict: index = self.puidIndexDict[self.curFriends.puid] self.__FriendsList.itemconfig(index,{'bg':'white'}) self.RefreshCurFriendsInfo(self.curFriends) self.RefreshChatRecord(self.curFriends) if self.curFriends.puid not in self.fuctionDict: self.fuctionDict[self.curFriends.puid] = self.WeiXinFuction() self.RefreshFuctionSetup(self.fuctionDict[self.curFriends.puid]) def RefreshChatRecord(self,friend): self.__chatMsg.delete(0,self.__chatMsg.size()) if friend.puid in self.chatRecordDict: for record in self.chatRecordDict[friend.puid]: self.__chatMsg.insert(tk.END,filter_emoji(record)) self.__chatMsg.select_set(self.__chatMsg.size() -1) def OnKeyDown(self,event): self.SendMsg() def FuctionChange(self): if self.curFriends is not None and self.curFriends.puid in self.fuctionDict: fuc = self.fuctionDict[self.curFriends.puid] fuc.autoRecieveCommon = self.checkValue[0].get() fuc.autoRecievePicture = self.checkValue[1].get() fuc.autoRecieveTuling = self.checkValue[2].get() fuc.autoRecieveCustom = self.checkValue[3].get() if self.checkValue[3].get(): self.__AutoRecieveCustom['state'] = tk.NORMAL else: self.__AutoRecieveCustom['state'] = tk.DISABLED def autoRecieveCustomChange(self,event): if self.curFriends is not None and self.curFriends.puid in self.fuctionDict: fuc = self.fuctionDict[self.curFriends.puid] fuc.autoRecieveCustom_Content = self.__AutoRecieveCustom.get() def RefreshFuctionSetup(self,fuc): self.checkValue[0].set(fuc.autoRecieveCommon) self.checkValue[1].set(fuc.autoRecievePicture) self.checkValue[2].set(fuc.autoRecieveTuling) self.checkValue[3].set(fuc.autoRecieveCustom) self.__AutoRecieveCustom['text'] = fuc.autoRecieveCustom_Content if self.checkValue[3].get(): self.__AutoRecieveCustom['state'] = tk.NORMAL else: self.__AutoRecieveCustom['state'] = tk.DISABLED app = WeixinMainUI() app.master.title("微信自動回覆") app.master.geometry('900x600') app.master.resizable(0,0) app.mainloop()