Python create a micro-channel group chat robot (with operator interface)

Foreword

These days one of my little friends asked if I could do to Ta a flexible configuration of the micro-channel group chat robot, before understood the itchatuse of the library, I readily agreed, and spent a night, finally made a prototype.

A computer running the program as follows:

Here Insert Picture Description

Information on the phone as follows:

Here Insert Picture Description

In fact, based on itchatmicro-channel robots already rotten Street, but most are too simple, comparatively speaking, I have this program has the following several distinct characteristics:

1, support for open / close automatic reply specified group chat, simply use Notepad to open group.csvthe file, you want to open automatically fill in reply to a group chat name, losers every time a group chat name, you must wrap.

2, support for custom settings keywords reply, just use Notepad to open keyword.csvthe file, in accordance with the keyword {***, ***} reply formats can be added without having to make any changes in the code. Losers a key-value pair, also need wrap, note that the input comma.

3, the timing of bulk messaging support, and time, the message can be modified dynamically during program execution.

4, there is favorably GUIinterface, wherein the reference color with a simple design of the micro-channel.

DIY play

1, for businesses

As a merchant, when maintenance group may have such needs, time to send a message. For example 回复 xxx 可获得 yyy, while in the keyword.csvpre-written document. In this way, you can make group members what they need, and you do not need to type, copy and paste, can also handle multiple groups at the same time, peace of mind is also efficient.

2, for ordinary individuals

Timing, parents who send blessings to the male and female friends good night messages.

3, Ali goes to deploying server

If you want to have a bug that has been automatically group sent message, your computer must have been open, but deploy to the cloud server can solve this problem. Deployment process can refer to my previous article, Ali cloud server while giving preferential purchase portal.

Detailed design of the code

1, the code architecture

Since the introduction GUI, GUIcode blocks and code blocks responsible for mass messages, are obstructive, to that end, procedures must be introduced multi-threading mechanism, in which the GUIinterface is the main thread, run a block of code responsible for mass message in a child thread, the thread communication between I use the wxPythonbuilt-in wx.lib.pubsubmodule, once the child thread to perform the corresponding action on the adoption of wx.CallAfter(pub.sendMessage)the interface to send messages to notify GUIthe thread, so as to ensure GUItimely refresh does not regard Caton.

Here Insert Picture Description

2, the code flow

First, load the appropriate configuration file to determine which group chat open automatic reply, reply and keyword information. That is why, during program execution, this information can not be changed dynamically.

Wherein the loading keywordcode is as follows:

def load_keyword(self):
	global keywords
	with open('keyword.csv', 'r', encoding='utf-8', newline='') as f:
		reader = csv.reader(f)
		for i, line in enumerate(reader):
			if i == 0:
				continue
			keywords[line[0]] = line[1]

The keywordsset of global variables for easy retrieval, to avoid call parameter passing, it is determined i == 0to remove csvthe first line of the file header information.

The main bulk of the code block following responsible, code comments more clear, will not be repeated

@itchat.msg_register(TEXT, isGroupChat=True)
def group_text(msg):
	global keywords
	groups = itchat.get_chatrooms(update=True)
	for group in groups:
		# 群的 NickName 是群名称,UserName 是群id(以两个@开始)
		# Python/Java 学习交流群
		if group['NickName'] in group_names:  # 从群中找到指定的群聊
			group_id = msg['FromUserName']
			# 防止其他群消息的的干扰
			if not group_id == group['UserName']:
				break
			# 准备回复的消息
			keys = keywords.keys()
			key = ''
			for i in keys:
				if i in msg['Text']:
					key = i
					break
			if key == '':
				return
			message = keywords.get(key)
			# 在消息中找到 发送人的id
			sender_id = msg['ActualUserName']
			# 有时 group['MemberList'] 为空,改变思路由群 id 获取群聊成员
			# group_info = itchat.update_chatroom(msg['ToUserName'], detailedMember=True)
			# if len(group_info) == 0:
			# toUserName 是自己在群聊发消息时,群 id 在消息里的 key
			# FromUserName 是别人在群里发时,群 id 在消息里的 key
			group_info = itchat.update_chatroom(group_id, detailedMember=True)
			memberlist = group_info['MemberList']
			for member in memberlist:
				# 找到消息的发送者
				if member['UserName'] == sender_id:
					# 如果有备注名,群聊显示的是备注名
					to_user = member['RemarkName']
					if len(to_user) == 0:
						# 否则显示成员自己修改的在群里的昵称
						to_user = member['DisplayName']
					if len(to_user) == 0:
						# 否则显示他微信号的昵称
						to_user = member['NickName']
					itchat.send_msg('@{}\n{}'.format(to_user, message), group['UserName'])
					wx.CallAfter(pub.sendMessage, "update", msg="回复群聊[{}]成员[{}]成功:[{}]".format(group['NickName'],to_user,message))

Mass responsible for the timing and the above code code more independent, while the child threads started, start timing of execution logic of mass

def run(self):
    global t
    t = threading.Timer(minutes * 60, self.auto_timer)
    t.start()
    self.load_keyword()
    self.load_group()
    itchat.auto_login(hotReload=True)
    itchat.run()

One of the major function is threading.Timer(minutes * 60, self.auto_timer), what it means is responsible for implementing the bulk of the thread, and then open a thread, the thread interval minutes * 60after seconds to execute a callback function self.auto_timer, but this can only be triggered once, no way has been polling, the solution is in go inside the callback function to perform threading.Timer(minutes * 60, self.auto_timer), a little similar to the recursive call, and is different from the recursive call is no termination condition, but does not produce memory overflow because of the timer, the time comes and a trigger callback function, this life thread ends here, so the duration of the program is running, the number of active threads just single digits:

def auto_timer(self):
    global auto_message
    groups = itchat.get_chatrooms(update=True)
    for group in groups:
        if group['NickName'] in group_names:
            itchat.send_msg('{}'.format(auto_message), group['UserName'])
            wx.CallAfter(pub.sendMessage, "update",
                         msg="群聊[{}]定时消息:[{}]发送成功".format(group['NickName'], auto_message))

    global t  # 把 t 设置为全局变量
    t = threading.Timer(minutes * 60, self.auto_timer)
    t.start()

GUI Due to space constraints part of the code, do not stick out.

How to Experience

Public concern No. month long small water background replies micro-channel group robot can be obtained

Published 84 original articles · won praise 250 · Views 150,000 +

Guess you like

Origin blog.csdn.net/ygdxt/article/details/89134003