1. 程式人生 > >利用wxpy快速實現微信自動回覆

利用wxpy快速實現微信自動回覆

最近發現一個關於微信的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()