撤回我也能看到!教你用Python制作微信防撤回腳本
一、之前解決方案
大概是這樣:短時間內同一位好友發送瞭多條消息,當他隨便撤回一條消息時,我們不能確定他到底撤回的到底是哪一條消息。隻能猜他可能是撤回瞭最近的一條消息,然後將其他消息貼出來作為備選。代碼如下:
target_msg_pattern = '"{}" 撤回瞭一條消息'.format(sender_name) if content == target_msg_pattern: return_msg = '【{}】撤回瞭一條消息:\n'.format(sender_name) if len(log[sender_name].items()) == 0: return_msg = '緩存信息列表為空!' else: return_msg += log[sender_name].items()[-1][-1] + '\n' if len(log[sender_name].items()) > 1: msgs = [msg for timestamp, msg in log[sender_name].items()[:-1]] return_msg += '也有可能是下列信息中的某一條:\n' + '\n'.join(msgs)
實際效果是這樣:
我這個強迫癥簡直受不瞭這麼不確定的說法。
二、分析msg信息
要想確定撤回瞭哪一條信息,就必須先熟悉普通msg和撤回的msg裡面都有哪些信息,他們的相同點和不同點。下面就來看看這兩種情況下msg都是怎麼樣的,不需要仔細的看每一行,後面會作具體分析。
先是用機器人“小幫幫”發送過來的信息得到的msg信息:
{ 'MsgId': '2018511155698964390', 'FromUserName': '@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3', 'ToUserName': '@**********c2e61fdb47b5c241553a2f', 'MsgType': 1, 'Content': 'msg裡面到底有什麼?', 'Status': 3, 'ImgStatus': 1, 'CreateTime': 1578069291, 'VoiceLength': 0, 'PlayLength': 0, 'FileName': '', 'FileSize': '', 'MediaId': '', 'Url': '', 'AppMsgType': 0, 'StatusNotifyCode': 0, 'StatusNotifyUserName': '', 'RecommendInfo': { 'UserName': '', 'NickName': '', 'QQNum': 0, 'Province': '', 'City': '', 'Content': '', 'Signature': '', 'Alias': '', 'Scene': 0, 'VerifyFlag': 0, 'AttrStatus': 0, 'Sex': 0, 'Ticket': '', 'OpCode': 0 }, 'ForwardFlag': 0, 'AppInfo': { 'AppID': '', 'Type': 0 }, 'HasProductId': 0, 'Ticket': '', 'ImgHeight': 0, 'ImgWidth': 0, 'SubMsgType': 0, 'NewMsgId': 2018511155698964390, 'OriContent': '', 'EncryFileName': '', 'User': < User: { 'MemberList': < ContactList: [] > , 'Uin': 0, 'UserName': '@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3', 'NickName': '小幫幫', 'HeadImgUrl': '/cgi-bin/mmwebwx-bin/webwxgeticon?seq=699837854&username=@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3&skey=@crypt_****c00c_92668c8ba7d285c221a85e**********', 'ContactFlag': 2049, 'MemberCount': 0, 'RemarkName': '小幫幫', 'HideInputBarFlag': 0, 'Sex': 2, 'Signature': '', 'VerifyFlag': 0, 'OwnerUin': 0, 'PYInitial': 'XBB', 'PYQuanPin': 'xiaobangbang', 'RemarkPYInitial': 'XBB', 'RemarkPYQuanPin': 'xiaobangbang', 'StarFriend': 0, 'AppAccountFlag': 0, 'Statues': 0, 'AttrStatus': 33658937, 'Province': '浙江', 'City': '臺州', 'Alias': '', 'SnsFlag': 17, 'UniFriend': 0, 'DisplayName': '', 'ChatRoomId': 0, 'KeyWord': '', 'EncryChatRoomId': '', 'IsOwner': 0 } > , 'Type': 'Text', 'Text': 'msg裡面到底有什麼?' }
下面是機器人撤回剛才的信息得到的msg信息:
{ 'MsgId': '4056955577161654067', 'FromUserName': '@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3', 'ToUserName': '@**********c2e61fdb47b5c241553a2f', 'MsgType': 10002, 'Content': '<sysmsg type="revokemsg"><revokemsg><session>wxid_4gngrr04aqjn21</session><oldmsgid>1123721956</oldmsgid><msgid>2018511155698964390</msgid><replacemsg><![CDATA["小幫幫" 撤回瞭一條消息]]></replacemsg></revokemsg></sysmsg>', 'Status': 4, 'ImgStatus': 1, 'CreateTime': 1578069381, 'VoiceLength': 0, 'PlayLength': 0, 'FileName': '', 'FileSize': '', 'MediaId': '', 'Url': '', 'AppMsgType': 0, 'StatusNotifyCode': 0, 'StatusNotifyUserName': '', 'RecommendInfo': { 'UserName': '', 'NickName': '', 'QQNum': 0, 'Province': '', 'City': '', 'Content': '', 'Signature': '', 'Alias': '', 'Scene': 0, 'VerifyFlag': 0, 'AttrStatus': 0, 'Sex': 0, 'Ticket': '', 'OpCode': 0 }, 'ForwardFlag': 0, 'AppInfo': { 'AppID': '', 'Type': 0 }, 'HasProductId': 0, 'Ticket': '', 'ImgHeight': 0, 'ImgWidth': 0, 'SubMsgType': 0, 'NewMsgId': 4056955577161654067, 'OriContent': '', 'EncryFileName': '', 'User': < User: { 'MemberList': < ContactList: [] > , 'Uin': 0, 'UserName': '@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3', 'NickName': '小幫幫', 'HeadImgUrl': '/cgi-bin/mmwebwx-bin/webwxgeticon?seq=699837854&username=@**********f511363f8200853d724137bb31236a7ea81e5183cc06cb4ec978e3&skey=@crypt_****c00c_92668c8ba7d285c221a85e**********', 'ContactFlag': 2049, 'MemberCount': 0, 'RemarkName': '小幫幫', 'HideInputBarFlag': 0, 'Sex': 2, 'Signature': '', 'VerifyFlag': 0, 'OwnerUin': 0, 'PYInitial': 'XBB', 'PYQuanPin': 'xiaobangbang', 'RemarkPYInitial': 'XBB', 'RemarkPYQuanPin': 'xiaobangbang', 'StarFriend': 0, 'AppAccountFlag': 0, 'Statues': 0, 'AttrStatus': 33658937, 'Province': '浙江', 'City': '臺州', 'Alias': '', 'SnsFlag': 17, 'UniFriend': 0, 'DisplayName': '', 'ChatRoomId': 0, 'KeyWord': '', 'EncryChatRoomId': '', 'IsOwner': 0 } > , 'Type': 'Note', 'Text': '"小幫幫" 撤回瞭一條消息' }
得到瞭兩種類型的msg,下面是對比(高亮的部分是不同處,省略瞭部分相同內容。可以點擊放大查看大圖
現在來分析幾條關鍵信息:
- MsgId(與下面的NewMsgId同)
- 消息編號。這個很好理解,每條消息都是通過一個獨一無二的編號來與其他消息區分,所以這兩條消息的編號不同很正常。如果我們能拿到好友撤回消息的編號,也就能鎖定這條消息瞭。
- MsgType(與下面的Type同)
- 消息類型。如下圖,左邊是普通的對話消息,右邊類似於系統提示消息。是不是可以根據這條信息來判斷是不是有好友撤回瞭消息?
Content
消息內容,註意與下面的Text區分,這兩種消息類型在內容上最大的區別可能就在這裡瞭。
來看一下撤回消息的Content是怎麼樣的(為瞭便於查看,已經經過格式化)
<sysmsg type="revokemsg"> <revokemsg> <session>wxid_4gngrr04aqjn21</session> <oldmsgid>1123721956</oldmsgid> <msgid>2018511155698964390</msgid> <replacemsg><![CDATA["小幫幫" 撤回瞭一條消息]]></replacemsg> </revokemsg> </sysmsg>
一眼就能發現關鍵點:撤回的那條消息屬於系統消息(sysmsg
),類型是撤回消息(revokemsg
),對應的消息編號是2018511155698964390
。
細心的讀者已經發現,這個消息編號正好就是左邊那條消息的編號。
通過這個推理,猜測Content
字段是系統內部傳輸的內容,而Text字段則是用戶看到的內容。
三、確定消息類型
根據上述分析,有三個地方幫助確定收到的某條信息是否是撤回的消息:
1.MsgType
是1就是普通消息,是10002則可能為撤回消息。
2.Content
如果Content裡有包含type="revokemsg"
則可能為撤回消息,否則不是撤回消息。
3.Type
是Text就是普通消息,是Note則可能為撤回消息。
精確起見,消息還要同時滿足上面三種情況才可認定為撤回消息。
四、鎖定撤回的消息
由於要鎖定撤回消息必須要MsgId
才能確定,所以在存儲臨時消息時需要加上這一字段。
log[sender_name][cur_timestamp] = msg['MsgId'] + '|||' + content
為瞭簡化數據復雜度,我通過分隔符|||
直接把MsgId
加在前面。
於是,鎖定並發送撤回消息的代碼就時這樣:
content = str(msg['Text']) revoke_info = msg['Content'] print('{}, {} 發來消息: {}'.format(formatted_timestamp, sender_name, content)) target_msg_pattern = '"{}" 撤回瞭一條消息'.format(sender_name) if target_msg_pattern == content and msg['Type'] == 'Note' and str(msg['MsgType']) == '10002' and 'type="revokemsg"' in revoke_info: return_msg = '' return_msg_head = '{},【{}】撤回瞭一條消息:\n'.format(formatted_timestamp, sender_name) revoke_msg_id = revoke_info.split('<msgid>')[-1].split('</msgid>')[0] for _, value in log[sender_name].items(): if value.split('|||')[0] == revoke_msg_id: return_msg = value.split('|||')[1] if return_msg == '': return_msg = '緩存信息列表為空!' return_msg = return_msg_head + return_msg print(return_msg) itchat.send_msg(return_msg, 'filehelper')
測試一下,為便於查看,將撤回提醒直接發給機器人“小幫幫”
一個完美的微信防撤回腳本大功告成!
五、結語
Python有很多好用好玩的庫,可以慢慢發掘。本期我們利用ItChat
庫編寫瞭一個微信防撤回腳本。其實ItChat
功能遠遠不止這些,它還可以處理微信群消息以及各種其他類型的消息,我們講到的隻是九牛一毛,更多的還要大傢自己去探索。
到此這篇關於撤回我也能看到!教你用Python制作微信防撤回腳本的文章就介紹到這瞭,更多相關Python微信防撤回腳本內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MySQL REVOKE實現刪除用戶權限
- C++示例講解觀察者設計模式
- 三分鐘python搭建支付寶三方支付
- python–字典(dict)和集合(set)詳解
- python庫JsonSchema驗證JSON數據結構使用詳解