# _*_ coding: utf-8 _*_
"""
python_wechat.py by xianhu
主è¦å
æ¬å¦ä¸åè½ï¼
(1) èªå¨æé群红å
(2) èªå¨çæµè¢«æ¤åæ¶æ¯
(3) 群å
³é®åæéï¼ç¾¤è¢«@æé
"""
import time
import itchat
import logging
from itchat.content import *
# åå§å
my = itchat.new_instance()
my.auto_login(hotReload=False, enableCmdQR=2)
# myè¿å
æ¬ç以ä¸å±æ§ï¼æ³¨æç¨ç¹.æ¥çï¼
# (1) alive æ¯å¦è¿æ´»çï¼isLogging æ¯å¦å·²ç»é
# (2) loginInfo ç»éä¿¡æ¯ï¼å
¶ä¸çUser屿§ä¸ºèªå·±çä¿¡æ¯Useråå
¸ç±»ï¼å
æ¬UserName, NickName, RemarkName, Sex(1 or 2), Signature, Province, Cityç
# (3) memberList é讯å½åè¡¨ï¼æ¯ä¸é¡¹ä¸ºä¸ä¸ªUseråå
¸ç±»ï¼å
æ¬UserName, NickName, RemarkName, Sex(1 or 2), Signature, Province, Cityç
# (4) chatroomList 群èåè¡¨ï¼æ¯ä¸é¡¹ä¸ºä¸ä¸ªChatroomåå
¸ç±»ï¼å
æ¬UserName, NickName, RemarkName, MemberCount, MemberList, Selfç
# (5) mpList 订é
å·åè¡¨ï¼æ¯ä¸é¡¹ä¸ºä¸ä¸ªMassivePlatformåå
¸ç±»ï¼å
æ¬UserName, NickNameç
my.global_keys = ["åä¸", "人工æºè½", "ä¼ä¸æå¡"]
my.to_user_name = "filehelper" # æ¶æ¯æ¥åè
my.update_time = time.time() # ä¿¡æ¯æ´æ°æ¶é´
my.msg_store = {} # æ¶æ¯åå¨éå
my.friends = {} # 好ååå
¸å表
my.groups = {} # 群èåå
¸å表
def update_my_infos():
"""
æ´æ°ä¿¡æ¯
"""
# è·åå¹¶æ´æ°é讯å½: {UserName: UserInstance}
my.friends = {user["UserName"]: user for user in my.get_friends(update=True)}
# è·åå¹¶æ´æ°ç¾¤å表: {UserName: UserInstance}
my.groups = {group["UserName"]: group for group in my.get_chatrooms(update=True)}
return
update_my_infos()
class Message(object):
"""
æ¶æ¯ç±»
"""
def __init__(self, msg):
"""
æé 彿°ï¼æåæ¶æ¯å
容
æ¶æ¯æ¥æºåç±»ï¼
ï¼1ï¼æ¥èªå¥½åçæ¶æ¯
ï¼2ï¼æ¥èªç¾¤çæ¶æ¯
æåæ¶æ¯å
å®¹ï¼æ¶æ¯ç±»ååç±»ï¼
ï¼1ï¼æåï¼2ï¼å¾çï¼3ï¼è¯é³ï¼4ï¼è§é¢ï¼5ï¼å°åï¼6ï¼åçï¼7ï¼æéï¼8ï¼å享ï¼9ï¼éä»¶
"""
# æ´æ°ä¿¡æ¯ï¼ååéæ´æ°ä¸æ¬¡
# logging.warning("message: %s", msg)
if time.time() - my.update_time > 600:
update_my_infos()
my.update_time = time.time()
self.msg_id = msg["MsgId"] # æ¶æ¯ID
self.from_user_name = msg["FromUserName"] # æ¶æ¯åéè
IDï¼å¦æä¸ºç¾¤æ¶æ¯ï¼å为群ID
self.msg_type = msg["MsgType"] # æ¶æ¯ç±»åï¼è¿éåèä¸è¾¹çwe_type
self.msg_content = msg["Content"] # æ¶æ¯å
容ï¼è¿éåèä¸è¾¹çwe_text
self.msg_time = msg["CreateTime"] # æ¶æ¯åéæ¶é´ï¼æ¶é´æ³æ ¼å¼
self.msg_file = msg["FileName"] # æ¶æ¯ä¸æå¸¦æä»¶çåç§°
self.msg_file_length = msg["FileSize"] # æ¶æ¯ä¸æå¸¦æä»¶ç大å°ï¼å符串类å
self.msg_voice_length = msg["VoiceLength"] # æ¶æ¯ä¸æå¸¦è¯é³çé¿åº¦ï¼æ¯«ç§ï¼
self.msg_play_length = msg["PlayLength"] # æ¶æ¯ä¸æå¸¦è§é¢çé¿åº¦ï¼ç§ï¼
self.msg_url = msg["Url"] # æ¶æ¯ä¸æå¸¦é¾æ¥çå°å
self.user_user_name = msg["User"].get("UserName", "") # æ¶æ¯åéè
IDï¼å¦æä¸ºç¾¤æ¶æ¯ï¼å为群ID
self.user_nick_name = msg["User"].get("NickName", "") # æ¶æ¯åéè
æµç§°ï¼å¦æä¸ºç¾¤æ¶æ¯ï¼å为群å
self.user_remark_name = msg["User"].get("RemarkName", "") # æ¶æ¯åéè
夿³¨åç§°ï¼å¦æä¸ºç¾¤æ¶æ¯ï¼åä¸ºç¾¤å¤æ³¨åç§°
self.wind_name = self.user_remark_name if self.user_remark_name else (
self.user_nick_name if self.user_nick_name else (
my.friends[self.user_user_name]["NickName"] if self.user_user_name in my.friends else (
my.groups[self.user_user_name]["NickName"] if self.user_user_name in my.groups else "æªç¥çªå£"
)
)
)
self.actual_user_name = msg.get("ActualUserName", "") # ç¾¤æ¶æ¯ä¸ï¼æ¶æ¯åéè
çID
self.actual_nick_name = msg.get("ActualNickName", "") # ç¾¤æ¶æ¯ä¸ï¼æ¶æ¯åéè
ç群æµç§°
self.actual_remark_name = self.actual_nick_name \
if (self.actual_user_name not in my.friends) or (not my.friends[self.actual_user_name]["RemarkName"]) \
else my.friends[self.actual_user_name]["RemarkName"]
self.is_at = msg.get("IsAt", None) # æ¯å¦å¨ç¾¤å
被@
self.we_type = msg["Type"] # æ¶æ¯ç±»å
self.we_text = msg["Text"] # æ¶æ¯å
容
logging.warning("wind_name=%s, send_name=%s, we_type=%s, we_text=%s", self.wind_name, self.actual_remark_name, self.we_type, self.we_text)
return
def process_message_group(msg):
"""
å¤çç¾¤æ¶æ¯
"""
# ==== å¤ç红å
æ¶æ¯ ====
if msg.we_type == "Note" and msg.we_text.find("æ¶å°çº¢å
ï¼è¯·å¨ææºä¸æ¥ç") >= 0:
my.send("ã%sãä¸æäººå红å
å¦ï¼å¿«æ¢ï¼" % msg.wind_name, toUserName=my.to_user_name)
# ==== å¤çå
³é®è¯æ¶æ¯ ====
for key in my.global_keys:
if msg.we_type == "Text" and msg.we_text.find(key) >= 0:
my.send("ã%sãä¸ã%sãæåäºå
³é®åï¼%s" % (msg.wind_name, msg.actual_remark_name, key), toUserName=my.to_user_name)
my.send(msg.we_text, toUserName=my.to_user_name)
break
# ==== 群å
æ¯å¦è¢«@ ====
if msg.we_type == "Text" and msg.is_at:
my.send("ã%sãä¸ã%sã@äºä½ " % (msg.wind_name, msg.actual_remark_name), toUserName=my.to_user_name)
my.send(msg.we_text, toUserName=my.to_user_name)
return
def process_message_revoke(msg):
"""
å¤çæ¤åæ¶æ¯
"""
# æ¶æ¯åå¨ï¼å é¤è¿ææ¶æ¯
my.msg_store[msg.msg_id] = msg
for _id in [_id for _id in my.msg_store if time.time() - my.msg_store[_id].msg_time > 120]:
my.msg_store.pop(_id)
# ä¿åæ¶æ¯ä¸çå
容ï¼å¾çãè¯é³çï¼
if msg.we_type in ["Picture", "Recording"]:
try:
msg.we_text(".Cache/" + msg.msg_file)
logging.warning("process_message_revoke: download %s to .Cache/", msg.msg_file)
except Exception as excep:
logging.error("process_message_revoke: download %s to .Cache/ error: %s", msg.msg_file, excep)
# ==== æ¤åæ¶æ¯å¤çï¼å¿
须为æå䏿¥ï¼ ====
if msg.we_type == "Note" and msg.we_text.find("æ¤åäºä¸æ¡æ¶æ¯") >= 0:
old_msg = my.msg_store.get(msg.msg_content[msg.msg_content.find("