88(3) 自动保存被撤回消息
99"""
1010
11+ import re
1112import time
1213import itchat
1314import logging
1617
1718# 初始化
1819newInstance = itchat .new_instance ()
19- newInstance .auto_login (enableCmdQR = 2 )
20+ newInstance .auto_login (hotReload = False , enableCmdQR = 2 )
2021newInstance .global_keys = ["人工智能" , "机器学习" , "算法" , "数据挖掘" ]
22+ newInstance .to_user_name = "filehelper"
2123
22- # 获取自己的属性字典
23- owner = newInstance .search_friends ( name = None )
24+ # 获取自己的属性字典:UserName, NickName, RemarkName, Sex(1 or 2)
25+ newInstance . owner = newInstance .loginInfo [ "User" ]
2426
2527# 获取通讯录: {UserName: UserInstance}
26- friends = {item ["UserName" ]: item for item in newInstance .get_friends (update = True )}
28+ newInstance . friends = {user ["UserName" ]: user for user in newInstance .get_friends (update = True )}
2729
2830# 消息存储队列
29- msg_store = {}
31+ newInstance . msg_store = {}
3032
3133
3234# 消息提取函数
3335def get_msg_list (msg ):
3436 """
3537 提取消息内容
3638 """
37- logging .warning ("%s: %s" , msg [ "MsgType" ] , msg )
38-
39- msg_id = msg ["MsgId" ] # 消息ID
40- from_user_name = msg ["FromUserName" ] # 消息发送者ID
41- to_user_name = msg ["ToUserName" ] # 消息接受者ID
42- msg_type = msg [ "MsgType" ] # 消息类型
43- msg_content = msg ["Content " ] # 消息内容
44- msg_file = msg ["FileName " ] # 消息中所带文件的名称
39+ logging .warning ("%s" , msg )
40+
41+ msg_id = msg ["MsgId" ] # 消息ID
42+ from_user_name = msg ["FromUserName" ] # 消息发送者ID
43+ to_user_name = msg ["ToUserName" ] # 消息接受者ID
44+
45+ msg_type = msg ["MsgType " ] # 消息类型
46+ msg_content = msg ["Content " ] # 消息内容
4547 msg_time = datetime .datetime .fromtimestamp (msg ["CreateTime" ]) # 消息发送时间
4648
47- wind_name = msg ["User" ]["NickName" ] # 聊天窗口名称
48- user_name = msg ["ActualUserName" ] # 消息发送者的名称
49- nick_name = msg ["ActualNickName" ] if (user_name not in friends ) or (friends [user_name ]["RemarkName" ] == "" ) else friends [user_name ]["RemarkName" ]
49+ msg_file = msg ["FileName" ] # 消息中所带文件的名称
50+ msg_url = msg ["Url" ] # 消息中带有的链接地址
51+
52+ if from_user_name .startswith ("@@" ):
53+ # 群消息
54+ wind_name = msg ["User" ]["RemarkName" ] if msg ["User" ]["RemarkName" ] else msg ["User" ]["NickName" ]
55+ nick_name = msg ["ActualNickName" ] if (msg ["ActualUserName" ] not in newInstance .friends ) or \
56+ (not newInstance .friends [msg ["ActualUserName" ]]["RemarkName" ]) else newInstance .friends [msg ["ActualUserName" ]]["RemarkName" ]
57+ else :
58+ # 个人消息
59+ wind_name = msg ["User" ]["RemarkName" ] if msg ["User" ]["RemarkName" ] else msg ["User" ]["NickName" ]
60+ nick_name = wind_name
61+
62+ we_type = msg ["Type" ] # 消息类型
63+ we_text = msg ["Text" ] # 消息内容
5064
51- print (msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_file , msg_time , wind_name , nick_name )
52- return msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_file , msg_time , wind_name , nick_name
65+ return msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_time , msg_file , msg_url , wind_name , nick_name , we_type , we_text
5366
5467
5568# 消息注册,主要处理群消息
@@ -59,37 +72,61 @@ def text_reply(msg):
5972 消息自动接收, 接受全部的消息
6073 """
6174 # 消息提取
62- msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_file , msg_time , wind_name , nick_name = get_msg_list (msg )
75+ msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_time , msg_file , msg_url , wind_name , nick_name , we_type , we_text = get_msg_list (msg )
6376
64- # 消息存储,并删除过期消息
65- msg_store [msg_id ] = msg
66- for _id in msg_store :
67- if time .time () - msg_store [_id ]["CreateTime" ] > 120 :
68- msg_store .pop (_id )
77+ # 消息过滤,过滤自己发送的消息
78+ if from_user_name == newInstance .owner ["UserName" ]:
79+ logging .warning ("message from myself, skip" )
80+ return
81+
82+ # 消息过滤, 只监测文字、注解、分享、图片、语音、视频、附件等
83+ if we_type not in ["Text" , "Note" , "Sharing" , "Picture" , "Recording" , "Video" , "Attachment" ]:
84+ logging .warning ("message ignored" )
85+ return
86+
87+ if we_type in ["Picture" , "Recording" , "Video" , "Attachment" ]:
88+ re_length = re .search ("[\" \s]length=\" (?P<length>[\d]+?)\" " , msg_content , flags = re .IGNORECASE )
89+ if (not msg_content ) or (re_length and (int (re_length .group ("length" )) < 5000000 )):
90+ we_text (".Cache/" + msg_file )
91+ logging .warning ("downloading %s to .Cache/" , msg_file )
92+
93+ # 消息存储
94+ newInstance .msg_store [msg_id ] = msg
95+
96+ # 删除过期消息
97+ ids_list = [_id for _id in newInstance .msg_store if time .time () - newInstance .msg_store [_id ]["CreateTime" ] > 120 ]
98+ for _id in ids_list :
99+ logging .warning ("delete message, message_id = %s" , _id )
100+ newInstance .msg_store .pop (_id )
69101
70102 # 处理群消息
71103 if from_user_name .startswith ("@@" ):
72104 # 红包消息处理
73- if msg_type == 10000 and msg_content .find ("红包" ) :
74- newInstance .send ("【%s】中有红包,快抢!\n From: %s\n Content: %s\n Time: %s" % (wind_name , nick_name , msg_content , msg_time ), toUserName = "filehelper" )
105+ if we_type == "Note" and we_text .find ("收到红包,请在手机上查看" ) >= 0 :
106+ newInstance .send ("【%s】中有红包,快抢!\n From: %s\n Content: %s\n Time: %s" % (wind_name , nick_name , msg_content , msg_time ), toUserName = newInstance . to_user_name )
75107
76108 # 提到自己消息处理
77109 if msg ["IsAt" ]:
78- newInstance .send ("【%s】中有@你的消息:\n From: %s\n Content: %s\n Time: %s" % (wind_name , nick_name , msg_content , msg_time ), toUserName = "filehelper" )
110+ newInstance .send ("【%s】中有@你的消息:\n From: %s\n Content: %s\n Time: %s" % (wind_name , nick_name , msg_content , msg_time ), toUserName = newInstance . to_user_name )
79111
80112 for key in newInstance .global_keys :
81113 if msg_content .find (key ) >= 0 :
82- newInstance .send ("【%s】中有关键字【%s】:\n From: %s\n Content: %s\n Time: %s" % (wind_name , key , nick_name , msg_content , msg_time ), toUserName = "filehelper" )
114+ newInstance .send ("【%s】中有关键字【%s】:\n From: %s\n Content: %s\n Time: %s" % (wind_name , key , nick_name , msg_content , msg_time ), toUserName = newInstance . to_user_name )
83115 break
84116
85117 # 撤回消息处理
86- if msg_type == 10002 and msg_content .find ("撤回" ):
87- old_msg_id = msg_content [msg_content .find ("<msgid>" )+ 7 : msg_content .find ("</msgid>" )]
88- msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_file , msg_time , wind_name , nick_name = get_msg_list (msg_store [old_msg_id ])
89- newInstance .send ("【%s】中有消息被撤回:\n From: %s\n Content: %s\n File: %s\n Time: %s" % (wind_name , nick_name , msg_content , msg_file , msg_time ), toUserName = "filehelper" )
90- if msg_file :
91- msg_store [old_msg_id ].download (msg_file )
92-
118+ if we_type == "Note" and we_text .find ("撤回了一条消息" ) >= 0 :
119+ old_msg = newInstance .msg_store .get (msg_content [msg_content .find ("<msgid>" )+ 7 : msg_content .find ("</msgid>" )])
120+ if not old_msg :
121+ return
122+
123+ msg_id , from_user_name , to_user_name , msg_type , msg_content , msg_time , msg_file , msg_url , wind_name , nick_name , we_type , we_text = get_msg_list (old_msg )
124+ if we_type in ["Picture" , "Recording" , "Video" , "Attachment" ]:
125+ msg_content = msg_file
126+ elif we_type == "Sharing" :
127+ msg_content = we_text + ": " + msg_url
128+
129+ newInstance .send ("【%s】中有消息被撤回:\n From: %s\n Type: %s\n Content: %s\n Time: %s" % (wind_name , nick_name , we_type , msg_content , msg_time ), toUserName = newInstance .to_user_name )
93130 return
94131
95132
0 commit comments