撤回我也能看到!教你用Python制作微信防撤回腳本
一、之前解決方案
大概是這樣:短時(shí)間內(nèi)同一位好友發(fā)送了多條消息,當(dāng)他隨便撤回一條消息時(shí),我們不能確定他到底撤回的到底是哪一條消息。只能猜他可能是撤回了最近的一條消息,然后將其他消息貼出來(lái)作為備選。代碼如下:
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)
實(shí)際效果是這樣:

我這個(gè)強(qiáng)迫癥簡(jiǎn)直受不了這么不確定的說(shuō)法。
二、分析msg信息
要想確定撤回了哪一條信息,就必須先熟悉普通msg和撤回的msg里面都有哪些信息,他們的相同點(diǎn)和不同點(diǎn)。下面就來(lái)看看這兩種情況下msg都是怎么樣的,不需要仔細(xì)的看每一行,后面會(huì)作具體分析。
先是用機(jī)器人“小幫幫”發(fā)送過(guò)來(lái)的信息得到的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': '臺(tái)州',
'Alias': '',
'SnsFlag': 17,
'UniFriend': 0,
'DisplayName': '',
'ChatRoomId': 0,
'KeyWord': '',
'EncryChatRoomId': '',
'IsOwner': 0
} > ,
'Type': 'Text',
'Text': 'msg里面到底有什么?'
}
下面是機(jī)器人撤回剛才的信息得到的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': '臺(tái)州',
'Alias': '',
'SnsFlag': 17,
'UniFriend': 0,
'DisplayName': '',
'ChatRoomId': 0,
'KeyWord': '',
'EncryChatRoomId': '',
'IsOwner': 0
} > ,
'Type': 'Note',
'Text': '"小幫幫" 撤回了一條消息'
}
得到了兩種類(lèi)型的msg,下面是對(duì)比(高亮的部分是不同處,省略了部分相同內(nèi)容。可以點(diǎn)擊放大查看大圖

現(xiàn)在來(lái)分析幾條關(guān)鍵信息:
- MsgId(與下面的NewMsgId同)
- 消息編號(hào)。這個(gè)很好理解,每條消息都是通過(guò)一個(gè)獨(dú)一無(wú)二的編號(hào)來(lái)與其他消息區(qū)分,所以這兩條消息的編號(hào)不同很正常。如果我們能拿到好友撤回消息的編號(hào),也就能鎖定這條消息了。
- MsgType(與下面的Type同)
- 消息類(lèi)型。如下圖,左邊是普通的對(duì)話消息,右邊類(lèi)似于系統(tǒng)提示消息。是不是可以根據(jù)這條信息來(lái)判斷是不是有好友撤回了消息?

Content
消息內(nèi)容,注意與下面的Text區(qū)分,這兩種消息類(lèi)型在內(nèi)容上最大的區(qū)別可能就在這里了。
來(lái)看一下撤回消息的Content是怎么樣的(為了便于查看,已經(jīng)經(jīng)過(guò)格式化)
<sysmsg type="revokemsg"> <revokemsg> <session>wxid_4gngrr04aqjn21</session> <oldmsgid>1123721956</oldmsgid> <msgid>2018511155698964390</msgid> <replacemsg><![CDATA["小幫幫" 撤回了一條消息]]></replacemsg> </revokemsg> </sysmsg>
一眼就能發(fā)現(xiàn)關(guān)鍵點(diǎn):撤回的那條消息屬于系統(tǒng)消息(sysmsg),類(lèi)型是撤回消息(revokemsg),對(duì)應(yīng)的消息編號(hào)是2018511155698964390。
細(xì)心的讀者已經(jīng)發(fā)現(xiàn),這個(gè)消息編號(hào)正好就是左邊那條消息的編號(hào)。
通過(guò)這個(gè)推理,猜測(cè)Content字段是系統(tǒng)內(nèi)部傳輸?shù)膬?nèi)容,而Text字段則是用戶看到的內(nèi)容。
三、確定消息類(lèi)型
根據(jù)上述分析,有三個(gè)地方幫助確定收到的某條信息是否是撤回的消息:
1.MsgType
是1就是普通消息,是10002則可能為撤回消息。
2.Content
如果Content里有包含type="revokemsg"則可能為撤回消息,否則不是撤回消息。
3.Type
是Text就是普通消息,是Note則可能為撤回消息。
精確起見(jiàn),消息還要同時(shí)滿足上面三種情況才可認(rèn)定為撤回消息。
四、鎖定撤回的消息
由于要鎖定撤回消息必須要MsgId才能確定,所以在存儲(chǔ)臨時(shí)消息時(shí)需要加上這一字段。
log[sender_name][cur_timestamp] = msg['MsgId'] + '|||' + content
為了簡(jiǎn)化數(shù)據(jù)復(fù)雜度,我通過(guò)分隔符|||直接把MsgId加在前面。
于是,鎖定并發(fā)送撤回消息的代碼就時(shí)這樣:
content = str(msg['Text'])
revoke_info = msg['Content']
print('{}, {} 發(fā)來(lái)消息: {}'.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')
測(cè)試一下,為便于查看,將撤回提醒直接發(fā)給機(jī)器人“小幫幫”

一個(gè)完美的微信防撤回腳本大功告成!
五、結(jié)語(yǔ)
Python有很多好用好玩的庫(kù),可以慢慢發(fā)掘。本期我們利用ItChat庫(kù)編寫(xiě)了一個(gè)微信防撤回腳本。其實(shí)ItChat功能遠(yuǎn)遠(yuǎn)不止這些,它還可以處理微信群消息以及各種其他類(lèi)型的消息,我們講到的只是九牛一毛,更多的還要大家自己去探索。
到此這篇關(guān)于撤回我也能看到!教你用Python制作微信防撤回腳本的文章就介紹到這了,更多相關(guān)Python微信防撤回腳本內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。
關(guān)注官方微信