├── .idea ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── tmp_crawler.iml └── workspace.xml ├── Config ├── __pycache__ │ ├── database.cpython-38.pyc │ ├── pdd.cpython-38.pyc │ └── wx.cpython-38.pyc ├── database.py ├── pdd.py └── wx.py ├── Library └── PyWeChatSpy │ ├── 1660944441 │ └── WeChatSpy3.0.dll │ ├── SpyK.exe │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-38.pyc │ ├── command.cpython-38.pyc │ └── spy.cpython-38.pyc │ ├── command.py │ ├── games │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ └── truth_or_dare.cpython-38.pyc │ └── truth_or_dare.py │ ├── proto │ ├── __pycache__ │ │ ├── spy_pb2.cpython-38.pyc │ │ └── wx_pb2.cpython-38.pyc │ ├── spy_pb2.py │ └── wx_pb2.py │ ├── service │ ├── API.md │ ├── __init__.py │ ├── app.py │ └── config.py │ └── spy.py ├── Logs └── spy.log ├── README.md ├── Temp ├── WeChatSetup-3.0.0.57.exe ├── crawler.sql ├── pdd_last_order_ask.py └── wx_robot_image │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4-1.jpg │ ├── 4.jpg │ ├── 5-1.jpg │ ├── 5.jpg │ └── 6.jpg ├── boot.bat ├── pdd.py └── wx_robot.py /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/tmp_crawler.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 42 | 43 | 44 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 1617758326046 77 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Config/__pycache__/database.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Config/__pycache__/database.cpython-38.pyc -------------------------------------------------------------------------------- /Config/__pycache__/pdd.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Config/__pycache__/pdd.cpython-38.pyc -------------------------------------------------------------------------------- /Config/__pycache__/wx.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Config/__pycache__/wx.cpython-38.pyc -------------------------------------------------------------------------------- /Config/database.py: -------------------------------------------------------------------------------- 1 | MYSQL = { 2 | 'host': "localhost", 3 | 'user': "root", 4 | 'pass': "root", 5 | 'database': "blog" 6 | } 7 | 8 | REDIS = { 9 | 'host': '127.0.0.1', 10 | 'port': 6379 11 | } 12 | -------------------------------------------------------------------------------- /Config/pdd.py: -------------------------------------------------------------------------------- 1 | # 立即回复话术 2 | reply_common = "亲您好,在的哦" 3 | 4 | # 是否立即回复、循环的间隔秒数 5 | reply_at_one = False 6 | time_sleep = 3 7 | 8 | # 定义角色 9 | seller_role = 'mall_cs' 10 | buyer_role = 'user' 11 | 12 | # 最近联系人 13 | talk_people_url = "https://mms.pinduoduo.com/plateau/chat/latest_conversations" 14 | # 聊天框的最近聊天内容 15 | talk_list_url = "https://mms.pinduoduo.com/plateau/chat/list" 16 | # 发送聊天消息 17 | send_msg_url = "https://mms.pinduoduo.com/plateau/chat/send_message" 18 | 19 | # 上面不同接口请求结果中,主要数据标识 20 | data_mark = {"latest_conversations": "conversations", "list": "messages", "send_message": "msg_id"} -------------------------------------------------------------------------------- /Config/wx.py: -------------------------------------------------------------------------------- 1 | wx_exe_path = r"D:\Program Files (x86)\Tencent\WeChat2\WeChat\WeChat.exe" 2 | 3 | WECHAT_PROFILE = rf"D:\Documents\Tencent\WeChat Files" 4 | PATCH_PATH = rf"C:\Users\zhou.3491\AppData\Roaming\Tencent\WeChat\patch" # os.environ['USERNAME'] 5 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/1660944441/WeChatSpy3.0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/1660944441/WeChatSpy3.0.dll -------------------------------------------------------------------------------- /Library/PyWeChatSpy/SpyK.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/SpyK.exe -------------------------------------------------------------------------------- /Library/PyWeChatSpy/__init__.py: -------------------------------------------------------------------------------- 1 | from .spy import WeChatSpy 2 | # ,-.----. 3 | # \ / \ .---. ,----.. ,---, ___ .--.--. 4 | # | : \ /. ./| / / \,--.' | ,--.'|_ / / '.,-.----. 5 | # | | .\ : .--'. ' ; | : | | : | | :,'| : /`. /\ / \ 6 | # . : |: | /__./ \ : | . | ;. : : : : : ' :; | |--` | : | 7 | # | | \ : .--,.--'. ' \' . ,---. . ; /--`: | |,--. ,--.--. .;__,' / | : ;_ | | .\ : .--, 8 | # | : . / /_ .//___/ \ | ' ' / \; | ; | : ' |/ \| | | \ \ `.. : |: | /_ ./| 9 | # ; | |`-, ' , ' ; \ \; :/ / | : | | | /' .--. .-. :__,'| : `----. | | \ :, ' , ' : 10 | # | | ; /___/ \: |\ ; ` . ' / . | '___' : | | |\__\/: . . ' : |__ __ \ \ | : . /___/ \: | 11 | # : ' | . \ ' | . \ .\ ' ; /' ; : .'| | ' | :," .--.; | | | '.'|/ /`--' : |`-'. \ ' | 12 | # : : : \ ; : \ \ ' \ ' | / ' | '/ | : :_:,/ / ,. | ; : '--'. /: : : \ ; : 13 | # | | : \ \ ; : ' |--"| : | : /| | ,' ; : .' \| , / `--'---' | | : \ \ ; 14 | # `---'.| : \ \ \ \ ; \ \ / \ \ .' `--'' | , .-./ ---`-' `---'.| : \ \ 15 | # `---` \ ' ; '---" `----' `---` `--`---' `---` \ ' ; 16 | # `--` `--` 17 | WECHAT_SUPPORTED = ["3.0.0.57"] 18 | 19 | __version__ = "3.1.10.4" 20 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/__pycache__/command.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/__pycache__/command.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/__pycache__/spy.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/__pycache__/spy.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/command.py: -------------------------------------------------------------------------------- 1 | PROFESSIONAL_KEY = 9527 # 系统设置 2 | WECHAT_CONNECTED = 100 # socket连接 3 | HEART_BEAT = 101 # 心跳 4 | WECHAT_DISCONNECT = 102 # socket断开 5 | WECHAT_LOGIN = 200 # 微信登录 6 | WECHAT_LOGOUT = 201 # 微信登出 7 | CHAT_MESSAGE = 202 # 聊天消息 8 | GROUP_MEMBER_DETAILS = 203 # 群成员详情 9 | GROUP_MEMBER_EVENT = 204 # 群成员变动 10 | GET_ACCOUNT_DETAILS = 300 # 账号详情 11 | GET_CONTACTS_LIST = 301 # 联系人列表 12 | GET_CONTACT_DETAILS = 302 # 联系人详情 13 | SEND_TEXT = 303 14 | SEND_FILE = 304 15 | USER_LOGOUT = 305 16 | SEND_ANNOUNCEMENT = 306 17 | ACCEPT_NEW_CONTACT = 307 18 | SET_REMARK = 308 19 | SHARE_CHATROOM = 309 20 | REMOVE_CHATROOM_MEMBER = 310 21 | REMOVE_CONTACT = 311 22 | SEND_MINI_PROGRAM = 312 23 | SEND_LINK_CARD = 313 24 | DECRYPT_IMAGE = 314 25 | CREATE_CHATROOM = 315 26 | SET_CHATROOM_NAME = 316 27 | GET_CONTACT_STATUS = 317 28 | GET_LOGIN_QRCODE = 318 29 | SEND_CARD = 319 30 | GET_GROUP_ENTER_URL = 320 31 | ACCOUNT_DETAILS = 400 32 | CONTACTS_LIST = 401 33 | CONTACT_DETAILS = 402 34 | CREATE_GROUP_CALLBACK = 403 35 | LOGIN_QRCODE = 404 36 | GROUP_ENTER_URL = 405 37 | SEND_TEXT_CALLBACK = 406 38 | SEND_XML_CALLBACK = 407 39 | SEND_IMAGE_CALLBACK = 408 40 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/games/__init__.py: -------------------------------------------------------------------------------- 1 | from .truth_or_dare import TruthOrDare 2 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/games/__pycache__/__init__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/games/__pycache__/__init__.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/games/__pycache__/truth_or_dare.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/games/__pycache__/truth_or_dare.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/games/truth_or_dare.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | from ..command import CHAT_MESSAGE, CONTACT_DETAILS 3 | from ..proto import spy_pb2 4 | from ..spy import WeChatSpy 5 | from lxml import etree 6 | 7 | 8 | class TruthOrDare: 9 | def __init__(self, spy: WeChatSpy): 10 | self.spy = spy 11 | self.admin = None 12 | self.group = None 13 | self.group_member = dict() 14 | self.count = 0 15 | self.records = [] 16 | self.record = dict() 17 | self.ask = [] 18 | self.answer = [] 19 | 20 | def game(self, func): 21 | @wraps(func) 22 | def wrapper(data): 23 | if data.type == CHAT_MESSAGE: 24 | chat_message = spy_pb2.ChatMessage() 25 | chat_message.ParseFromString(data.bytes) 26 | for message in chat_message.message: 27 | _type = message.type # 消息类型 1.文本|3.图片...自行探索 28 | _from = message.wxidFrom.str # 消息发送方 29 | _to = message.wxidTo.str # 消息接收方 30 | # if _to == "filehelper": 31 | # print(message) 32 | content = message.content.str # 消息内容 33 | _from_group_member = "" 34 | if _from.endswith("@chatroom"): # 群聊消息 35 | _from_group_member = message.content.str.split(':\n', 1)[0] # 群内发言人 36 | content = message.content.str.split(':\n', 1)[-1] # 群聊消息内容 37 | if _type == 1: # 文本消息 38 | if not self.group and content == "真心话大冒险": 39 | self.admin = _from_group_member 40 | if _from_group_member == "": 41 | self.group = _to 42 | else: 43 | self.group = _from 44 | self.spy.get_contact_details(self.group) 45 | elif self.admin == _from_group_member: 46 | if content == "开始": 47 | self.count += 1 48 | self.record.clear() 49 | self.ask.clear() 50 | self.answer.clear() 51 | self.spy.send_text(self.group, f"第{self.count}轮游戏开始,请掷骰子") 52 | elif content == "结算": 53 | values = self.record.values() 54 | _max = max(values) 55 | _min = min(values) 56 | for k, v in self.record.items(): 57 | if v == _max: 58 | self.ask.append(k) 59 | elif v == _min: 60 | self.answer.append(k) 61 | ask = answer = "" 62 | for w in self.ask: 63 | ask += f"{self.group_member[w]} " 64 | # w_ask = ",".join(self.ask) 65 | for w in self.answer: 66 | answer = f"{self.group_member[w]} " 67 | # w_answer = ",".join(self.answer) 68 | message = f"第{self.count}轮游戏结算,请{ask}向{answer}提问" 69 | self.spy.send_text(self.group, message) 70 | elif _type == 47: 71 | if _from == self.group or _to == self.group: 72 | xml = etree.XML(content) 73 | game_type = xml.xpath("/msg/gameext/@type")[0] 74 | if game_type == "2": # 骰子游戏 75 | fromusername = xml.xpath("/msg/emoji/@fromusername")[0] 76 | value = int(xml.xpath("/msg/gameext/@content")[0]) - 3 77 | if not self.record.get(fromusername): 78 | self.record[fromusername] = value 79 | elif data.type == CONTACT_DETAILS: 80 | contact_details_list = spy_pb2.Contacts() 81 | contact_details_list.ParseFromString(data.bytes) 82 | for contact_details in contact_details_list.contactDetails: # 遍历联系人详情 83 | wxid = contact_details.wxid.str # 联系人wxid 84 | if wxid == self.group: 85 | # nickname = contact_details.nickname.str # 联系人昵称 86 | # remark = contact_details.remark.str # 联系人备注 87 | group_member_list = contact_details.groupMemberList # 群成员列表 88 | member_count = group_member_list.memberCount # 群成员数量 89 | for group_member in group_member_list.groupMember: # 遍历群成员 90 | member_wxid = group_member.wxid # 群成员wxid 91 | member_nickname = group_member.nickname # 群成员昵称 92 | self.group_member[member_wxid] = member_nickname 93 | self.spy.send_text( 94 | self.group, f"游戏成员[{member_count}]加载完成,游戏准备就绪,请管理员发送'开始'开始游戏,发送'结算'结算此轮游戏") 95 | func(data) 96 | return wrapper 97 | 98 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/proto/__pycache__/spy_pb2.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/proto/__pycache__/spy_pb2.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/proto/__pycache__/wx_pb2.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Library/PyWeChatSpy/proto/__pycache__/wx_pb2.cpython-38.pyc -------------------------------------------------------------------------------- /Library/PyWeChatSpy/proto/spy_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: spy.proto 4 | 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | # import wx_pb2 as wx__pb2 15 | from . import wx_pb2 as wx__pb2 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='spy.proto', 20 | package='spy', 21 | syntax='proto3', 22 | serialized_options=None, 23 | serialized_pb=b'\n\tspy.proto\x12\x03spy\x1a\x08wx.proto\"/\n\x0b\x43hatMessage\x12 \n\x07message\x18\x01 \x03(\x0b\x32\x0f.wx.ChatMessage\"\xeb\x01\n\x0e\x41\x63\x63ountDetails\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x10\n\x08nickname\x18\x02 \x01(\t\x12\x10\n\x08wechatid\x18\x03 \x01(\t\x12\x11\n\tautograph\x18\x04 \x01(\t\x12\x16\n\x0eprofilePhotoHD\x18\x05 \x01(\t\x12\x14\n\x0cprofilePhoto\x18\x06 \x01(\t\x12\r\n\x05phone\x18\x07 \x01(\t\x12\r\n\x05\x65mail\x18\x08 \x01(\t\x12\n\n\x02qq\x18\t \x01(\x03\x12\x0b\n\x03sex\x18\n \x01(\x05\x12\x0c\n\x04\x63ity\x18\x0b \x01(\t\x12\x10\n\x08province\x18\x0c \x01(\t\x12\x0f\n\x07\x63ountry\x18\r \x01(\t\"6\n\x08\x43ontacts\x12*\n\x0e\x63ontactDetails\x18\x01 \x03(\x0b\x32\x12.wx.ContactDetails\"9\n\x0bTextMessage\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x0e\n\x06wxidAt\x18\x02 \x01(\t\x12\x0c\n\x04text\x18\x03 \x01(\t\"-\n\x0b\x46ileMessage\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x10\n\x08\x66ilePath\x18\x02 \x01(\t\"\xae\x01\n\nXmlMessage\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x65sc\x18\x03 \x01(\t\x12\r\n\x05\x61ppId\x18\x04 \x01(\t\x12\r\n\x05route\x18\x05 \x01(\t\x12\x0b\n\x03url\x18\x06 \x01(\t\x12\x11\n\timagePath\x18\x07 \x01(\t\x12\x10\n\x08username\x18\x08 \x01(\t\x12\x14\n\x0cweappiconurl\x18\t \x01(\t\x12\x0f\n\x07\x61ppname\x18\n \x01(\t\"=\n\x12\x43ontactApplication\x12\x17\n\x0f\x65ncryptusername\x18\x01 \x01(\t\x12\x0e\n\x06ticket\x18\x02 \x01(\t\"m\n\x08Response\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04port\x18\x04 \x01(\x05\x12\n\n\x02id\x18\x05 \x01(\t\x12\x0c\n\x04\x63ode\x18\x06 \x01(\x05\x12\x0f\n\x07message\x18\x07 \x01(\t\"2\n\x07Request\x12\x0c\n\x04type\x18\x01 \x01(\x05\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c\x12\n\n\x02id\x18\x03 \x01(\t\"d\n\x13\x43reateGroupCallback\x12\x1e\n\x04wxid\x18\x01 \x01(\x0b\x32\x10.wx.WeChatString\x12-\n\nmemberData\x18\x02 \x03(\x0b\x32\x19.wx.CreateGroupMemberData\"l\n\x12GroupMemberDetails\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x65tailsCount\x18\x02 \x01(\x05\x12\x32\n\x12groupMemberDetails\x18\x03 \x03(\x0b\x32\x16.wx.GroupMemberDetails\"E\n\x10GroupMemberEvent\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x10\n\x08wxidJoin\x18\x02 \x03(\t\x12\x11\n\twxidLeave\x18\x03 \x03(\t\"6\n\x0bLoginQRCode\x12\x12\n\nqrcodeSize\x18\x01 \x01(\x05\x12\x13\n\x0bqrcodeBytes\x18\x02 \x01(\x0c\"\x1c\n\rGroupEnterUrl\x12\x0b\n\x03url\x18\x02 \x01(\tb\x06proto3' 24 | , 25 | dependencies=[wx__pb2.DESCRIPTOR,]) 26 | 27 | 28 | 29 | 30 | _CHATMESSAGE = _descriptor.Descriptor( 31 | name='ChatMessage', 32 | full_name='spy.ChatMessage', 33 | filename=None, 34 | file=DESCRIPTOR, 35 | containing_type=None, 36 | fields=[ 37 | _descriptor.FieldDescriptor( 38 | name='message', full_name='spy.ChatMessage.message', index=0, 39 | number=1, type=11, cpp_type=10, label=3, 40 | has_default_value=False, default_value=[], 41 | message_type=None, enum_type=None, containing_type=None, 42 | is_extension=False, extension_scope=None, 43 | serialized_options=None, file=DESCRIPTOR), 44 | ], 45 | extensions=[ 46 | ], 47 | nested_types=[], 48 | enum_types=[ 49 | ], 50 | serialized_options=None, 51 | is_extendable=False, 52 | syntax='proto3', 53 | extension_ranges=[], 54 | oneofs=[ 55 | ], 56 | serialized_start=28, 57 | serialized_end=75, 58 | ) 59 | 60 | 61 | _ACCOUNTDETAILS = _descriptor.Descriptor( 62 | name='AccountDetails', 63 | full_name='spy.AccountDetails', 64 | filename=None, 65 | file=DESCRIPTOR, 66 | containing_type=None, 67 | fields=[ 68 | _descriptor.FieldDescriptor( 69 | name='wxid', full_name='spy.AccountDetails.wxid', index=0, 70 | number=1, type=9, cpp_type=9, label=1, 71 | has_default_value=False, default_value=b"".decode('utf-8'), 72 | message_type=None, enum_type=None, containing_type=None, 73 | is_extension=False, extension_scope=None, 74 | serialized_options=None, file=DESCRIPTOR), 75 | _descriptor.FieldDescriptor( 76 | name='nickname', full_name='spy.AccountDetails.nickname', index=1, 77 | number=2, type=9, cpp_type=9, label=1, 78 | has_default_value=False, default_value=b"".decode('utf-8'), 79 | message_type=None, enum_type=None, containing_type=None, 80 | is_extension=False, extension_scope=None, 81 | serialized_options=None, file=DESCRIPTOR), 82 | _descriptor.FieldDescriptor( 83 | name='wechatid', full_name='spy.AccountDetails.wechatid', index=2, 84 | number=3, type=9, cpp_type=9, label=1, 85 | has_default_value=False, default_value=b"".decode('utf-8'), 86 | message_type=None, enum_type=None, containing_type=None, 87 | is_extension=False, extension_scope=None, 88 | serialized_options=None, file=DESCRIPTOR), 89 | _descriptor.FieldDescriptor( 90 | name='autograph', full_name='spy.AccountDetails.autograph', index=3, 91 | number=4, type=9, cpp_type=9, label=1, 92 | has_default_value=False, default_value=b"".decode('utf-8'), 93 | message_type=None, enum_type=None, containing_type=None, 94 | is_extension=False, extension_scope=None, 95 | serialized_options=None, file=DESCRIPTOR), 96 | _descriptor.FieldDescriptor( 97 | name='profilePhotoHD', full_name='spy.AccountDetails.profilePhotoHD', index=4, 98 | number=5, type=9, cpp_type=9, label=1, 99 | has_default_value=False, default_value=b"".decode('utf-8'), 100 | message_type=None, enum_type=None, containing_type=None, 101 | is_extension=False, extension_scope=None, 102 | serialized_options=None, file=DESCRIPTOR), 103 | _descriptor.FieldDescriptor( 104 | name='profilePhoto', full_name='spy.AccountDetails.profilePhoto', index=5, 105 | number=6, type=9, cpp_type=9, label=1, 106 | has_default_value=False, default_value=b"".decode('utf-8'), 107 | message_type=None, enum_type=None, containing_type=None, 108 | is_extension=False, extension_scope=None, 109 | serialized_options=None, file=DESCRIPTOR), 110 | _descriptor.FieldDescriptor( 111 | name='phone', full_name='spy.AccountDetails.phone', index=6, 112 | number=7, type=9, cpp_type=9, label=1, 113 | has_default_value=False, default_value=b"".decode('utf-8'), 114 | message_type=None, enum_type=None, containing_type=None, 115 | is_extension=False, extension_scope=None, 116 | serialized_options=None, file=DESCRIPTOR), 117 | _descriptor.FieldDescriptor( 118 | name='email', full_name='spy.AccountDetails.email', index=7, 119 | number=8, type=9, cpp_type=9, label=1, 120 | has_default_value=False, default_value=b"".decode('utf-8'), 121 | message_type=None, enum_type=None, containing_type=None, 122 | is_extension=False, extension_scope=None, 123 | serialized_options=None, file=DESCRIPTOR), 124 | _descriptor.FieldDescriptor( 125 | name='qq', full_name='spy.AccountDetails.qq', index=8, 126 | number=9, type=3, cpp_type=2, label=1, 127 | has_default_value=False, default_value=0, 128 | message_type=None, enum_type=None, containing_type=None, 129 | is_extension=False, extension_scope=None, 130 | serialized_options=None, file=DESCRIPTOR), 131 | _descriptor.FieldDescriptor( 132 | name='sex', full_name='spy.AccountDetails.sex', index=9, 133 | number=10, type=5, cpp_type=1, label=1, 134 | has_default_value=False, default_value=0, 135 | message_type=None, enum_type=None, containing_type=None, 136 | is_extension=False, extension_scope=None, 137 | serialized_options=None, file=DESCRIPTOR), 138 | _descriptor.FieldDescriptor( 139 | name='city', full_name='spy.AccountDetails.city', index=10, 140 | number=11, type=9, cpp_type=9, label=1, 141 | has_default_value=False, default_value=b"".decode('utf-8'), 142 | message_type=None, enum_type=None, containing_type=None, 143 | is_extension=False, extension_scope=None, 144 | serialized_options=None, file=DESCRIPTOR), 145 | _descriptor.FieldDescriptor( 146 | name='province', full_name='spy.AccountDetails.province', index=11, 147 | number=12, type=9, cpp_type=9, label=1, 148 | has_default_value=False, default_value=b"".decode('utf-8'), 149 | message_type=None, enum_type=None, containing_type=None, 150 | is_extension=False, extension_scope=None, 151 | serialized_options=None, file=DESCRIPTOR), 152 | _descriptor.FieldDescriptor( 153 | name='country', full_name='spy.AccountDetails.country', index=12, 154 | number=13, type=9, cpp_type=9, label=1, 155 | has_default_value=False, default_value=b"".decode('utf-8'), 156 | message_type=None, enum_type=None, containing_type=None, 157 | is_extension=False, extension_scope=None, 158 | serialized_options=None, file=DESCRIPTOR), 159 | ], 160 | extensions=[ 161 | ], 162 | nested_types=[], 163 | enum_types=[ 164 | ], 165 | serialized_options=None, 166 | is_extendable=False, 167 | syntax='proto3', 168 | extension_ranges=[], 169 | oneofs=[ 170 | ], 171 | serialized_start=78, 172 | serialized_end=313, 173 | ) 174 | 175 | 176 | _CONTACTS = _descriptor.Descriptor( 177 | name='Contacts', 178 | full_name='spy.Contacts', 179 | filename=None, 180 | file=DESCRIPTOR, 181 | containing_type=None, 182 | fields=[ 183 | _descriptor.FieldDescriptor( 184 | name='contactDetails', full_name='spy.Contacts.contactDetails', index=0, 185 | number=1, type=11, cpp_type=10, label=3, 186 | has_default_value=False, default_value=[], 187 | message_type=None, enum_type=None, containing_type=None, 188 | is_extension=False, extension_scope=None, 189 | serialized_options=None, file=DESCRIPTOR), 190 | ], 191 | extensions=[ 192 | ], 193 | nested_types=[], 194 | enum_types=[ 195 | ], 196 | serialized_options=None, 197 | is_extendable=False, 198 | syntax='proto3', 199 | extension_ranges=[], 200 | oneofs=[ 201 | ], 202 | serialized_start=315, 203 | serialized_end=369, 204 | ) 205 | 206 | 207 | _TEXTMESSAGE = _descriptor.Descriptor( 208 | name='TextMessage', 209 | full_name='spy.TextMessage', 210 | filename=None, 211 | file=DESCRIPTOR, 212 | containing_type=None, 213 | fields=[ 214 | _descriptor.FieldDescriptor( 215 | name='wxid', full_name='spy.TextMessage.wxid', index=0, 216 | number=1, type=9, cpp_type=9, label=1, 217 | has_default_value=False, default_value=b"".decode('utf-8'), 218 | message_type=None, enum_type=None, containing_type=None, 219 | is_extension=False, extension_scope=None, 220 | serialized_options=None, file=DESCRIPTOR), 221 | _descriptor.FieldDescriptor( 222 | name='wxidAt', full_name='spy.TextMessage.wxidAt', index=1, 223 | number=2, type=9, cpp_type=9, label=1, 224 | has_default_value=False, default_value=b"".decode('utf-8'), 225 | message_type=None, enum_type=None, containing_type=None, 226 | is_extension=False, extension_scope=None, 227 | serialized_options=None, file=DESCRIPTOR), 228 | _descriptor.FieldDescriptor( 229 | name='text', full_name='spy.TextMessage.text', index=2, 230 | number=3, type=9, cpp_type=9, label=1, 231 | has_default_value=False, default_value=b"".decode('utf-8'), 232 | message_type=None, enum_type=None, containing_type=None, 233 | is_extension=False, extension_scope=None, 234 | serialized_options=None, file=DESCRIPTOR), 235 | ], 236 | extensions=[ 237 | ], 238 | nested_types=[], 239 | enum_types=[ 240 | ], 241 | serialized_options=None, 242 | is_extendable=False, 243 | syntax='proto3', 244 | extension_ranges=[], 245 | oneofs=[ 246 | ], 247 | serialized_start=371, 248 | serialized_end=428, 249 | ) 250 | 251 | 252 | _FILEMESSAGE = _descriptor.Descriptor( 253 | name='FileMessage', 254 | full_name='spy.FileMessage', 255 | filename=None, 256 | file=DESCRIPTOR, 257 | containing_type=None, 258 | fields=[ 259 | _descriptor.FieldDescriptor( 260 | name='wxid', full_name='spy.FileMessage.wxid', index=0, 261 | number=1, type=9, cpp_type=9, label=1, 262 | has_default_value=False, default_value=b"".decode('utf-8'), 263 | message_type=None, enum_type=None, containing_type=None, 264 | is_extension=False, extension_scope=None, 265 | serialized_options=None, file=DESCRIPTOR), 266 | _descriptor.FieldDescriptor( 267 | name='filePath', full_name='spy.FileMessage.filePath', index=1, 268 | number=2, type=9, cpp_type=9, label=1, 269 | has_default_value=False, default_value=b"".decode('utf-8'), 270 | message_type=None, enum_type=None, containing_type=None, 271 | is_extension=False, extension_scope=None, 272 | serialized_options=None, file=DESCRIPTOR), 273 | ], 274 | extensions=[ 275 | ], 276 | nested_types=[], 277 | enum_types=[ 278 | ], 279 | serialized_options=None, 280 | is_extendable=False, 281 | syntax='proto3', 282 | extension_ranges=[], 283 | oneofs=[ 284 | ], 285 | serialized_start=430, 286 | serialized_end=475, 287 | ) 288 | 289 | 290 | _XMLMESSAGE = _descriptor.Descriptor( 291 | name='XmlMessage', 292 | full_name='spy.XmlMessage', 293 | filename=None, 294 | file=DESCRIPTOR, 295 | containing_type=None, 296 | fields=[ 297 | _descriptor.FieldDescriptor( 298 | name='wxid', full_name='spy.XmlMessage.wxid', index=0, 299 | number=1, type=9, cpp_type=9, label=1, 300 | has_default_value=False, default_value=b"".decode('utf-8'), 301 | message_type=None, enum_type=None, containing_type=None, 302 | is_extension=False, extension_scope=None, 303 | serialized_options=None, file=DESCRIPTOR), 304 | _descriptor.FieldDescriptor( 305 | name='title', full_name='spy.XmlMessage.title', index=1, 306 | number=2, type=9, cpp_type=9, label=1, 307 | has_default_value=False, default_value=b"".decode('utf-8'), 308 | message_type=None, enum_type=None, containing_type=None, 309 | is_extension=False, extension_scope=None, 310 | serialized_options=None, file=DESCRIPTOR), 311 | _descriptor.FieldDescriptor( 312 | name='desc', full_name='spy.XmlMessage.desc', index=2, 313 | number=3, type=9, cpp_type=9, label=1, 314 | has_default_value=False, default_value=b"".decode('utf-8'), 315 | message_type=None, enum_type=None, containing_type=None, 316 | is_extension=False, extension_scope=None, 317 | serialized_options=None, file=DESCRIPTOR), 318 | _descriptor.FieldDescriptor( 319 | name='appId', full_name='spy.XmlMessage.appId', index=3, 320 | number=4, type=9, cpp_type=9, label=1, 321 | has_default_value=False, default_value=b"".decode('utf-8'), 322 | message_type=None, enum_type=None, containing_type=None, 323 | is_extension=False, extension_scope=None, 324 | serialized_options=None, file=DESCRIPTOR), 325 | _descriptor.FieldDescriptor( 326 | name='route', full_name='spy.XmlMessage.route', index=4, 327 | number=5, type=9, cpp_type=9, label=1, 328 | has_default_value=False, default_value=b"".decode('utf-8'), 329 | message_type=None, enum_type=None, containing_type=None, 330 | is_extension=False, extension_scope=None, 331 | serialized_options=None, file=DESCRIPTOR), 332 | _descriptor.FieldDescriptor( 333 | name='url', full_name='spy.XmlMessage.url', index=5, 334 | number=6, type=9, cpp_type=9, label=1, 335 | has_default_value=False, default_value=b"".decode('utf-8'), 336 | message_type=None, enum_type=None, containing_type=None, 337 | is_extension=False, extension_scope=None, 338 | serialized_options=None, file=DESCRIPTOR), 339 | _descriptor.FieldDescriptor( 340 | name='imagePath', full_name='spy.XmlMessage.imagePath', index=6, 341 | number=7, type=9, cpp_type=9, label=1, 342 | has_default_value=False, default_value=b"".decode('utf-8'), 343 | message_type=None, enum_type=None, containing_type=None, 344 | is_extension=False, extension_scope=None, 345 | serialized_options=None, file=DESCRIPTOR), 346 | _descriptor.FieldDescriptor( 347 | name='username', full_name='spy.XmlMessage.username', index=7, 348 | number=8, type=9, cpp_type=9, label=1, 349 | has_default_value=False, default_value=b"".decode('utf-8'), 350 | message_type=None, enum_type=None, containing_type=None, 351 | is_extension=False, extension_scope=None, 352 | serialized_options=None, file=DESCRIPTOR), 353 | _descriptor.FieldDescriptor( 354 | name='weappiconurl', full_name='spy.XmlMessage.weappiconurl', index=8, 355 | number=9, type=9, cpp_type=9, label=1, 356 | has_default_value=False, default_value=b"".decode('utf-8'), 357 | message_type=None, enum_type=None, containing_type=None, 358 | is_extension=False, extension_scope=None, 359 | serialized_options=None, file=DESCRIPTOR), 360 | _descriptor.FieldDescriptor( 361 | name='appname', full_name='spy.XmlMessage.appname', index=9, 362 | number=10, type=9, cpp_type=9, label=1, 363 | has_default_value=False, default_value=b"".decode('utf-8'), 364 | message_type=None, enum_type=None, containing_type=None, 365 | is_extension=False, extension_scope=None, 366 | serialized_options=None, file=DESCRIPTOR), 367 | ], 368 | extensions=[ 369 | ], 370 | nested_types=[], 371 | enum_types=[ 372 | ], 373 | serialized_options=None, 374 | is_extendable=False, 375 | syntax='proto3', 376 | extension_ranges=[], 377 | oneofs=[ 378 | ], 379 | serialized_start=478, 380 | serialized_end=652, 381 | ) 382 | 383 | 384 | _CONTACTAPPLICATION = _descriptor.Descriptor( 385 | name='ContactApplication', 386 | full_name='spy.ContactApplication', 387 | filename=None, 388 | file=DESCRIPTOR, 389 | containing_type=None, 390 | fields=[ 391 | _descriptor.FieldDescriptor( 392 | name='encryptusername', full_name='spy.ContactApplication.encryptusername', index=0, 393 | number=1, type=9, cpp_type=9, label=1, 394 | has_default_value=False, default_value=b"".decode('utf-8'), 395 | message_type=None, enum_type=None, containing_type=None, 396 | is_extension=False, extension_scope=None, 397 | serialized_options=None, file=DESCRIPTOR), 398 | _descriptor.FieldDescriptor( 399 | name='ticket', full_name='spy.ContactApplication.ticket', index=1, 400 | number=2, type=9, cpp_type=9, label=1, 401 | has_default_value=False, default_value=b"".decode('utf-8'), 402 | message_type=None, enum_type=None, containing_type=None, 403 | is_extension=False, extension_scope=None, 404 | serialized_options=None, file=DESCRIPTOR), 405 | ], 406 | extensions=[ 407 | ], 408 | nested_types=[], 409 | enum_types=[ 410 | ], 411 | serialized_options=None, 412 | is_extendable=False, 413 | syntax='proto3', 414 | extension_ranges=[], 415 | oneofs=[ 416 | ], 417 | serialized_start=654, 418 | serialized_end=715, 419 | ) 420 | 421 | 422 | _RESPONSE = _descriptor.Descriptor( 423 | name='Response', 424 | full_name='spy.Response', 425 | filename=None, 426 | file=DESCRIPTOR, 427 | containing_type=None, 428 | fields=[ 429 | _descriptor.FieldDescriptor( 430 | name='type', full_name='spy.Response.type', index=0, 431 | number=1, type=5, cpp_type=1, label=1, 432 | has_default_value=False, default_value=0, 433 | message_type=None, enum_type=None, containing_type=None, 434 | is_extension=False, extension_scope=None, 435 | serialized_options=None, file=DESCRIPTOR), 436 | _descriptor.FieldDescriptor( 437 | name='bytes', full_name='spy.Response.bytes', index=1, 438 | number=2, type=12, cpp_type=9, label=1, 439 | has_default_value=False, default_value=b"", 440 | message_type=None, enum_type=None, containing_type=None, 441 | is_extension=False, extension_scope=None, 442 | serialized_options=None, file=DESCRIPTOR), 443 | _descriptor.FieldDescriptor( 444 | name='pid', full_name='spy.Response.pid', index=2, 445 | number=3, type=5, cpp_type=1, label=1, 446 | has_default_value=False, default_value=0, 447 | message_type=None, enum_type=None, containing_type=None, 448 | is_extension=False, extension_scope=None, 449 | serialized_options=None, file=DESCRIPTOR), 450 | _descriptor.FieldDescriptor( 451 | name='port', full_name='spy.Response.port', index=3, 452 | number=4, type=5, cpp_type=1, label=1, 453 | has_default_value=False, default_value=0, 454 | message_type=None, enum_type=None, containing_type=None, 455 | is_extension=False, extension_scope=None, 456 | serialized_options=None, file=DESCRIPTOR), 457 | _descriptor.FieldDescriptor( 458 | name='id', full_name='spy.Response.id', index=4, 459 | number=5, type=9, cpp_type=9, label=1, 460 | has_default_value=False, default_value=b"".decode('utf-8'), 461 | message_type=None, enum_type=None, containing_type=None, 462 | is_extension=False, extension_scope=None, 463 | serialized_options=None, file=DESCRIPTOR), 464 | _descriptor.FieldDescriptor( 465 | name='code', full_name='spy.Response.code', index=5, 466 | number=6, type=5, cpp_type=1, label=1, 467 | has_default_value=False, default_value=0, 468 | message_type=None, enum_type=None, containing_type=None, 469 | is_extension=False, extension_scope=None, 470 | serialized_options=None, file=DESCRIPTOR), 471 | _descriptor.FieldDescriptor( 472 | name='message', full_name='spy.Response.message', index=6, 473 | number=7, type=9, cpp_type=9, label=1, 474 | has_default_value=False, default_value=b"".decode('utf-8'), 475 | message_type=None, enum_type=None, containing_type=None, 476 | is_extension=False, extension_scope=None, 477 | serialized_options=None, file=DESCRIPTOR), 478 | ], 479 | extensions=[ 480 | ], 481 | nested_types=[], 482 | enum_types=[ 483 | ], 484 | serialized_options=None, 485 | is_extendable=False, 486 | syntax='proto3', 487 | extension_ranges=[], 488 | oneofs=[ 489 | ], 490 | serialized_start=717, 491 | serialized_end=826, 492 | ) 493 | 494 | 495 | _REQUEST = _descriptor.Descriptor( 496 | name='Request', 497 | full_name='spy.Request', 498 | filename=None, 499 | file=DESCRIPTOR, 500 | containing_type=None, 501 | fields=[ 502 | _descriptor.FieldDescriptor( 503 | name='type', full_name='spy.Request.type', index=0, 504 | number=1, type=5, cpp_type=1, label=1, 505 | has_default_value=False, default_value=0, 506 | message_type=None, enum_type=None, containing_type=None, 507 | is_extension=False, extension_scope=None, 508 | serialized_options=None, file=DESCRIPTOR), 509 | _descriptor.FieldDescriptor( 510 | name='bytes', full_name='spy.Request.bytes', index=1, 511 | number=2, type=12, cpp_type=9, label=1, 512 | has_default_value=False, default_value=b"", 513 | message_type=None, enum_type=None, containing_type=None, 514 | is_extension=False, extension_scope=None, 515 | serialized_options=None, file=DESCRIPTOR), 516 | _descriptor.FieldDescriptor( 517 | name='id', full_name='spy.Request.id', index=2, 518 | number=3, type=9, cpp_type=9, label=1, 519 | has_default_value=False, default_value=b"".decode('utf-8'), 520 | message_type=None, enum_type=None, containing_type=None, 521 | is_extension=False, extension_scope=None, 522 | serialized_options=None, file=DESCRIPTOR), 523 | ], 524 | extensions=[ 525 | ], 526 | nested_types=[], 527 | enum_types=[ 528 | ], 529 | serialized_options=None, 530 | is_extendable=False, 531 | syntax='proto3', 532 | extension_ranges=[], 533 | oneofs=[ 534 | ], 535 | serialized_start=828, 536 | serialized_end=878, 537 | ) 538 | 539 | 540 | _CREATEGROUPCALLBACK = _descriptor.Descriptor( 541 | name='CreateGroupCallback', 542 | full_name='spy.CreateGroupCallback', 543 | filename=None, 544 | file=DESCRIPTOR, 545 | containing_type=None, 546 | fields=[ 547 | _descriptor.FieldDescriptor( 548 | name='wxid', full_name='spy.CreateGroupCallback.wxid', index=0, 549 | number=1, type=11, cpp_type=10, label=1, 550 | has_default_value=False, default_value=None, 551 | message_type=None, enum_type=None, containing_type=None, 552 | is_extension=False, extension_scope=None, 553 | serialized_options=None, file=DESCRIPTOR), 554 | _descriptor.FieldDescriptor( 555 | name='memberData', full_name='spy.CreateGroupCallback.memberData', index=1, 556 | number=2, type=11, cpp_type=10, label=3, 557 | has_default_value=False, default_value=[], 558 | message_type=None, enum_type=None, containing_type=None, 559 | is_extension=False, extension_scope=None, 560 | serialized_options=None, file=DESCRIPTOR), 561 | ], 562 | extensions=[ 563 | ], 564 | nested_types=[], 565 | enum_types=[ 566 | ], 567 | serialized_options=None, 568 | is_extendable=False, 569 | syntax='proto3', 570 | extension_ranges=[], 571 | oneofs=[ 572 | ], 573 | serialized_start=880, 574 | serialized_end=980, 575 | ) 576 | 577 | 578 | _GROUPMEMBERDETAILS = _descriptor.Descriptor( 579 | name='GroupMemberDetails', 580 | full_name='spy.GroupMemberDetails', 581 | filename=None, 582 | file=DESCRIPTOR, 583 | containing_type=None, 584 | fields=[ 585 | _descriptor.FieldDescriptor( 586 | name='wxid', full_name='spy.GroupMemberDetails.wxid', index=0, 587 | number=1, type=9, cpp_type=9, label=1, 588 | has_default_value=False, default_value=b"".decode('utf-8'), 589 | message_type=None, enum_type=None, containing_type=None, 590 | is_extension=False, extension_scope=None, 591 | serialized_options=None, file=DESCRIPTOR), 592 | _descriptor.FieldDescriptor( 593 | name='detailsCount', full_name='spy.GroupMemberDetails.detailsCount', index=1, 594 | number=2, type=5, cpp_type=1, label=1, 595 | has_default_value=False, default_value=0, 596 | message_type=None, enum_type=None, containing_type=None, 597 | is_extension=False, extension_scope=None, 598 | serialized_options=None, file=DESCRIPTOR), 599 | _descriptor.FieldDescriptor( 600 | name='groupMemberDetails', full_name='spy.GroupMemberDetails.groupMemberDetails', index=2, 601 | number=3, type=11, cpp_type=10, label=3, 602 | has_default_value=False, default_value=[], 603 | message_type=None, enum_type=None, containing_type=None, 604 | is_extension=False, extension_scope=None, 605 | serialized_options=None, file=DESCRIPTOR), 606 | ], 607 | extensions=[ 608 | ], 609 | nested_types=[], 610 | enum_types=[ 611 | ], 612 | serialized_options=None, 613 | is_extendable=False, 614 | syntax='proto3', 615 | extension_ranges=[], 616 | oneofs=[ 617 | ], 618 | serialized_start=982, 619 | serialized_end=1090, 620 | ) 621 | 622 | 623 | _GROUPMEMBEREVENT = _descriptor.Descriptor( 624 | name='GroupMemberEvent', 625 | full_name='spy.GroupMemberEvent', 626 | filename=None, 627 | file=DESCRIPTOR, 628 | containing_type=None, 629 | fields=[ 630 | _descriptor.FieldDescriptor( 631 | name='wxid', full_name='spy.GroupMemberEvent.wxid', index=0, 632 | number=1, type=9, cpp_type=9, label=1, 633 | has_default_value=False, default_value=b"".decode('utf-8'), 634 | message_type=None, enum_type=None, containing_type=None, 635 | is_extension=False, extension_scope=None, 636 | serialized_options=None, file=DESCRIPTOR), 637 | _descriptor.FieldDescriptor( 638 | name='wxidJoin', full_name='spy.GroupMemberEvent.wxidJoin', index=1, 639 | number=2, type=9, cpp_type=9, label=3, 640 | has_default_value=False, default_value=[], 641 | message_type=None, enum_type=None, containing_type=None, 642 | is_extension=False, extension_scope=None, 643 | serialized_options=None, file=DESCRIPTOR), 644 | _descriptor.FieldDescriptor( 645 | name='wxidLeave', full_name='spy.GroupMemberEvent.wxidLeave', index=2, 646 | number=3, type=9, cpp_type=9, label=3, 647 | has_default_value=False, default_value=[], 648 | message_type=None, enum_type=None, containing_type=None, 649 | is_extension=False, extension_scope=None, 650 | serialized_options=None, file=DESCRIPTOR), 651 | ], 652 | extensions=[ 653 | ], 654 | nested_types=[], 655 | enum_types=[ 656 | ], 657 | serialized_options=None, 658 | is_extendable=False, 659 | syntax='proto3', 660 | extension_ranges=[], 661 | oneofs=[ 662 | ], 663 | serialized_start=1092, 664 | serialized_end=1161, 665 | ) 666 | 667 | 668 | _LOGINQRCODE = _descriptor.Descriptor( 669 | name='LoginQRCode', 670 | full_name='spy.LoginQRCode', 671 | filename=None, 672 | file=DESCRIPTOR, 673 | containing_type=None, 674 | fields=[ 675 | _descriptor.FieldDescriptor( 676 | name='qrcodeSize', full_name='spy.LoginQRCode.qrcodeSize', index=0, 677 | number=1, type=5, cpp_type=1, label=1, 678 | has_default_value=False, default_value=0, 679 | message_type=None, enum_type=None, containing_type=None, 680 | is_extension=False, extension_scope=None, 681 | serialized_options=None, file=DESCRIPTOR), 682 | _descriptor.FieldDescriptor( 683 | name='qrcodeBytes', full_name='spy.LoginQRCode.qrcodeBytes', index=1, 684 | number=2, type=12, cpp_type=9, label=1, 685 | has_default_value=False, default_value=b"", 686 | message_type=None, enum_type=None, containing_type=None, 687 | is_extension=False, extension_scope=None, 688 | serialized_options=None, file=DESCRIPTOR), 689 | ], 690 | extensions=[ 691 | ], 692 | nested_types=[], 693 | enum_types=[ 694 | ], 695 | serialized_options=None, 696 | is_extendable=False, 697 | syntax='proto3', 698 | extension_ranges=[], 699 | oneofs=[ 700 | ], 701 | serialized_start=1163, 702 | serialized_end=1217, 703 | ) 704 | 705 | 706 | _GROUPENTERURL = _descriptor.Descriptor( 707 | name='GroupEnterUrl', 708 | full_name='spy.GroupEnterUrl', 709 | filename=None, 710 | file=DESCRIPTOR, 711 | containing_type=None, 712 | fields=[ 713 | _descriptor.FieldDescriptor( 714 | name='url', full_name='spy.GroupEnterUrl.url', index=0, 715 | number=2, type=9, cpp_type=9, label=1, 716 | has_default_value=False, default_value=b"".decode('utf-8'), 717 | message_type=None, enum_type=None, containing_type=None, 718 | is_extension=False, extension_scope=None, 719 | serialized_options=None, file=DESCRIPTOR), 720 | ], 721 | extensions=[ 722 | ], 723 | nested_types=[], 724 | enum_types=[ 725 | ], 726 | serialized_options=None, 727 | is_extendable=False, 728 | syntax='proto3', 729 | extension_ranges=[], 730 | oneofs=[ 731 | ], 732 | serialized_start=1219, 733 | serialized_end=1247, 734 | ) 735 | 736 | _CHATMESSAGE.fields_by_name['message'].message_type = wx__pb2._CHATMESSAGE 737 | _CONTACTS.fields_by_name['contactDetails'].message_type = wx__pb2._CONTACTDETAILS 738 | _CREATEGROUPCALLBACK.fields_by_name['wxid'].message_type = wx__pb2._WECHATSTRING 739 | _CREATEGROUPCALLBACK.fields_by_name['memberData'].message_type = wx__pb2._CREATEGROUPMEMBERDATA 740 | _GROUPMEMBERDETAILS.fields_by_name['groupMemberDetails'].message_type = wx__pb2._GROUPMEMBERDETAILS 741 | DESCRIPTOR.message_types_by_name['ChatMessage'] = _CHATMESSAGE 742 | DESCRIPTOR.message_types_by_name['AccountDetails'] = _ACCOUNTDETAILS 743 | DESCRIPTOR.message_types_by_name['Contacts'] = _CONTACTS 744 | DESCRIPTOR.message_types_by_name['TextMessage'] = _TEXTMESSAGE 745 | DESCRIPTOR.message_types_by_name['FileMessage'] = _FILEMESSAGE 746 | DESCRIPTOR.message_types_by_name['XmlMessage'] = _XMLMESSAGE 747 | DESCRIPTOR.message_types_by_name['ContactApplication'] = _CONTACTAPPLICATION 748 | DESCRIPTOR.message_types_by_name['Response'] = _RESPONSE 749 | DESCRIPTOR.message_types_by_name['Request'] = _REQUEST 750 | DESCRIPTOR.message_types_by_name['CreateGroupCallback'] = _CREATEGROUPCALLBACK 751 | DESCRIPTOR.message_types_by_name['GroupMemberDetails'] = _GROUPMEMBERDETAILS 752 | DESCRIPTOR.message_types_by_name['GroupMemberEvent'] = _GROUPMEMBEREVENT 753 | DESCRIPTOR.message_types_by_name['LoginQRCode'] = _LOGINQRCODE 754 | DESCRIPTOR.message_types_by_name['GroupEnterUrl'] = _GROUPENTERURL 755 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 756 | 757 | ChatMessage = _reflection.GeneratedProtocolMessageType('ChatMessage', (_message.Message,), { 758 | 'DESCRIPTOR' : _CHATMESSAGE, 759 | '__module__' : 'spy_pb2' 760 | # @@protoc_insertion_point(class_scope:spy.ChatMessage) 761 | }) 762 | _sym_db.RegisterMessage(ChatMessage) 763 | 764 | AccountDetails = _reflection.GeneratedProtocolMessageType('AccountDetails', (_message.Message,), { 765 | 'DESCRIPTOR' : _ACCOUNTDETAILS, 766 | '__module__' : 'spy_pb2' 767 | # @@protoc_insertion_point(class_scope:spy.AccountDetails) 768 | }) 769 | _sym_db.RegisterMessage(AccountDetails) 770 | 771 | Contacts = _reflection.GeneratedProtocolMessageType('Contacts', (_message.Message,), { 772 | 'DESCRIPTOR' : _CONTACTS, 773 | '__module__' : 'spy_pb2' 774 | # @@protoc_insertion_point(class_scope:spy.Contacts) 775 | }) 776 | _sym_db.RegisterMessage(Contacts) 777 | 778 | TextMessage = _reflection.GeneratedProtocolMessageType('TextMessage', (_message.Message,), { 779 | 'DESCRIPTOR' : _TEXTMESSAGE, 780 | '__module__' : 'spy_pb2' 781 | # @@protoc_insertion_point(class_scope:spy.TextMessage) 782 | }) 783 | _sym_db.RegisterMessage(TextMessage) 784 | 785 | FileMessage = _reflection.GeneratedProtocolMessageType('FileMessage', (_message.Message,), { 786 | 'DESCRIPTOR' : _FILEMESSAGE, 787 | '__module__' : 'spy_pb2' 788 | # @@protoc_insertion_point(class_scope:spy.FileMessage) 789 | }) 790 | _sym_db.RegisterMessage(FileMessage) 791 | 792 | XmlMessage = _reflection.GeneratedProtocolMessageType('XmlMessage', (_message.Message,), { 793 | 'DESCRIPTOR' : _XMLMESSAGE, 794 | '__module__' : 'spy_pb2' 795 | # @@protoc_insertion_point(class_scope:spy.XmlMessage) 796 | }) 797 | _sym_db.RegisterMessage(XmlMessage) 798 | 799 | ContactApplication = _reflection.GeneratedProtocolMessageType('ContactApplication', (_message.Message,), { 800 | 'DESCRIPTOR' : _CONTACTAPPLICATION, 801 | '__module__' : 'spy_pb2' 802 | # @@protoc_insertion_point(class_scope:spy.ContactApplication) 803 | }) 804 | _sym_db.RegisterMessage(ContactApplication) 805 | 806 | Response = _reflection.GeneratedProtocolMessageType('Response', (_message.Message,), { 807 | 'DESCRIPTOR' : _RESPONSE, 808 | '__module__' : 'spy_pb2' 809 | # @@protoc_insertion_point(class_scope:spy.Response) 810 | }) 811 | _sym_db.RegisterMessage(Response) 812 | 813 | Request = _reflection.GeneratedProtocolMessageType('Request', (_message.Message,), { 814 | 'DESCRIPTOR' : _REQUEST, 815 | '__module__' : 'spy_pb2' 816 | # @@protoc_insertion_point(class_scope:spy.Request) 817 | }) 818 | _sym_db.RegisterMessage(Request) 819 | 820 | CreateGroupCallback = _reflection.GeneratedProtocolMessageType('CreateGroupCallback', (_message.Message,), { 821 | 'DESCRIPTOR' : _CREATEGROUPCALLBACK, 822 | '__module__' : 'spy_pb2' 823 | # @@protoc_insertion_point(class_scope:spy.CreateGroupCallback) 824 | }) 825 | _sym_db.RegisterMessage(CreateGroupCallback) 826 | 827 | GroupMemberDetails = _reflection.GeneratedProtocolMessageType('GroupMemberDetails', (_message.Message,), { 828 | 'DESCRIPTOR' : _GROUPMEMBERDETAILS, 829 | '__module__' : 'spy_pb2' 830 | # @@protoc_insertion_point(class_scope:spy.GroupMemberDetails) 831 | }) 832 | _sym_db.RegisterMessage(GroupMemberDetails) 833 | 834 | GroupMemberEvent = _reflection.GeneratedProtocolMessageType('GroupMemberEvent', (_message.Message,), { 835 | 'DESCRIPTOR' : _GROUPMEMBEREVENT, 836 | '__module__' : 'spy_pb2' 837 | # @@protoc_insertion_point(class_scope:spy.GroupMemberEvent) 838 | }) 839 | _sym_db.RegisterMessage(GroupMemberEvent) 840 | 841 | LoginQRCode = _reflection.GeneratedProtocolMessageType('LoginQRCode', (_message.Message,), { 842 | 'DESCRIPTOR' : _LOGINQRCODE, 843 | '__module__' : 'spy_pb2' 844 | # @@protoc_insertion_point(class_scope:spy.LoginQRCode) 845 | }) 846 | _sym_db.RegisterMessage(LoginQRCode) 847 | 848 | GroupEnterUrl = _reflection.GeneratedProtocolMessageType('GroupEnterUrl', (_message.Message,), { 849 | 'DESCRIPTOR' : _GROUPENTERURL, 850 | '__module__' : 'spy_pb2' 851 | # @@protoc_insertion_point(class_scope:spy.GroupEnterUrl) 852 | }) 853 | _sym_db.RegisterMessage(GroupEnterUrl) 854 | 855 | 856 | # @@protoc_insertion_point(module_scope) 857 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/proto/wx_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: wx.proto 4 | 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor.FileDescriptor( 17 | name='wx.proto', 18 | package='wx', 19 | syntax='proto3', 20 | serialized_options=None, 21 | serialized_pb=b'\n\x08wx.proto\x12\x02wx\"\x1b\n\x0cWeChatString\x12\x0b\n\x03str\x18\x01 \x01(\t\"\xbc\x02\n\x0f\x41\x63\x63ountDetails1\x12\x1e\n\x04wxid\x18\x02 \x01(\x0b\x32\x10.wx.WeChatString\x12\"\n\x08nickname\x18\x03 \x01(\x0b\x32\x10.wx.WeChatString\x12\n\n\x02QQ\x18\x04 \x01(\x03\x12\x1f\n\x05\x65mail\x18\x05 \x01(\x0b\x32\x10.wx.WeChatString\x12\x1f\n\x05phone\x18\x06 \x01(\x0b\x32\x10.wx.WeChatString\x12\x10\n\x08unknown7\x18\x07 \x01(\x05\x12\x10\n\x08unknown8\x18\x08 \x01(\x05\x12\x10\n\x08unknown9\x18\t \x01(\x0c\x12\x0b\n\x03sex\x18\n \x01(\x05\x12\x10\n\x08province\x18\x0b \x01(\t\x12\x0c\n\x04\x63ity\x18\x0c \x01(\t\x12\x11\n\tautograph\x18\r \x01(\t\x12\x10\n\x08wechatId\x18\x1b \x01(\t\x12\x0f\n\x07\x63ountry\x18& \x01(\t\"8\n\rWeChatMoments\x12\x0c\n\x04\x66lag\x18\x01 \x01(\x05\x12\x19\n\x11momentsBackground\x18\x02 \x01(\t\"i\n\x0f\x41\x63\x63ountDetails2\x12(\n\rwechatMoments\x18\x01 \x01(\x0b\x32\x11.wx.WeChatMoments\x12\x16\n\x0eprofilePhotoHD\x18\t \x01(\t\x12\x14\n\x0cprofilePhoto\x18\n \x01(\t\"\x82\x01\n\x12\x41\x63\x63ountDetailsData\x12\x10\n\x08unknown1\x18\x01 \x01(\x0c\x12,\n\x0f\x61\x63\x63ountDetails1\x18\x02 \x01(\x0b\x32\x13.wx.AccountDetails1\x12,\n\x0f\x61\x63\x63ountDetails2\x18\x03 \x01(\x0b\x32\x13.wx.AccountDetails2\":\n\rMessageDetail\x12\x13\n\x0bmessageSize\x18\x01 \x01(\x05\x12\x14\n\x0cmessageBytes\x18\x02 \x01(\x0c\"H\n\x07Message\x12\x13\n\x0bmessageType\x18\x01 \x01(\x05\x12(\n\rmessageDetail\x18\x02 \x01(\x0b\x32\x11.wx.MessageDetail\"A\n\x0bMessageList\x12\x14\n\x0cmessageCount\x18\x01 \x01(\x05\x12\x1c\n\x07message\x18\x02 \x03(\x0b\x32\x0b.wx.Message\"E\n\x0bMessageData\x12\x10\n\x08unknown1\x18\x01 \x01(\x05\x12$\n\x0bmessageList\x18\x02 \x01(\x0b\x32\x0f.wx.MessageList\"6\n\rImageOverview\x12\x11\n\timageSize\x18\x01 \x01(\x05\x12\x12\n\nimageBytes\x18\x02 \x01(\x0c\"\x93\x02\n\x0b\x43hatMessage\x12\"\n\x08wxidFrom\x18\x02 \x01(\x0b\x32\x10.wx.WeChatString\x12 \n\x06wxidTo\x18\x03 \x01(\x0b\x32\x10.wx.WeChatString\x12\x0c\n\x04type\x18\x04 \x01(\x05\x12!\n\x07\x63ontent\x18\x05 \x01(\x0b\x32\x10.wx.WeChatString\x12\x10\n\x08unknown6\x18\x06 \x01(\x05\x12\x10\n\x08unknown7\x18\x07 \x01(\x05\x12(\n\rimageOverview\x18\x08 \x01(\x0b\x32\x11.wx.ImageOverview\x12\x11\n\ttimestamp\x18\t \x01(\x03\x12\x0c\n\x04head\x18\n \x01(\t\x12\x10\n\x08overview\x18\x0b \x01(\t\x12\x0c\n\x04\x66ile\x18\x0e \x01(\t\"-\n\x0bGroupMember\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x10\n\x08nickname\x18\x02 \x01(\t\"\x82\x01\n\x0fGroupMemberList\x12\x13\n\x0bmemberCount\x18\x01 \x01(\x05\x12$\n\x0bgroupMember\x18\x02 \x03(\x0b\x32\x0f.wx.GroupMember\x12\x10\n\x08unknown1\x18\x03 \x01(\x05\x12\x10\n\x08unknown2\x18\x04 \x01(\t\x12\x10\n\x08unknown3\x18\x05 \x01(\x05\"C\n\x0c\x43ontactPhone\x12\x12\n\nphoneCount\x18\x01 \x01(\x05\x12\x1f\n\x05phone\x18\x02 \x03(\x0b\x32\x10.wx.WeChatString\"\xc1\x05\n\x0e\x43ontactDetails\x12\x1e\n\x04wxid\x18\x01 \x01(\x0b\x32\x10.wx.WeChatString\x12\"\n\x08nickname\x18\x02 \x01(\x0b\x32\x10.wx.WeChatString\x12\x31\n\x17nicknamePinyinUppercase\x18\x03 \x01(\x0b\x32\x10.wx.WeChatString\x12(\n\x0enicknamePinyin\x18\x04 \x01(\x0b\x32\x10.wx.WeChatString\x12\x0b\n\x03sex\x18\x05 \x01(\x05\x12 \n\x06remark\x18\n \x01(\x0b\x32\x10.wx.WeChatString\x12/\n\x15remarkPinyinUppercase\x18\x0b \x01(\x0b\x32\x10.wx.WeChatString\x12&\n\x0cremarkPinyin\x18\x0c \x01(\x0b\x32\x10.wx.WeChatString\x12\x10\n\x08province\x18\x13 \x01(\t\x12\x0c\n\x04\x63ity\x18\x14 \x01(\t\x12\x11\n\tautograph\x18\x15 \x01(\t\x12\x10\n\x08wechatId\x18\x1e \x01(\t\x12\x16\n\x0egroupOwnerWxid\x18\x1f \x01(\t\x12(\n\rweChatMoments\x18% \x03(\x0b\x32\x11.wx.WeChatMoments\x12\x0f\n\x07\x63ountry\x18& \x01(\t\x12\x16\n\x0eprofilePhotoHD\x18\' \x01(\t\x12\x14\n\x0cprofilePhoto\x18( \x01(\t\x12\x11\n\tbrandList\x18) \x01(\t\x12\x0b\n\x03md5\x18, \x01(\t\x12\x17\n\x0f\x65ncryptusername\x18- \x01(\t\x12,\n\x0fgroupMemberList\x18\x39 \x01(\x0b\x32\x13.wx.GroupMemberList\x12\x13\n\x0b\x64\x65scription\x18; \x01(\t\x12\r\n\x05tagId\x18= \x01(\t\x12&\n\x0c\x63ontactPhone\x18> \x01(\x0b\x32\x10.wx.ContactPhone\x12\r\n\x05wxid2\x18G \x01(\t\"@\n\x12\x43ontactDetailsData\x12*\n\x0e\x63ontactDetails\x18\x03 \x01(\x0b\x32\x12.wx.ContactDetails\"7\n\x15\x43reateGroupMemberData\x12\x1e\n\x04wxid\x18\x01 \x01(\x0b\x32\x10.wx.WeChatString\"\x8e\x01\n\x12GroupMemberDetails\x12\x0c\n\x04wxid\x18\x01 \x01(\t\x12\x10\n\x08nickname\x18\x02 \x01(\t\x12\x15\n\rgroupNickname\x18\x03 \x01(\t\x12\x16\n\x0eprofilePhotoHD\x18\x04 \x01(\t\x12\x14\n\x0cprofilePhoto\x18\x05 \x01(\t\x12\x13\n\x0binviterWxid\x18\x07 \x01(\t\"b\n\x16GroupMemberDetailsList\x12\x14\n\x0c\x64\x65tailsCount\x18\x01 \x01(\x05\x12\x32\n\x12groupMemberDetails\x18\x02 \x03(\x0b\x32\x16.wx.GroupMemberDetails\"k\n\x1aGroupMemberDetailsListData\x12\x11\n\tgroupWxid\x18\x02 \x01(\t\x12:\n\x16groupMemberDetailsList\x18\x04 \x01(\x0b\x32\x1a.wx.GroupMemberDetailsList\"6\n\x0bLoginQRCode\x12\x12\n\nqrcodeSize\x18\x01 \x01(\x05\x12\x13\n\x0bqrcodeBytes\x18\x02 \x01(\x0c\"7\n\x0fLoginQRCodeData\x12$\n\x0bloginQRCode\x18\x02 \x01(\x0b\x32\x0f.wx.LoginQRCodeb\x06proto3' 22 | ) 23 | 24 | 25 | 26 | 27 | _WECHATSTRING = _descriptor.Descriptor( 28 | name='WeChatString', 29 | full_name='wx.WeChatString', 30 | filename=None, 31 | file=DESCRIPTOR, 32 | containing_type=None, 33 | fields=[ 34 | _descriptor.FieldDescriptor( 35 | name='str', full_name='wx.WeChatString.str', index=0, 36 | number=1, type=9, cpp_type=9, label=1, 37 | has_default_value=False, default_value=b"".decode('utf-8'), 38 | message_type=None, enum_type=None, containing_type=None, 39 | is_extension=False, extension_scope=None, 40 | serialized_options=None, file=DESCRIPTOR), 41 | ], 42 | extensions=[ 43 | ], 44 | nested_types=[], 45 | enum_types=[ 46 | ], 47 | serialized_options=None, 48 | is_extendable=False, 49 | syntax='proto3', 50 | extension_ranges=[], 51 | oneofs=[ 52 | ], 53 | serialized_start=16, 54 | serialized_end=43, 55 | ) 56 | 57 | 58 | _ACCOUNTDETAILS1 = _descriptor.Descriptor( 59 | name='AccountDetails1', 60 | full_name='wx.AccountDetails1', 61 | filename=None, 62 | file=DESCRIPTOR, 63 | containing_type=None, 64 | fields=[ 65 | _descriptor.FieldDescriptor( 66 | name='wxid', full_name='wx.AccountDetails1.wxid', index=0, 67 | number=2, type=11, cpp_type=10, label=1, 68 | has_default_value=False, default_value=None, 69 | message_type=None, enum_type=None, containing_type=None, 70 | is_extension=False, extension_scope=None, 71 | serialized_options=None, file=DESCRIPTOR), 72 | _descriptor.FieldDescriptor( 73 | name='nickname', full_name='wx.AccountDetails1.nickname', index=1, 74 | number=3, type=11, cpp_type=10, label=1, 75 | has_default_value=False, default_value=None, 76 | message_type=None, enum_type=None, containing_type=None, 77 | is_extension=False, extension_scope=None, 78 | serialized_options=None, file=DESCRIPTOR), 79 | _descriptor.FieldDescriptor( 80 | name='QQ', full_name='wx.AccountDetails1.QQ', index=2, 81 | number=4, type=3, cpp_type=2, label=1, 82 | has_default_value=False, default_value=0, 83 | message_type=None, enum_type=None, containing_type=None, 84 | is_extension=False, extension_scope=None, 85 | serialized_options=None, file=DESCRIPTOR), 86 | _descriptor.FieldDescriptor( 87 | name='email', full_name='wx.AccountDetails1.email', index=3, 88 | number=5, type=11, cpp_type=10, label=1, 89 | has_default_value=False, default_value=None, 90 | message_type=None, enum_type=None, containing_type=None, 91 | is_extension=False, extension_scope=None, 92 | serialized_options=None, file=DESCRIPTOR), 93 | _descriptor.FieldDescriptor( 94 | name='phone', full_name='wx.AccountDetails1.phone', index=4, 95 | number=6, type=11, cpp_type=10, label=1, 96 | has_default_value=False, default_value=None, 97 | message_type=None, enum_type=None, containing_type=None, 98 | is_extension=False, extension_scope=None, 99 | serialized_options=None, file=DESCRIPTOR), 100 | _descriptor.FieldDescriptor( 101 | name='unknown7', full_name='wx.AccountDetails1.unknown7', index=5, 102 | number=7, type=5, cpp_type=1, label=1, 103 | has_default_value=False, default_value=0, 104 | message_type=None, enum_type=None, containing_type=None, 105 | is_extension=False, extension_scope=None, 106 | serialized_options=None, file=DESCRIPTOR), 107 | _descriptor.FieldDescriptor( 108 | name='unknown8', full_name='wx.AccountDetails1.unknown8', index=6, 109 | number=8, type=5, cpp_type=1, label=1, 110 | has_default_value=False, default_value=0, 111 | message_type=None, enum_type=None, containing_type=None, 112 | is_extension=False, extension_scope=None, 113 | serialized_options=None, file=DESCRIPTOR), 114 | _descriptor.FieldDescriptor( 115 | name='unknown9', full_name='wx.AccountDetails1.unknown9', index=7, 116 | number=9, type=12, cpp_type=9, label=1, 117 | has_default_value=False, default_value=b"", 118 | message_type=None, enum_type=None, containing_type=None, 119 | is_extension=False, extension_scope=None, 120 | serialized_options=None, file=DESCRIPTOR), 121 | _descriptor.FieldDescriptor( 122 | name='sex', full_name='wx.AccountDetails1.sex', index=8, 123 | number=10, type=5, cpp_type=1, label=1, 124 | has_default_value=False, default_value=0, 125 | message_type=None, enum_type=None, containing_type=None, 126 | is_extension=False, extension_scope=None, 127 | serialized_options=None, file=DESCRIPTOR), 128 | _descriptor.FieldDescriptor( 129 | name='province', full_name='wx.AccountDetails1.province', index=9, 130 | number=11, type=9, cpp_type=9, label=1, 131 | has_default_value=False, default_value=b"".decode('utf-8'), 132 | message_type=None, enum_type=None, containing_type=None, 133 | is_extension=False, extension_scope=None, 134 | serialized_options=None, file=DESCRIPTOR), 135 | _descriptor.FieldDescriptor( 136 | name='city', full_name='wx.AccountDetails1.city', index=10, 137 | number=12, type=9, cpp_type=9, label=1, 138 | has_default_value=False, default_value=b"".decode('utf-8'), 139 | message_type=None, enum_type=None, containing_type=None, 140 | is_extension=False, extension_scope=None, 141 | serialized_options=None, file=DESCRIPTOR), 142 | _descriptor.FieldDescriptor( 143 | name='autograph', full_name='wx.AccountDetails1.autograph', index=11, 144 | number=13, type=9, cpp_type=9, label=1, 145 | has_default_value=False, default_value=b"".decode('utf-8'), 146 | message_type=None, enum_type=None, containing_type=None, 147 | is_extension=False, extension_scope=None, 148 | serialized_options=None, file=DESCRIPTOR), 149 | _descriptor.FieldDescriptor( 150 | name='wechatId', full_name='wx.AccountDetails1.wechatId', index=12, 151 | number=27, type=9, cpp_type=9, label=1, 152 | has_default_value=False, default_value=b"".decode('utf-8'), 153 | message_type=None, enum_type=None, containing_type=None, 154 | is_extension=False, extension_scope=None, 155 | serialized_options=None, file=DESCRIPTOR), 156 | _descriptor.FieldDescriptor( 157 | name='country', full_name='wx.AccountDetails1.country', index=13, 158 | number=38, type=9, cpp_type=9, label=1, 159 | has_default_value=False, default_value=b"".decode('utf-8'), 160 | message_type=None, enum_type=None, containing_type=None, 161 | is_extension=False, extension_scope=None, 162 | serialized_options=None, file=DESCRIPTOR), 163 | ], 164 | extensions=[ 165 | ], 166 | nested_types=[], 167 | enum_types=[ 168 | ], 169 | serialized_options=None, 170 | is_extendable=False, 171 | syntax='proto3', 172 | extension_ranges=[], 173 | oneofs=[ 174 | ], 175 | serialized_start=46, 176 | serialized_end=362, 177 | ) 178 | 179 | 180 | _WECHATMOMENTS = _descriptor.Descriptor( 181 | name='WeChatMoments', 182 | full_name='wx.WeChatMoments', 183 | filename=None, 184 | file=DESCRIPTOR, 185 | containing_type=None, 186 | fields=[ 187 | _descriptor.FieldDescriptor( 188 | name='flag', full_name='wx.WeChatMoments.flag', index=0, 189 | number=1, type=5, cpp_type=1, label=1, 190 | has_default_value=False, default_value=0, 191 | message_type=None, enum_type=None, containing_type=None, 192 | is_extension=False, extension_scope=None, 193 | serialized_options=None, file=DESCRIPTOR), 194 | _descriptor.FieldDescriptor( 195 | name='momentsBackground', full_name='wx.WeChatMoments.momentsBackground', index=1, 196 | number=2, type=9, cpp_type=9, label=1, 197 | has_default_value=False, default_value=b"".decode('utf-8'), 198 | message_type=None, enum_type=None, containing_type=None, 199 | is_extension=False, extension_scope=None, 200 | serialized_options=None, file=DESCRIPTOR), 201 | ], 202 | extensions=[ 203 | ], 204 | nested_types=[], 205 | enum_types=[ 206 | ], 207 | serialized_options=None, 208 | is_extendable=False, 209 | syntax='proto3', 210 | extension_ranges=[], 211 | oneofs=[ 212 | ], 213 | serialized_start=364, 214 | serialized_end=420, 215 | ) 216 | 217 | 218 | _ACCOUNTDETAILS2 = _descriptor.Descriptor( 219 | name='AccountDetails2', 220 | full_name='wx.AccountDetails2', 221 | filename=None, 222 | file=DESCRIPTOR, 223 | containing_type=None, 224 | fields=[ 225 | _descriptor.FieldDescriptor( 226 | name='wechatMoments', full_name='wx.AccountDetails2.wechatMoments', index=0, 227 | number=1, type=11, cpp_type=10, label=1, 228 | has_default_value=False, default_value=None, 229 | message_type=None, enum_type=None, containing_type=None, 230 | is_extension=False, extension_scope=None, 231 | serialized_options=None, file=DESCRIPTOR), 232 | _descriptor.FieldDescriptor( 233 | name='profilePhotoHD', full_name='wx.AccountDetails2.profilePhotoHD', index=1, 234 | number=9, type=9, cpp_type=9, label=1, 235 | has_default_value=False, default_value=b"".decode('utf-8'), 236 | message_type=None, enum_type=None, containing_type=None, 237 | is_extension=False, extension_scope=None, 238 | serialized_options=None, file=DESCRIPTOR), 239 | _descriptor.FieldDescriptor( 240 | name='profilePhoto', full_name='wx.AccountDetails2.profilePhoto', index=2, 241 | number=10, type=9, cpp_type=9, label=1, 242 | has_default_value=False, default_value=b"".decode('utf-8'), 243 | message_type=None, enum_type=None, containing_type=None, 244 | is_extension=False, extension_scope=None, 245 | serialized_options=None, file=DESCRIPTOR), 246 | ], 247 | extensions=[ 248 | ], 249 | nested_types=[], 250 | enum_types=[ 251 | ], 252 | serialized_options=None, 253 | is_extendable=False, 254 | syntax='proto3', 255 | extension_ranges=[], 256 | oneofs=[ 257 | ], 258 | serialized_start=422, 259 | serialized_end=527, 260 | ) 261 | 262 | 263 | _ACCOUNTDETAILSDATA = _descriptor.Descriptor( 264 | name='AccountDetailsData', 265 | full_name='wx.AccountDetailsData', 266 | filename=None, 267 | file=DESCRIPTOR, 268 | containing_type=None, 269 | fields=[ 270 | _descriptor.FieldDescriptor( 271 | name='unknown1', full_name='wx.AccountDetailsData.unknown1', index=0, 272 | number=1, type=12, cpp_type=9, label=1, 273 | has_default_value=False, default_value=b"", 274 | message_type=None, enum_type=None, containing_type=None, 275 | is_extension=False, extension_scope=None, 276 | serialized_options=None, file=DESCRIPTOR), 277 | _descriptor.FieldDescriptor( 278 | name='accountDetails1', full_name='wx.AccountDetailsData.accountDetails1', index=1, 279 | number=2, type=11, cpp_type=10, label=1, 280 | has_default_value=False, default_value=None, 281 | message_type=None, enum_type=None, containing_type=None, 282 | is_extension=False, extension_scope=None, 283 | serialized_options=None, file=DESCRIPTOR), 284 | _descriptor.FieldDescriptor( 285 | name='accountDetails2', full_name='wx.AccountDetailsData.accountDetails2', index=2, 286 | number=3, type=11, cpp_type=10, label=1, 287 | has_default_value=False, default_value=None, 288 | message_type=None, enum_type=None, containing_type=None, 289 | is_extension=False, extension_scope=None, 290 | serialized_options=None, file=DESCRIPTOR), 291 | ], 292 | extensions=[ 293 | ], 294 | nested_types=[], 295 | enum_types=[ 296 | ], 297 | serialized_options=None, 298 | is_extendable=False, 299 | syntax='proto3', 300 | extension_ranges=[], 301 | oneofs=[ 302 | ], 303 | serialized_start=530, 304 | serialized_end=660, 305 | ) 306 | 307 | 308 | _MESSAGEDETAIL = _descriptor.Descriptor( 309 | name='MessageDetail', 310 | full_name='wx.MessageDetail', 311 | filename=None, 312 | file=DESCRIPTOR, 313 | containing_type=None, 314 | fields=[ 315 | _descriptor.FieldDescriptor( 316 | name='messageSize', full_name='wx.MessageDetail.messageSize', index=0, 317 | number=1, type=5, cpp_type=1, label=1, 318 | has_default_value=False, default_value=0, 319 | message_type=None, enum_type=None, containing_type=None, 320 | is_extension=False, extension_scope=None, 321 | serialized_options=None, file=DESCRIPTOR), 322 | _descriptor.FieldDescriptor( 323 | name='messageBytes', full_name='wx.MessageDetail.messageBytes', index=1, 324 | number=2, type=12, cpp_type=9, label=1, 325 | has_default_value=False, default_value=b"", 326 | message_type=None, enum_type=None, containing_type=None, 327 | is_extension=False, extension_scope=None, 328 | serialized_options=None, file=DESCRIPTOR), 329 | ], 330 | extensions=[ 331 | ], 332 | nested_types=[], 333 | enum_types=[ 334 | ], 335 | serialized_options=None, 336 | is_extendable=False, 337 | syntax='proto3', 338 | extension_ranges=[], 339 | oneofs=[ 340 | ], 341 | serialized_start=662, 342 | serialized_end=720, 343 | ) 344 | 345 | 346 | _MESSAGE = _descriptor.Descriptor( 347 | name='Message', 348 | full_name='wx.Message', 349 | filename=None, 350 | file=DESCRIPTOR, 351 | containing_type=None, 352 | fields=[ 353 | _descriptor.FieldDescriptor( 354 | name='messageType', full_name='wx.Message.messageType', index=0, 355 | number=1, type=5, cpp_type=1, label=1, 356 | has_default_value=False, default_value=0, 357 | message_type=None, enum_type=None, containing_type=None, 358 | is_extension=False, extension_scope=None, 359 | serialized_options=None, file=DESCRIPTOR), 360 | _descriptor.FieldDescriptor( 361 | name='messageDetail', full_name='wx.Message.messageDetail', index=1, 362 | number=2, type=11, cpp_type=10, label=1, 363 | has_default_value=False, default_value=None, 364 | message_type=None, enum_type=None, containing_type=None, 365 | is_extension=False, extension_scope=None, 366 | serialized_options=None, file=DESCRIPTOR), 367 | ], 368 | extensions=[ 369 | ], 370 | nested_types=[], 371 | enum_types=[ 372 | ], 373 | serialized_options=None, 374 | is_extendable=False, 375 | syntax='proto3', 376 | extension_ranges=[], 377 | oneofs=[ 378 | ], 379 | serialized_start=722, 380 | serialized_end=794, 381 | ) 382 | 383 | 384 | _MESSAGELIST = _descriptor.Descriptor( 385 | name='MessageList', 386 | full_name='wx.MessageList', 387 | filename=None, 388 | file=DESCRIPTOR, 389 | containing_type=None, 390 | fields=[ 391 | _descriptor.FieldDescriptor( 392 | name='messageCount', full_name='wx.MessageList.messageCount', index=0, 393 | number=1, type=5, cpp_type=1, label=1, 394 | has_default_value=False, default_value=0, 395 | message_type=None, enum_type=None, containing_type=None, 396 | is_extension=False, extension_scope=None, 397 | serialized_options=None, file=DESCRIPTOR), 398 | _descriptor.FieldDescriptor( 399 | name='message', full_name='wx.MessageList.message', index=1, 400 | number=2, type=11, cpp_type=10, label=3, 401 | has_default_value=False, default_value=[], 402 | message_type=None, enum_type=None, containing_type=None, 403 | is_extension=False, extension_scope=None, 404 | serialized_options=None, file=DESCRIPTOR), 405 | ], 406 | extensions=[ 407 | ], 408 | nested_types=[], 409 | enum_types=[ 410 | ], 411 | serialized_options=None, 412 | is_extendable=False, 413 | syntax='proto3', 414 | extension_ranges=[], 415 | oneofs=[ 416 | ], 417 | serialized_start=796, 418 | serialized_end=861, 419 | ) 420 | 421 | 422 | _MESSAGEDATA = _descriptor.Descriptor( 423 | name='MessageData', 424 | full_name='wx.MessageData', 425 | filename=None, 426 | file=DESCRIPTOR, 427 | containing_type=None, 428 | fields=[ 429 | _descriptor.FieldDescriptor( 430 | name='unknown1', full_name='wx.MessageData.unknown1', index=0, 431 | number=1, type=5, cpp_type=1, label=1, 432 | has_default_value=False, default_value=0, 433 | message_type=None, enum_type=None, containing_type=None, 434 | is_extension=False, extension_scope=None, 435 | serialized_options=None, file=DESCRIPTOR), 436 | _descriptor.FieldDescriptor( 437 | name='messageList', full_name='wx.MessageData.messageList', index=1, 438 | number=2, type=11, cpp_type=10, label=1, 439 | has_default_value=False, default_value=None, 440 | message_type=None, enum_type=None, containing_type=None, 441 | is_extension=False, extension_scope=None, 442 | serialized_options=None, file=DESCRIPTOR), 443 | ], 444 | extensions=[ 445 | ], 446 | nested_types=[], 447 | enum_types=[ 448 | ], 449 | serialized_options=None, 450 | is_extendable=False, 451 | syntax='proto3', 452 | extension_ranges=[], 453 | oneofs=[ 454 | ], 455 | serialized_start=863, 456 | serialized_end=932, 457 | ) 458 | 459 | 460 | _IMAGEOVERVIEW = _descriptor.Descriptor( 461 | name='ImageOverview', 462 | full_name='wx.ImageOverview', 463 | filename=None, 464 | file=DESCRIPTOR, 465 | containing_type=None, 466 | fields=[ 467 | _descriptor.FieldDescriptor( 468 | name='imageSize', full_name='wx.ImageOverview.imageSize', index=0, 469 | number=1, type=5, cpp_type=1, label=1, 470 | has_default_value=False, default_value=0, 471 | message_type=None, enum_type=None, containing_type=None, 472 | is_extension=False, extension_scope=None, 473 | serialized_options=None, file=DESCRIPTOR), 474 | _descriptor.FieldDescriptor( 475 | name='imageBytes', full_name='wx.ImageOverview.imageBytes', index=1, 476 | number=2, type=12, cpp_type=9, label=1, 477 | has_default_value=False, default_value=b"", 478 | message_type=None, enum_type=None, containing_type=None, 479 | is_extension=False, extension_scope=None, 480 | serialized_options=None, file=DESCRIPTOR), 481 | ], 482 | extensions=[ 483 | ], 484 | nested_types=[], 485 | enum_types=[ 486 | ], 487 | serialized_options=None, 488 | is_extendable=False, 489 | syntax='proto3', 490 | extension_ranges=[], 491 | oneofs=[ 492 | ], 493 | serialized_start=934, 494 | serialized_end=988, 495 | ) 496 | 497 | 498 | _CHATMESSAGE = _descriptor.Descriptor( 499 | name='ChatMessage', 500 | full_name='wx.ChatMessage', 501 | filename=None, 502 | file=DESCRIPTOR, 503 | containing_type=None, 504 | fields=[ 505 | _descriptor.FieldDescriptor( 506 | name='wxidFrom', full_name='wx.ChatMessage.wxidFrom', index=0, 507 | number=2, type=11, cpp_type=10, label=1, 508 | has_default_value=False, default_value=None, 509 | message_type=None, enum_type=None, containing_type=None, 510 | is_extension=False, extension_scope=None, 511 | serialized_options=None, file=DESCRIPTOR), 512 | _descriptor.FieldDescriptor( 513 | name='wxidTo', full_name='wx.ChatMessage.wxidTo', index=1, 514 | number=3, type=11, cpp_type=10, label=1, 515 | has_default_value=False, default_value=None, 516 | message_type=None, enum_type=None, containing_type=None, 517 | is_extension=False, extension_scope=None, 518 | serialized_options=None, file=DESCRIPTOR), 519 | _descriptor.FieldDescriptor( 520 | name='type', full_name='wx.ChatMessage.type', index=2, 521 | number=4, type=5, cpp_type=1, label=1, 522 | has_default_value=False, default_value=0, 523 | message_type=None, enum_type=None, containing_type=None, 524 | is_extension=False, extension_scope=None, 525 | serialized_options=None, file=DESCRIPTOR), 526 | _descriptor.FieldDescriptor( 527 | name='content', full_name='wx.ChatMessage.content', index=3, 528 | number=5, type=11, cpp_type=10, label=1, 529 | has_default_value=False, default_value=None, 530 | message_type=None, enum_type=None, containing_type=None, 531 | is_extension=False, extension_scope=None, 532 | serialized_options=None, file=DESCRIPTOR), 533 | _descriptor.FieldDescriptor( 534 | name='unknown6', full_name='wx.ChatMessage.unknown6', index=4, 535 | number=6, type=5, cpp_type=1, label=1, 536 | has_default_value=False, default_value=0, 537 | message_type=None, enum_type=None, containing_type=None, 538 | is_extension=False, extension_scope=None, 539 | serialized_options=None, file=DESCRIPTOR), 540 | _descriptor.FieldDescriptor( 541 | name='unknown7', full_name='wx.ChatMessage.unknown7', index=5, 542 | number=7, type=5, cpp_type=1, label=1, 543 | has_default_value=False, default_value=0, 544 | message_type=None, enum_type=None, containing_type=None, 545 | is_extension=False, extension_scope=None, 546 | serialized_options=None, file=DESCRIPTOR), 547 | _descriptor.FieldDescriptor( 548 | name='imageOverview', full_name='wx.ChatMessage.imageOverview', index=6, 549 | number=8, type=11, cpp_type=10, label=1, 550 | has_default_value=False, default_value=None, 551 | message_type=None, enum_type=None, containing_type=None, 552 | is_extension=False, extension_scope=None, 553 | serialized_options=None, file=DESCRIPTOR), 554 | _descriptor.FieldDescriptor( 555 | name='timestamp', full_name='wx.ChatMessage.timestamp', index=7, 556 | number=9, type=3, cpp_type=2, label=1, 557 | has_default_value=False, default_value=0, 558 | message_type=None, enum_type=None, containing_type=None, 559 | is_extension=False, extension_scope=None, 560 | serialized_options=None, file=DESCRIPTOR), 561 | _descriptor.FieldDescriptor( 562 | name='head', full_name='wx.ChatMessage.head', index=8, 563 | number=10, type=9, cpp_type=9, label=1, 564 | has_default_value=False, default_value=b"".decode('utf-8'), 565 | message_type=None, enum_type=None, containing_type=None, 566 | is_extension=False, extension_scope=None, 567 | serialized_options=None, file=DESCRIPTOR), 568 | _descriptor.FieldDescriptor( 569 | name='overview', full_name='wx.ChatMessage.overview', index=9, 570 | number=11, type=9, cpp_type=9, label=1, 571 | has_default_value=False, default_value=b"".decode('utf-8'), 572 | message_type=None, enum_type=None, containing_type=None, 573 | is_extension=False, extension_scope=None, 574 | serialized_options=None, file=DESCRIPTOR), 575 | _descriptor.FieldDescriptor( 576 | name='file', full_name='wx.ChatMessage.file', index=10, 577 | number=14, type=9, cpp_type=9, label=1, 578 | has_default_value=False, default_value=b"".decode('utf-8'), 579 | message_type=None, enum_type=None, containing_type=None, 580 | is_extension=False, extension_scope=None, 581 | serialized_options=None, file=DESCRIPTOR), 582 | ], 583 | extensions=[ 584 | ], 585 | nested_types=[], 586 | enum_types=[ 587 | ], 588 | serialized_options=None, 589 | is_extendable=False, 590 | syntax='proto3', 591 | extension_ranges=[], 592 | oneofs=[ 593 | ], 594 | serialized_start=991, 595 | serialized_end=1266, 596 | ) 597 | 598 | 599 | _GROUPMEMBER = _descriptor.Descriptor( 600 | name='GroupMember', 601 | full_name='wx.GroupMember', 602 | filename=None, 603 | file=DESCRIPTOR, 604 | containing_type=None, 605 | fields=[ 606 | _descriptor.FieldDescriptor( 607 | name='wxid', full_name='wx.GroupMember.wxid', index=0, 608 | number=1, type=9, cpp_type=9, label=1, 609 | has_default_value=False, default_value=b"".decode('utf-8'), 610 | message_type=None, enum_type=None, containing_type=None, 611 | is_extension=False, extension_scope=None, 612 | serialized_options=None, file=DESCRIPTOR), 613 | _descriptor.FieldDescriptor( 614 | name='nickname', full_name='wx.GroupMember.nickname', index=1, 615 | number=2, type=9, cpp_type=9, label=1, 616 | has_default_value=False, default_value=b"".decode('utf-8'), 617 | message_type=None, enum_type=None, containing_type=None, 618 | is_extension=False, extension_scope=None, 619 | serialized_options=None, file=DESCRIPTOR), 620 | ], 621 | extensions=[ 622 | ], 623 | nested_types=[], 624 | enum_types=[ 625 | ], 626 | serialized_options=None, 627 | is_extendable=False, 628 | syntax='proto3', 629 | extension_ranges=[], 630 | oneofs=[ 631 | ], 632 | serialized_start=1268, 633 | serialized_end=1313, 634 | ) 635 | 636 | 637 | _GROUPMEMBERLIST = _descriptor.Descriptor( 638 | name='GroupMemberList', 639 | full_name='wx.GroupMemberList', 640 | filename=None, 641 | file=DESCRIPTOR, 642 | containing_type=None, 643 | fields=[ 644 | _descriptor.FieldDescriptor( 645 | name='memberCount', full_name='wx.GroupMemberList.memberCount', index=0, 646 | number=1, type=5, cpp_type=1, label=1, 647 | has_default_value=False, default_value=0, 648 | message_type=None, enum_type=None, containing_type=None, 649 | is_extension=False, extension_scope=None, 650 | serialized_options=None, file=DESCRIPTOR), 651 | _descriptor.FieldDescriptor( 652 | name='groupMember', full_name='wx.GroupMemberList.groupMember', index=1, 653 | number=2, type=11, cpp_type=10, label=3, 654 | has_default_value=False, default_value=[], 655 | message_type=None, enum_type=None, containing_type=None, 656 | is_extension=False, extension_scope=None, 657 | serialized_options=None, file=DESCRIPTOR), 658 | _descriptor.FieldDescriptor( 659 | name='unknown1', full_name='wx.GroupMemberList.unknown1', index=2, 660 | number=3, type=5, cpp_type=1, label=1, 661 | has_default_value=False, default_value=0, 662 | message_type=None, enum_type=None, containing_type=None, 663 | is_extension=False, extension_scope=None, 664 | serialized_options=None, file=DESCRIPTOR), 665 | _descriptor.FieldDescriptor( 666 | name='unknown2', full_name='wx.GroupMemberList.unknown2', index=3, 667 | number=4, type=9, cpp_type=9, label=1, 668 | has_default_value=False, default_value=b"".decode('utf-8'), 669 | message_type=None, enum_type=None, containing_type=None, 670 | is_extension=False, extension_scope=None, 671 | serialized_options=None, file=DESCRIPTOR), 672 | _descriptor.FieldDescriptor( 673 | name='unknown3', full_name='wx.GroupMemberList.unknown3', index=4, 674 | number=5, type=5, cpp_type=1, label=1, 675 | has_default_value=False, default_value=0, 676 | message_type=None, enum_type=None, containing_type=None, 677 | is_extension=False, extension_scope=None, 678 | serialized_options=None, file=DESCRIPTOR), 679 | ], 680 | extensions=[ 681 | ], 682 | nested_types=[], 683 | enum_types=[ 684 | ], 685 | serialized_options=None, 686 | is_extendable=False, 687 | syntax='proto3', 688 | extension_ranges=[], 689 | oneofs=[ 690 | ], 691 | serialized_start=1316, 692 | serialized_end=1446, 693 | ) 694 | 695 | 696 | _CONTACTPHONE = _descriptor.Descriptor( 697 | name='ContactPhone', 698 | full_name='wx.ContactPhone', 699 | filename=None, 700 | file=DESCRIPTOR, 701 | containing_type=None, 702 | fields=[ 703 | _descriptor.FieldDescriptor( 704 | name='phoneCount', full_name='wx.ContactPhone.phoneCount', index=0, 705 | number=1, type=5, cpp_type=1, label=1, 706 | has_default_value=False, default_value=0, 707 | message_type=None, enum_type=None, containing_type=None, 708 | is_extension=False, extension_scope=None, 709 | serialized_options=None, file=DESCRIPTOR), 710 | _descriptor.FieldDescriptor( 711 | name='phone', full_name='wx.ContactPhone.phone', index=1, 712 | number=2, type=11, cpp_type=10, label=3, 713 | has_default_value=False, default_value=[], 714 | message_type=None, enum_type=None, containing_type=None, 715 | is_extension=False, extension_scope=None, 716 | serialized_options=None, file=DESCRIPTOR), 717 | ], 718 | extensions=[ 719 | ], 720 | nested_types=[], 721 | enum_types=[ 722 | ], 723 | serialized_options=None, 724 | is_extendable=False, 725 | syntax='proto3', 726 | extension_ranges=[], 727 | oneofs=[ 728 | ], 729 | serialized_start=1448, 730 | serialized_end=1515, 731 | ) 732 | 733 | 734 | _CONTACTDETAILS = _descriptor.Descriptor( 735 | name='ContactDetails', 736 | full_name='wx.ContactDetails', 737 | filename=None, 738 | file=DESCRIPTOR, 739 | containing_type=None, 740 | fields=[ 741 | _descriptor.FieldDescriptor( 742 | name='wxid', full_name='wx.ContactDetails.wxid', index=0, 743 | number=1, type=11, cpp_type=10, label=1, 744 | has_default_value=False, default_value=None, 745 | message_type=None, enum_type=None, containing_type=None, 746 | is_extension=False, extension_scope=None, 747 | serialized_options=None, file=DESCRIPTOR), 748 | _descriptor.FieldDescriptor( 749 | name='nickname', full_name='wx.ContactDetails.nickname', index=1, 750 | number=2, type=11, cpp_type=10, label=1, 751 | has_default_value=False, default_value=None, 752 | message_type=None, enum_type=None, containing_type=None, 753 | is_extension=False, extension_scope=None, 754 | serialized_options=None, file=DESCRIPTOR), 755 | _descriptor.FieldDescriptor( 756 | name='nicknamePinyinUppercase', full_name='wx.ContactDetails.nicknamePinyinUppercase', index=2, 757 | number=3, type=11, cpp_type=10, label=1, 758 | has_default_value=False, default_value=None, 759 | message_type=None, enum_type=None, containing_type=None, 760 | is_extension=False, extension_scope=None, 761 | serialized_options=None, file=DESCRIPTOR), 762 | _descriptor.FieldDescriptor( 763 | name='nicknamePinyin', full_name='wx.ContactDetails.nicknamePinyin', index=3, 764 | number=4, type=11, cpp_type=10, label=1, 765 | has_default_value=False, default_value=None, 766 | message_type=None, enum_type=None, containing_type=None, 767 | is_extension=False, extension_scope=None, 768 | serialized_options=None, file=DESCRIPTOR), 769 | _descriptor.FieldDescriptor( 770 | name='sex', full_name='wx.ContactDetails.sex', index=4, 771 | number=5, type=5, cpp_type=1, label=1, 772 | has_default_value=False, default_value=0, 773 | message_type=None, enum_type=None, containing_type=None, 774 | is_extension=False, extension_scope=None, 775 | serialized_options=None, file=DESCRIPTOR), 776 | _descriptor.FieldDescriptor( 777 | name='remark', full_name='wx.ContactDetails.remark', index=5, 778 | number=10, type=11, cpp_type=10, label=1, 779 | has_default_value=False, default_value=None, 780 | message_type=None, enum_type=None, containing_type=None, 781 | is_extension=False, extension_scope=None, 782 | serialized_options=None, file=DESCRIPTOR), 783 | _descriptor.FieldDescriptor( 784 | name='remarkPinyinUppercase', full_name='wx.ContactDetails.remarkPinyinUppercase', index=6, 785 | number=11, type=11, cpp_type=10, label=1, 786 | has_default_value=False, default_value=None, 787 | message_type=None, enum_type=None, containing_type=None, 788 | is_extension=False, extension_scope=None, 789 | serialized_options=None, file=DESCRIPTOR), 790 | _descriptor.FieldDescriptor( 791 | name='remarkPinyin', full_name='wx.ContactDetails.remarkPinyin', index=7, 792 | number=12, type=11, cpp_type=10, label=1, 793 | has_default_value=False, default_value=None, 794 | message_type=None, enum_type=None, containing_type=None, 795 | is_extension=False, extension_scope=None, 796 | serialized_options=None, file=DESCRIPTOR), 797 | _descriptor.FieldDescriptor( 798 | name='province', full_name='wx.ContactDetails.province', index=8, 799 | number=19, type=9, cpp_type=9, label=1, 800 | has_default_value=False, default_value=b"".decode('utf-8'), 801 | message_type=None, enum_type=None, containing_type=None, 802 | is_extension=False, extension_scope=None, 803 | serialized_options=None, file=DESCRIPTOR), 804 | _descriptor.FieldDescriptor( 805 | name='city', full_name='wx.ContactDetails.city', index=9, 806 | number=20, type=9, cpp_type=9, label=1, 807 | has_default_value=False, default_value=b"".decode('utf-8'), 808 | message_type=None, enum_type=None, containing_type=None, 809 | is_extension=False, extension_scope=None, 810 | serialized_options=None, file=DESCRIPTOR), 811 | _descriptor.FieldDescriptor( 812 | name='autograph', full_name='wx.ContactDetails.autograph', index=10, 813 | number=21, type=9, cpp_type=9, label=1, 814 | has_default_value=False, default_value=b"".decode('utf-8'), 815 | message_type=None, enum_type=None, containing_type=None, 816 | is_extension=False, extension_scope=None, 817 | serialized_options=None, file=DESCRIPTOR), 818 | _descriptor.FieldDescriptor( 819 | name='wechatId', full_name='wx.ContactDetails.wechatId', index=11, 820 | number=30, type=9, cpp_type=9, label=1, 821 | has_default_value=False, default_value=b"".decode('utf-8'), 822 | message_type=None, enum_type=None, containing_type=None, 823 | is_extension=False, extension_scope=None, 824 | serialized_options=None, file=DESCRIPTOR), 825 | _descriptor.FieldDescriptor( 826 | name='groupOwnerWxid', full_name='wx.ContactDetails.groupOwnerWxid', index=12, 827 | number=31, type=9, cpp_type=9, label=1, 828 | has_default_value=False, default_value=b"".decode('utf-8'), 829 | message_type=None, enum_type=None, containing_type=None, 830 | is_extension=False, extension_scope=None, 831 | serialized_options=None, file=DESCRIPTOR), 832 | _descriptor.FieldDescriptor( 833 | name='weChatMoments', full_name='wx.ContactDetails.weChatMoments', index=13, 834 | number=37, type=11, cpp_type=10, label=3, 835 | has_default_value=False, default_value=[], 836 | message_type=None, enum_type=None, containing_type=None, 837 | is_extension=False, extension_scope=None, 838 | serialized_options=None, file=DESCRIPTOR), 839 | _descriptor.FieldDescriptor( 840 | name='country', full_name='wx.ContactDetails.country', index=14, 841 | number=38, type=9, cpp_type=9, label=1, 842 | has_default_value=False, default_value=b"".decode('utf-8'), 843 | message_type=None, enum_type=None, containing_type=None, 844 | is_extension=False, extension_scope=None, 845 | serialized_options=None, file=DESCRIPTOR), 846 | _descriptor.FieldDescriptor( 847 | name='profilePhotoHD', full_name='wx.ContactDetails.profilePhotoHD', index=15, 848 | number=39, type=9, cpp_type=9, label=1, 849 | has_default_value=False, default_value=b"".decode('utf-8'), 850 | message_type=None, enum_type=None, containing_type=None, 851 | is_extension=False, extension_scope=None, 852 | serialized_options=None, file=DESCRIPTOR), 853 | _descriptor.FieldDescriptor( 854 | name='profilePhoto', full_name='wx.ContactDetails.profilePhoto', index=16, 855 | number=40, type=9, cpp_type=9, label=1, 856 | has_default_value=False, default_value=b"".decode('utf-8'), 857 | message_type=None, enum_type=None, containing_type=None, 858 | is_extension=False, extension_scope=None, 859 | serialized_options=None, file=DESCRIPTOR), 860 | _descriptor.FieldDescriptor( 861 | name='brandList', full_name='wx.ContactDetails.brandList', index=17, 862 | number=41, type=9, cpp_type=9, label=1, 863 | has_default_value=False, default_value=b"".decode('utf-8'), 864 | message_type=None, enum_type=None, containing_type=None, 865 | is_extension=False, extension_scope=None, 866 | serialized_options=None, file=DESCRIPTOR), 867 | _descriptor.FieldDescriptor( 868 | name='md5', full_name='wx.ContactDetails.md5', index=18, 869 | number=44, type=9, cpp_type=9, label=1, 870 | has_default_value=False, default_value=b"".decode('utf-8'), 871 | message_type=None, enum_type=None, containing_type=None, 872 | is_extension=False, extension_scope=None, 873 | serialized_options=None, file=DESCRIPTOR), 874 | _descriptor.FieldDescriptor( 875 | name='encryptusername', full_name='wx.ContactDetails.encryptusername', index=19, 876 | number=45, type=9, cpp_type=9, label=1, 877 | has_default_value=False, default_value=b"".decode('utf-8'), 878 | message_type=None, enum_type=None, containing_type=None, 879 | is_extension=False, extension_scope=None, 880 | serialized_options=None, file=DESCRIPTOR), 881 | _descriptor.FieldDescriptor( 882 | name='groupMemberList', full_name='wx.ContactDetails.groupMemberList', index=20, 883 | number=57, type=11, cpp_type=10, label=1, 884 | has_default_value=False, default_value=None, 885 | message_type=None, enum_type=None, containing_type=None, 886 | is_extension=False, extension_scope=None, 887 | serialized_options=None, file=DESCRIPTOR), 888 | _descriptor.FieldDescriptor( 889 | name='description', full_name='wx.ContactDetails.description', index=21, 890 | number=59, type=9, cpp_type=9, label=1, 891 | has_default_value=False, default_value=b"".decode('utf-8'), 892 | message_type=None, enum_type=None, containing_type=None, 893 | is_extension=False, extension_scope=None, 894 | serialized_options=None, file=DESCRIPTOR), 895 | _descriptor.FieldDescriptor( 896 | name='tagId', full_name='wx.ContactDetails.tagId', index=22, 897 | number=61, type=9, cpp_type=9, label=1, 898 | has_default_value=False, default_value=b"".decode('utf-8'), 899 | message_type=None, enum_type=None, containing_type=None, 900 | is_extension=False, extension_scope=None, 901 | serialized_options=None, file=DESCRIPTOR), 902 | _descriptor.FieldDescriptor( 903 | name='contactPhone', full_name='wx.ContactDetails.contactPhone', index=23, 904 | number=62, type=11, cpp_type=10, label=1, 905 | has_default_value=False, default_value=None, 906 | message_type=None, enum_type=None, containing_type=None, 907 | is_extension=False, extension_scope=None, 908 | serialized_options=None, file=DESCRIPTOR), 909 | _descriptor.FieldDescriptor( 910 | name='wxid2', full_name='wx.ContactDetails.wxid2', index=24, 911 | number=71, type=9, cpp_type=9, label=1, 912 | has_default_value=False, default_value=b"".decode('utf-8'), 913 | message_type=None, enum_type=None, containing_type=None, 914 | is_extension=False, extension_scope=None, 915 | serialized_options=None, file=DESCRIPTOR), 916 | ], 917 | extensions=[ 918 | ], 919 | nested_types=[], 920 | enum_types=[ 921 | ], 922 | serialized_options=None, 923 | is_extendable=False, 924 | syntax='proto3', 925 | extension_ranges=[], 926 | oneofs=[ 927 | ], 928 | serialized_start=1518, 929 | serialized_end=2223, 930 | ) 931 | 932 | 933 | _CONTACTDETAILSDATA = _descriptor.Descriptor( 934 | name='ContactDetailsData', 935 | full_name='wx.ContactDetailsData', 936 | filename=None, 937 | file=DESCRIPTOR, 938 | containing_type=None, 939 | fields=[ 940 | _descriptor.FieldDescriptor( 941 | name='contactDetails', full_name='wx.ContactDetailsData.contactDetails', index=0, 942 | number=3, type=11, cpp_type=10, label=1, 943 | has_default_value=False, default_value=None, 944 | message_type=None, enum_type=None, containing_type=None, 945 | is_extension=False, extension_scope=None, 946 | serialized_options=None, file=DESCRIPTOR), 947 | ], 948 | extensions=[ 949 | ], 950 | nested_types=[], 951 | enum_types=[ 952 | ], 953 | serialized_options=None, 954 | is_extendable=False, 955 | syntax='proto3', 956 | extension_ranges=[], 957 | oneofs=[ 958 | ], 959 | serialized_start=2225, 960 | serialized_end=2289, 961 | ) 962 | 963 | 964 | _CREATEGROUPMEMBERDATA = _descriptor.Descriptor( 965 | name='CreateGroupMemberData', 966 | full_name='wx.CreateGroupMemberData', 967 | filename=None, 968 | file=DESCRIPTOR, 969 | containing_type=None, 970 | fields=[ 971 | _descriptor.FieldDescriptor( 972 | name='wxid', full_name='wx.CreateGroupMemberData.wxid', index=0, 973 | number=1, type=11, cpp_type=10, label=1, 974 | has_default_value=False, default_value=None, 975 | message_type=None, enum_type=None, containing_type=None, 976 | is_extension=False, extension_scope=None, 977 | serialized_options=None, file=DESCRIPTOR), 978 | ], 979 | extensions=[ 980 | ], 981 | nested_types=[], 982 | enum_types=[ 983 | ], 984 | serialized_options=None, 985 | is_extendable=False, 986 | syntax='proto3', 987 | extension_ranges=[], 988 | oneofs=[ 989 | ], 990 | serialized_start=2291, 991 | serialized_end=2346, 992 | ) 993 | 994 | 995 | _GROUPMEMBERDETAILS = _descriptor.Descriptor( 996 | name='GroupMemberDetails', 997 | full_name='wx.GroupMemberDetails', 998 | filename=None, 999 | file=DESCRIPTOR, 1000 | containing_type=None, 1001 | fields=[ 1002 | _descriptor.FieldDescriptor( 1003 | name='wxid', full_name='wx.GroupMemberDetails.wxid', index=0, 1004 | number=1, type=9, cpp_type=9, label=1, 1005 | has_default_value=False, default_value=b"".decode('utf-8'), 1006 | message_type=None, enum_type=None, containing_type=None, 1007 | is_extension=False, extension_scope=None, 1008 | serialized_options=None, file=DESCRIPTOR), 1009 | _descriptor.FieldDescriptor( 1010 | name='nickname', full_name='wx.GroupMemberDetails.nickname', index=1, 1011 | number=2, type=9, cpp_type=9, label=1, 1012 | has_default_value=False, default_value=b"".decode('utf-8'), 1013 | message_type=None, enum_type=None, containing_type=None, 1014 | is_extension=False, extension_scope=None, 1015 | serialized_options=None, file=DESCRIPTOR), 1016 | _descriptor.FieldDescriptor( 1017 | name='groupNickname', full_name='wx.GroupMemberDetails.groupNickname', index=2, 1018 | number=3, type=9, cpp_type=9, label=1, 1019 | has_default_value=False, default_value=b"".decode('utf-8'), 1020 | message_type=None, enum_type=None, containing_type=None, 1021 | is_extension=False, extension_scope=None, 1022 | serialized_options=None, file=DESCRIPTOR), 1023 | _descriptor.FieldDescriptor( 1024 | name='profilePhotoHD', full_name='wx.GroupMemberDetails.profilePhotoHD', index=3, 1025 | number=4, type=9, cpp_type=9, label=1, 1026 | has_default_value=False, default_value=b"".decode('utf-8'), 1027 | message_type=None, enum_type=None, containing_type=None, 1028 | is_extension=False, extension_scope=None, 1029 | serialized_options=None, file=DESCRIPTOR), 1030 | _descriptor.FieldDescriptor( 1031 | name='profilePhoto', full_name='wx.GroupMemberDetails.profilePhoto', index=4, 1032 | number=5, type=9, cpp_type=9, label=1, 1033 | has_default_value=False, default_value=b"".decode('utf-8'), 1034 | message_type=None, enum_type=None, containing_type=None, 1035 | is_extension=False, extension_scope=None, 1036 | serialized_options=None, file=DESCRIPTOR), 1037 | _descriptor.FieldDescriptor( 1038 | name='inviterWxid', full_name='wx.GroupMemberDetails.inviterWxid', index=5, 1039 | number=7, type=9, cpp_type=9, label=1, 1040 | has_default_value=False, default_value=b"".decode('utf-8'), 1041 | message_type=None, enum_type=None, containing_type=None, 1042 | is_extension=False, extension_scope=None, 1043 | serialized_options=None, file=DESCRIPTOR), 1044 | ], 1045 | extensions=[ 1046 | ], 1047 | nested_types=[], 1048 | enum_types=[ 1049 | ], 1050 | serialized_options=None, 1051 | is_extendable=False, 1052 | syntax='proto3', 1053 | extension_ranges=[], 1054 | oneofs=[ 1055 | ], 1056 | serialized_start=2349, 1057 | serialized_end=2491, 1058 | ) 1059 | 1060 | 1061 | _GROUPMEMBERDETAILSLIST = _descriptor.Descriptor( 1062 | name='GroupMemberDetailsList', 1063 | full_name='wx.GroupMemberDetailsList', 1064 | filename=None, 1065 | file=DESCRIPTOR, 1066 | containing_type=None, 1067 | fields=[ 1068 | _descriptor.FieldDescriptor( 1069 | name='detailsCount', full_name='wx.GroupMemberDetailsList.detailsCount', index=0, 1070 | number=1, type=5, cpp_type=1, label=1, 1071 | has_default_value=False, default_value=0, 1072 | message_type=None, enum_type=None, containing_type=None, 1073 | is_extension=False, extension_scope=None, 1074 | serialized_options=None, file=DESCRIPTOR), 1075 | _descriptor.FieldDescriptor( 1076 | name='groupMemberDetails', full_name='wx.GroupMemberDetailsList.groupMemberDetails', index=1, 1077 | number=2, type=11, cpp_type=10, label=3, 1078 | has_default_value=False, default_value=[], 1079 | message_type=None, enum_type=None, containing_type=None, 1080 | is_extension=False, extension_scope=None, 1081 | serialized_options=None, file=DESCRIPTOR), 1082 | ], 1083 | extensions=[ 1084 | ], 1085 | nested_types=[], 1086 | enum_types=[ 1087 | ], 1088 | serialized_options=None, 1089 | is_extendable=False, 1090 | syntax='proto3', 1091 | extension_ranges=[], 1092 | oneofs=[ 1093 | ], 1094 | serialized_start=2493, 1095 | serialized_end=2591, 1096 | ) 1097 | 1098 | 1099 | _GROUPMEMBERDETAILSLISTDATA = _descriptor.Descriptor( 1100 | name='GroupMemberDetailsListData', 1101 | full_name='wx.GroupMemberDetailsListData', 1102 | filename=None, 1103 | file=DESCRIPTOR, 1104 | containing_type=None, 1105 | fields=[ 1106 | _descriptor.FieldDescriptor( 1107 | name='groupWxid', full_name='wx.GroupMemberDetailsListData.groupWxid', index=0, 1108 | number=2, type=9, cpp_type=9, label=1, 1109 | has_default_value=False, default_value=b"".decode('utf-8'), 1110 | message_type=None, enum_type=None, containing_type=None, 1111 | is_extension=False, extension_scope=None, 1112 | serialized_options=None, file=DESCRIPTOR), 1113 | _descriptor.FieldDescriptor( 1114 | name='groupMemberDetailsList', full_name='wx.GroupMemberDetailsListData.groupMemberDetailsList', index=1, 1115 | number=4, type=11, cpp_type=10, label=1, 1116 | has_default_value=False, default_value=None, 1117 | message_type=None, enum_type=None, containing_type=None, 1118 | is_extension=False, extension_scope=None, 1119 | serialized_options=None, file=DESCRIPTOR), 1120 | ], 1121 | extensions=[ 1122 | ], 1123 | nested_types=[], 1124 | enum_types=[ 1125 | ], 1126 | serialized_options=None, 1127 | is_extendable=False, 1128 | syntax='proto3', 1129 | extension_ranges=[], 1130 | oneofs=[ 1131 | ], 1132 | serialized_start=2593, 1133 | serialized_end=2700, 1134 | ) 1135 | 1136 | 1137 | _LOGINQRCODE = _descriptor.Descriptor( 1138 | name='LoginQRCode', 1139 | full_name='wx.LoginQRCode', 1140 | filename=None, 1141 | file=DESCRIPTOR, 1142 | containing_type=None, 1143 | fields=[ 1144 | _descriptor.FieldDescriptor( 1145 | name='qrcodeSize', full_name='wx.LoginQRCode.qrcodeSize', index=0, 1146 | number=1, type=5, cpp_type=1, label=1, 1147 | has_default_value=False, default_value=0, 1148 | message_type=None, enum_type=None, containing_type=None, 1149 | is_extension=False, extension_scope=None, 1150 | serialized_options=None, file=DESCRIPTOR), 1151 | _descriptor.FieldDescriptor( 1152 | name='qrcodeBytes', full_name='wx.LoginQRCode.qrcodeBytes', index=1, 1153 | number=2, type=12, cpp_type=9, label=1, 1154 | has_default_value=False, default_value=b"", 1155 | message_type=None, enum_type=None, containing_type=None, 1156 | is_extension=False, extension_scope=None, 1157 | serialized_options=None, file=DESCRIPTOR), 1158 | ], 1159 | extensions=[ 1160 | ], 1161 | nested_types=[], 1162 | enum_types=[ 1163 | ], 1164 | serialized_options=None, 1165 | is_extendable=False, 1166 | syntax='proto3', 1167 | extension_ranges=[], 1168 | oneofs=[ 1169 | ], 1170 | serialized_start=2702, 1171 | serialized_end=2756, 1172 | ) 1173 | 1174 | 1175 | _LOGINQRCODEDATA = _descriptor.Descriptor( 1176 | name='LoginQRCodeData', 1177 | full_name='wx.LoginQRCodeData', 1178 | filename=None, 1179 | file=DESCRIPTOR, 1180 | containing_type=None, 1181 | fields=[ 1182 | _descriptor.FieldDescriptor( 1183 | name='loginQRCode', full_name='wx.LoginQRCodeData.loginQRCode', index=0, 1184 | number=2, type=11, cpp_type=10, label=1, 1185 | has_default_value=False, default_value=None, 1186 | message_type=None, enum_type=None, containing_type=None, 1187 | is_extension=False, extension_scope=None, 1188 | serialized_options=None, file=DESCRIPTOR), 1189 | ], 1190 | extensions=[ 1191 | ], 1192 | nested_types=[], 1193 | enum_types=[ 1194 | ], 1195 | serialized_options=None, 1196 | is_extendable=False, 1197 | syntax='proto3', 1198 | extension_ranges=[], 1199 | oneofs=[ 1200 | ], 1201 | serialized_start=2758, 1202 | serialized_end=2813, 1203 | ) 1204 | 1205 | _ACCOUNTDETAILS1.fields_by_name['wxid'].message_type = _WECHATSTRING 1206 | _ACCOUNTDETAILS1.fields_by_name['nickname'].message_type = _WECHATSTRING 1207 | _ACCOUNTDETAILS1.fields_by_name['email'].message_type = _WECHATSTRING 1208 | _ACCOUNTDETAILS1.fields_by_name['phone'].message_type = _WECHATSTRING 1209 | _ACCOUNTDETAILS2.fields_by_name['wechatMoments'].message_type = _WECHATMOMENTS 1210 | _ACCOUNTDETAILSDATA.fields_by_name['accountDetails1'].message_type = _ACCOUNTDETAILS1 1211 | _ACCOUNTDETAILSDATA.fields_by_name['accountDetails2'].message_type = _ACCOUNTDETAILS2 1212 | _MESSAGE.fields_by_name['messageDetail'].message_type = _MESSAGEDETAIL 1213 | _MESSAGELIST.fields_by_name['message'].message_type = _MESSAGE 1214 | _MESSAGEDATA.fields_by_name['messageList'].message_type = _MESSAGELIST 1215 | _CHATMESSAGE.fields_by_name['wxidFrom'].message_type = _WECHATSTRING 1216 | _CHATMESSAGE.fields_by_name['wxidTo'].message_type = _WECHATSTRING 1217 | _CHATMESSAGE.fields_by_name['content'].message_type = _WECHATSTRING 1218 | _CHATMESSAGE.fields_by_name['imageOverview'].message_type = _IMAGEOVERVIEW 1219 | _GROUPMEMBERLIST.fields_by_name['groupMember'].message_type = _GROUPMEMBER 1220 | _CONTACTPHONE.fields_by_name['phone'].message_type = _WECHATSTRING 1221 | _CONTACTDETAILS.fields_by_name['wxid'].message_type = _WECHATSTRING 1222 | _CONTACTDETAILS.fields_by_name['nickname'].message_type = _WECHATSTRING 1223 | _CONTACTDETAILS.fields_by_name['nicknamePinyinUppercase'].message_type = _WECHATSTRING 1224 | _CONTACTDETAILS.fields_by_name['nicknamePinyin'].message_type = _WECHATSTRING 1225 | _CONTACTDETAILS.fields_by_name['remark'].message_type = _WECHATSTRING 1226 | _CONTACTDETAILS.fields_by_name['remarkPinyinUppercase'].message_type = _WECHATSTRING 1227 | _CONTACTDETAILS.fields_by_name['remarkPinyin'].message_type = _WECHATSTRING 1228 | _CONTACTDETAILS.fields_by_name['weChatMoments'].message_type = _WECHATMOMENTS 1229 | _CONTACTDETAILS.fields_by_name['groupMemberList'].message_type = _GROUPMEMBERLIST 1230 | _CONTACTDETAILS.fields_by_name['contactPhone'].message_type = _CONTACTPHONE 1231 | _CONTACTDETAILSDATA.fields_by_name['contactDetails'].message_type = _CONTACTDETAILS 1232 | _CREATEGROUPMEMBERDATA.fields_by_name['wxid'].message_type = _WECHATSTRING 1233 | _GROUPMEMBERDETAILSLIST.fields_by_name['groupMemberDetails'].message_type = _GROUPMEMBERDETAILS 1234 | _GROUPMEMBERDETAILSLISTDATA.fields_by_name['groupMemberDetailsList'].message_type = _GROUPMEMBERDETAILSLIST 1235 | _LOGINQRCODEDATA.fields_by_name['loginQRCode'].message_type = _LOGINQRCODE 1236 | DESCRIPTOR.message_types_by_name['WeChatString'] = _WECHATSTRING 1237 | DESCRIPTOR.message_types_by_name['AccountDetails1'] = _ACCOUNTDETAILS1 1238 | DESCRIPTOR.message_types_by_name['WeChatMoments'] = _WECHATMOMENTS 1239 | DESCRIPTOR.message_types_by_name['AccountDetails2'] = _ACCOUNTDETAILS2 1240 | DESCRIPTOR.message_types_by_name['AccountDetailsData'] = _ACCOUNTDETAILSDATA 1241 | DESCRIPTOR.message_types_by_name['MessageDetail'] = _MESSAGEDETAIL 1242 | DESCRIPTOR.message_types_by_name['Message'] = _MESSAGE 1243 | DESCRIPTOR.message_types_by_name['MessageList'] = _MESSAGELIST 1244 | DESCRIPTOR.message_types_by_name['MessageData'] = _MESSAGEDATA 1245 | DESCRIPTOR.message_types_by_name['ImageOverview'] = _IMAGEOVERVIEW 1246 | DESCRIPTOR.message_types_by_name['ChatMessage'] = _CHATMESSAGE 1247 | DESCRIPTOR.message_types_by_name['GroupMember'] = _GROUPMEMBER 1248 | DESCRIPTOR.message_types_by_name['GroupMemberList'] = _GROUPMEMBERLIST 1249 | DESCRIPTOR.message_types_by_name['ContactPhone'] = _CONTACTPHONE 1250 | DESCRIPTOR.message_types_by_name['ContactDetails'] = _CONTACTDETAILS 1251 | DESCRIPTOR.message_types_by_name['ContactDetailsData'] = _CONTACTDETAILSDATA 1252 | DESCRIPTOR.message_types_by_name['CreateGroupMemberData'] = _CREATEGROUPMEMBERDATA 1253 | DESCRIPTOR.message_types_by_name['GroupMemberDetails'] = _GROUPMEMBERDETAILS 1254 | DESCRIPTOR.message_types_by_name['GroupMemberDetailsList'] = _GROUPMEMBERDETAILSLIST 1255 | DESCRIPTOR.message_types_by_name['GroupMemberDetailsListData'] = _GROUPMEMBERDETAILSLISTDATA 1256 | DESCRIPTOR.message_types_by_name['LoginQRCode'] = _LOGINQRCODE 1257 | DESCRIPTOR.message_types_by_name['LoginQRCodeData'] = _LOGINQRCODEDATA 1258 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 1259 | 1260 | WeChatString = _reflection.GeneratedProtocolMessageType('WeChatString', (_message.Message,), { 1261 | 'DESCRIPTOR' : _WECHATSTRING, 1262 | '__module__' : 'wx_pb2' 1263 | # @@protoc_insertion_point(class_scope:wx.WeChatString) 1264 | }) 1265 | _sym_db.RegisterMessage(WeChatString) 1266 | 1267 | AccountDetails1 = _reflection.GeneratedProtocolMessageType('AccountDetails1', (_message.Message,), { 1268 | 'DESCRIPTOR' : _ACCOUNTDETAILS1, 1269 | '__module__' : 'wx_pb2' 1270 | # @@protoc_insertion_point(class_scope:wx.AccountDetails1) 1271 | }) 1272 | _sym_db.RegisterMessage(AccountDetails1) 1273 | 1274 | WeChatMoments = _reflection.GeneratedProtocolMessageType('WeChatMoments', (_message.Message,), { 1275 | 'DESCRIPTOR' : _WECHATMOMENTS, 1276 | '__module__' : 'wx_pb2' 1277 | # @@protoc_insertion_point(class_scope:wx.WeChatMoments) 1278 | }) 1279 | _sym_db.RegisterMessage(WeChatMoments) 1280 | 1281 | AccountDetails2 = _reflection.GeneratedProtocolMessageType('AccountDetails2', (_message.Message,), { 1282 | 'DESCRIPTOR' : _ACCOUNTDETAILS2, 1283 | '__module__' : 'wx_pb2' 1284 | # @@protoc_insertion_point(class_scope:wx.AccountDetails2) 1285 | }) 1286 | _sym_db.RegisterMessage(AccountDetails2) 1287 | 1288 | AccountDetailsData = _reflection.GeneratedProtocolMessageType('AccountDetailsData', (_message.Message,), { 1289 | 'DESCRIPTOR' : _ACCOUNTDETAILSDATA, 1290 | '__module__' : 'wx_pb2' 1291 | # @@protoc_insertion_point(class_scope:wx.AccountDetailsData) 1292 | }) 1293 | _sym_db.RegisterMessage(AccountDetailsData) 1294 | 1295 | MessageDetail = _reflection.GeneratedProtocolMessageType('MessageDetail', (_message.Message,), { 1296 | 'DESCRIPTOR' : _MESSAGEDETAIL, 1297 | '__module__' : 'wx_pb2' 1298 | # @@protoc_insertion_point(class_scope:wx.MessageDetail) 1299 | }) 1300 | _sym_db.RegisterMessage(MessageDetail) 1301 | 1302 | Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), { 1303 | 'DESCRIPTOR' : _MESSAGE, 1304 | '__module__' : 'wx_pb2' 1305 | # @@protoc_insertion_point(class_scope:wx.Message) 1306 | }) 1307 | _sym_db.RegisterMessage(Message) 1308 | 1309 | MessageList = _reflection.GeneratedProtocolMessageType('MessageList', (_message.Message,), { 1310 | 'DESCRIPTOR' : _MESSAGELIST, 1311 | '__module__' : 'wx_pb2' 1312 | # @@protoc_insertion_point(class_scope:wx.MessageList) 1313 | }) 1314 | _sym_db.RegisterMessage(MessageList) 1315 | 1316 | MessageData = _reflection.GeneratedProtocolMessageType('MessageData', (_message.Message,), { 1317 | 'DESCRIPTOR' : _MESSAGEDATA, 1318 | '__module__' : 'wx_pb2' 1319 | # @@protoc_insertion_point(class_scope:wx.MessageData) 1320 | }) 1321 | _sym_db.RegisterMessage(MessageData) 1322 | 1323 | ImageOverview = _reflection.GeneratedProtocolMessageType('ImageOverview', (_message.Message,), { 1324 | 'DESCRIPTOR' : _IMAGEOVERVIEW, 1325 | '__module__' : 'wx_pb2' 1326 | # @@protoc_insertion_point(class_scope:wx.ImageOverview) 1327 | }) 1328 | _sym_db.RegisterMessage(ImageOverview) 1329 | 1330 | ChatMessage = _reflection.GeneratedProtocolMessageType('ChatMessage', (_message.Message,), { 1331 | 'DESCRIPTOR' : _CHATMESSAGE, 1332 | '__module__' : 'wx_pb2' 1333 | # @@protoc_insertion_point(class_scope:wx.ChatMessage) 1334 | }) 1335 | _sym_db.RegisterMessage(ChatMessage) 1336 | 1337 | GroupMember = _reflection.GeneratedProtocolMessageType('GroupMember', (_message.Message,), { 1338 | 'DESCRIPTOR' : _GROUPMEMBER, 1339 | '__module__' : 'wx_pb2' 1340 | # @@protoc_insertion_point(class_scope:wx.GroupMember) 1341 | }) 1342 | _sym_db.RegisterMessage(GroupMember) 1343 | 1344 | GroupMemberList = _reflection.GeneratedProtocolMessageType('GroupMemberList', (_message.Message,), { 1345 | 'DESCRIPTOR' : _GROUPMEMBERLIST, 1346 | '__module__' : 'wx_pb2' 1347 | # @@protoc_insertion_point(class_scope:wx.GroupMemberList) 1348 | }) 1349 | _sym_db.RegisterMessage(GroupMemberList) 1350 | 1351 | ContactPhone = _reflection.GeneratedProtocolMessageType('ContactPhone', (_message.Message,), { 1352 | 'DESCRIPTOR' : _CONTACTPHONE, 1353 | '__module__' : 'wx_pb2' 1354 | # @@protoc_insertion_point(class_scope:wx.ContactPhone) 1355 | }) 1356 | _sym_db.RegisterMessage(ContactPhone) 1357 | 1358 | ContactDetails = _reflection.GeneratedProtocolMessageType('ContactDetails', (_message.Message,), { 1359 | 'DESCRIPTOR' : _CONTACTDETAILS, 1360 | '__module__' : 'wx_pb2' 1361 | # @@protoc_insertion_point(class_scope:wx.ContactDetails) 1362 | }) 1363 | _sym_db.RegisterMessage(ContactDetails) 1364 | 1365 | ContactDetailsData = _reflection.GeneratedProtocolMessageType('ContactDetailsData', (_message.Message,), { 1366 | 'DESCRIPTOR' : _CONTACTDETAILSDATA, 1367 | '__module__' : 'wx_pb2' 1368 | # @@protoc_insertion_point(class_scope:wx.ContactDetailsData) 1369 | }) 1370 | _sym_db.RegisterMessage(ContactDetailsData) 1371 | 1372 | CreateGroupMemberData = _reflection.GeneratedProtocolMessageType('CreateGroupMemberData', (_message.Message,), { 1373 | 'DESCRIPTOR' : _CREATEGROUPMEMBERDATA, 1374 | '__module__' : 'wx_pb2' 1375 | # @@protoc_insertion_point(class_scope:wx.CreateGroupMemberData) 1376 | }) 1377 | _sym_db.RegisterMessage(CreateGroupMemberData) 1378 | 1379 | GroupMemberDetails = _reflection.GeneratedProtocolMessageType('GroupMemberDetails', (_message.Message,), { 1380 | 'DESCRIPTOR' : _GROUPMEMBERDETAILS, 1381 | '__module__' : 'wx_pb2' 1382 | # @@protoc_insertion_point(class_scope:wx.GroupMemberDetails) 1383 | }) 1384 | _sym_db.RegisterMessage(GroupMemberDetails) 1385 | 1386 | GroupMemberDetailsList = _reflection.GeneratedProtocolMessageType('GroupMemberDetailsList', (_message.Message,), { 1387 | 'DESCRIPTOR' : _GROUPMEMBERDETAILSLIST, 1388 | '__module__' : 'wx_pb2' 1389 | # @@protoc_insertion_point(class_scope:wx.GroupMemberDetailsList) 1390 | }) 1391 | _sym_db.RegisterMessage(GroupMemberDetailsList) 1392 | 1393 | GroupMemberDetailsListData = _reflection.GeneratedProtocolMessageType('GroupMemberDetailsListData', (_message.Message,), { 1394 | 'DESCRIPTOR' : _GROUPMEMBERDETAILSLISTDATA, 1395 | '__module__' : 'wx_pb2' 1396 | # @@protoc_insertion_point(class_scope:wx.GroupMemberDetailsListData) 1397 | }) 1398 | _sym_db.RegisterMessage(GroupMemberDetailsListData) 1399 | 1400 | LoginQRCode = _reflection.GeneratedProtocolMessageType('LoginQRCode', (_message.Message,), { 1401 | 'DESCRIPTOR' : _LOGINQRCODE, 1402 | '__module__' : 'wx_pb2' 1403 | # @@protoc_insertion_point(class_scope:wx.LoginQRCode) 1404 | }) 1405 | _sym_db.RegisterMessage(LoginQRCode) 1406 | 1407 | LoginQRCodeData = _reflection.GeneratedProtocolMessageType('LoginQRCodeData', (_message.Message,), { 1408 | 'DESCRIPTOR' : _LOGINQRCODEDATA, 1409 | '__module__' : 'wx_pb2' 1410 | # @@protoc_insertion_point(class_scope:wx.LoginQRCodeData) 1411 | }) 1412 | _sym_db.RegisterMessage(LoginQRCodeData) 1413 | 1414 | 1415 | # @@protoc_insertion_point(module_scope) 1416 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/service/API.md: -------------------------------------------------------------------------------- 1 | # SpyService接口文档 2 | 3 | ## 1. 打开微信 4 | ### 1.1 功能描述 5 | 唤起微信客户端并返回微信客户端标识port 6 | ### 1.2 请求说明 7 | > 请求方式:GET
8 | 请求URL :[/open_wechat]() 9 | 10 | ### 1.3 请求参数 11 | 无 12 | ### 1.4 返回结果 13 | ```json 14 | { 15 | "code": 1, 16 | "port": 50866 17 | } 18 | ``` 19 | ### 1.5 返回参数 20 | 字段 |字段类型 |字段说明 21 | ------------|-----------|----------- 22 | code |int |状态码 23 | port |int |微信客户端标识 24 | ### 1.6 状态码 25 | 状态码 |说明 26 | ------------|----------- 27 | 1 |成功 28 | 0 |失败 29 | --- 30 | ## 2. 获取登录二维码 31 | ### 2.1 功能描述 32 | 获取微信登录二维码供用户扫码登录 33 | ### 2.2 请求说明 34 | > 请求方式:GET
35 | 请求URL :[/get_login_qrcode/\]() 36 | 37 | ### 2.3 请求参数 38 | 字段 |字段类型 |字段说明 39 | ------------|-----------|----------- 40 | port |int |微信客户端标识 41 | ### 2.4 返回结果 42 | ```json 43 | { 44 | "code": 1, 45 | "qrcode": "iVBORw0KGgoAAAANSUhEUgAAALkAAAC5CAYAAAB0rZ5cAAAOg0lEQVR4Ae3BwZHsypJDwQMa1UHqL0e0QJhZB2sRxma925+W7gLCH5FENJLCTUnEl0kKTRLRSAoDSUQjKTRJxE2Swk1JxICk8EectvnLbPOX2WbCNnfZ5km2+Tbb/BUHGxuvdrCx8WoHGxuvdvJBVfFtay2eVFXcJSkMJBFNVdFJCk0Svk1SGLDNv1BVfNtai+7kM/F94VniJtv8gmhshyvxZbb548T3heZgY+PVDjY2Xu1gY+PVToYkhZuSiJuqirskhSaJeJCk0CShkxRusk0nKTRJeNJai05SaJKImySFm5KIgZMh2/wj4ibbfJttPhCN7fAg23wgnhUa2zzJNt92sLHxagcbG692sLHxaid/nKTQJBE3SQpNEu6qKiaqiom1Fl1VsXHbyR9nmyfZ5gNxn5gRM+FKbNx1sLHxagcbG692sLHxaif/gySFgSTcJSk0SUQjKQwkEY2k0CShkxS+LIl4qZP/QbYZEjfZZsI2d9nmA9HYDht3HWxsvNrBxsarHWxsvNrJUFXxl1UV3yYpNEno1lp0kkJjm05SaGwzUVVMrLXoJIXGNt9WVXzbyZz428SX2eYDcRUa20zY5hfETGhs84+ILzvY2Hi1g42NVzvY2Hi1kw8khS+zzV1VRScpNElEIyk0ScRAVdFJCk0SurUWXVXRrbXoqopurcWEpNAkoVtr0VUV3VqLuySFL7NNd/KBbf440dgOA7b5BdHYDlfiKlyJq3AlrsKAbT4QV+FKXIWbbPMvHGxsvNrBxsarHWxsvNpZVfxlVcVdkkKThImqopMUGtt0kkJjm05SaJLQSQqNbTpJobHNk6qKiarirzgB8beJm2zzgZgRje0wYJsJ23wgGtthwDb/ATEj/oiDjY1XO9jYeLWDjY1XO/kFSaFJIgYkhSaJuKmq6NZadJJCk0QMVBUTay0mqoq7qoqJtRZ3SQoDScSApHBTEtFICgMnv2Cbu2zzMHEVGtv8gpgJM+I+MRNuss2TbPMk20wcbGy82sHGxqsdbGy82skvVBV3VRVPkhSaJDxJUmiSiIGqopMUBmwzISk0SegkhSYJ3VqLCUlhIAn/wsnviPvEg2zzgXiQbX5BNLbDg2zzgWhshytxFQZsMyT+gYONjVc72Nh4tYONjVc7JYWBJOImSWEgiWgkhQHbTEgKTRLxoKqikxSaJHRrLbqq4klVxURVcddai05SaJKIAUmhSUK31qI7bfNttrnLNk+yzX9ANLbDlbgKV+JZYkbcFxrb3GWbD8RVaA42Nl7tYGPj1Q42Nl7t5BckhSaJaKqKCUmhsU1XVXRrLSaqiglJobHNt1UVE5JCk4ROUhhIIh5UVXRrLTpJoUkimqpioqroTn7BNkNiwHaYEVdhRgzY5h8RA7b5QDS2w78hrkJjmyExI5qDjY1XO9jYeLWDjY1XO3mYpNAkEY2k0NjmrqpiQlIYSMKEpNAkETdJCk0SMSApNLZ5kqTQJBGNpNAk4V84eZhtJmzzMDFgmyExYDs8yDZ32ebbbDNhmw/EP3CwsfFqBxsbr3awsfFqJx9UFRNVxYSk0CThSZLCQBK6tRadpNAkEU1V0UkKTRI6SaFJwkRV0a216KqKbq3FXVXFXZJCk0Q0kkKTRDSSwsDJZ2JGDNgOV+JBthkSV6GxzZBobIcr0dgOV2JGXIUrcRXuEzfZZsI2E7aZONjYeLWDjY1XO9jYeLWTIUnhJtt0ksKDbNNVFZ2k0CThSVVFJyk0tukkhZuS0EkKjW06SaFJIgYkhcY2XVXRSQpNEjpJoUlCt9aiOxmyzZNs8x8Qje1wJZ4lGtthwDa/IBrbYcA2d9lmSDS2w5VobIcrcRWag42NVzvY2Hi1g42NVzsZqir+irUW3yYpDCQRf1hV0a21eFJVMSEpNEmYqCo6SaFJQncyJ/6O8GW2eQlxFZ4lBmyHKzEjGtvhSjQHGxuvdrCx8WoHGxuvdlYVnaTQJBGNpNAkEQOSQpNENJJCY5uuqvgXJIUB23RVxcRai66q6CSFgSQ8SVIYSMKEpDCQhIkTEI3tMGCbu2wzYZsh8Q/Y5hfETLgSje0wIx5kmyExYJshMXCwsfFqBxsbr3awsfFqp6TQ2GaiqugkhYEkdJJCY5uuqugkhSaJGJAUGtvcVVV0ay3uqiomqopurUUnKQwkEY2k0NjmLkmhsc1dkkJz2uYXRGM7zIjGdpgRje1wk20eJq7CfWJGXIXGNnfZ5km2eZJtuoONjVc72Nh4tYONjVc7q4oJSaFJIgaqik5SaJIwISk0tpmoKibWWnRVxYSk0CRhQlIYSCIGqopurcW3VRUTVUW31mJCUmhs052AGLAd7hON7XAlBmyH+8RMuBIDtsOVGLDNw8RV+D4xI67CgG0mDjY2Xu1gY+PVDjY2Xu2UFJokYkBSaJIwUVV0ksKAbbqqopMUmiSikRSaJHSSQpNEPKiq6NZadJLCTUno1lpMVBV3SQoDSejWWnRVRbfWojttc5dtPhAzorEd7hON7TBgmw9EYzt8n7gKjW1+QVyFGXGTbYbEVbgSV6E52Nh4tYONjVc72Nh4tZMPJIUmCd1ai05SaJKIRlJobNNVFU+SFBrbTFQVnaTQJOEuSaFJQrfWoqsqJiSFxjadpPAg29xVVXSSQpOE7uQD23wgrkJjmwnbDIkH2eYXRGM7XImbbPOBuApXYsB2GLDNHyIa2+FKNAcbG692sLHxagcbG692VhV3VRUTkkKThG6tRScpDCQRA1VFt9ZiQlJokjAhKQzYZqKqmJAUGtt0VcWT1lp0VcVdkkJjm05SaE5A3CcGbIcrcRUa2zxMXIUB23wgBmzzMDFgmyHxrHAlbrLNhG26g42NVzvY2Hi1g42NVzslhYEkopEUmiRiQFJobNNVFXdVFRNVxV2SwoBtuqqiW2vRSQoDScRNkkKTRDSSQpNEDEgKN9nmrtM2d9nmLtsMifvEjLjJNr8grkJjm2+zzYRt7rLNv3CwsfFqBxsbr3awsfFqZ1XRrbW4S1JobNNVFd1ai2+TFJok4kFVRbfWopMUmiR0ay3uqiq6tRZdVXGXpNDYpqsqurUWXVUxsdZi4gTEVbjJNkPiKnyZbf4D4io0tvlAXIX7xFW4EjfZZkhchSsxEwYONjZe7WBj49UONjZeTUBokvCBuAo3SaKzTffz80OXRAxICk0SOklM2Gbi5+eHLglD4io0ay26n58fJpLwgWgkhSYJE2stuqoSV+FKzIRmrUV32uYDMSNush0GbHOXbT4Qje3wINt8IO4TV6GxzZAYsM0HYibMiPvEVWgONjZe7WBj49UONjZe7awqJiSFgSRioKro1lp0VUUnKTRJxICk0Nimqyom1lp0VUUnKTRJxICk0CShW2txl6TQJKGTFJokYkBSaJKIRlJokoibTkAM2OZh4ipcicZ2uMk2Q2ImXInGdrjJNh+Iq3CTbT4Qje1wk20mbPOkg42NVzvY2Hi1g42NVzslhSaJaKqKbq1FJynclIROUmhs00kKTRK6tRYTkkKTRDRVRScpNLbpJIWBJHSSQpOEbq3Fk6qKTlJoktCttZioKjpJoUkiBk7bDImr0NjmF0RjOwzY5gNxFQZsMyQa22HANkOisR2uxFV4lmhshytxFWZEYzvcdLCx8WoHGxuvdrCx8WpnVdFJCk0S0VQVE2stuqqikxQa23RVxZOqim6txZOqim6tRVdVTFQVd0kKjW06SWHANp2k0NjmrqrirhMQje0wI2bClWhshxnxLHEVniWuwpWYETfZZsI2d9nmYeKmg42NVzvY2Hi1g42NVzslhcY2naRwUxI6SaFJwpMkhcY2E1VFJykMJGGiqugkhSaJaCSFAdt0VcVday2eJCk8KAndaZsJ2/yCaGyHK/Eg2/yCaGyHGTEjGtthwDa/IO4LD7LNw0RzsLHxagcbG692sLHxasr/4/vEVbgSjaRwUxK6tRbdz88PXRJxFZq1Fl1ViUZSaJKIq9BIorNNV1V0ay26qhKNpDBgm66quGutRVdVTKy16H5+fuhOQPwbYsA2vyCuQmObIXEVBmwzJBrbYUZchQHb/IK4L1yJmdDYpjvY2Hi1g42NVzvY2Hi1U1L4I5KIpqro1lp0VcVEVdGttZiQFJokdJJCk4ROUmiSiKaq+LaqoltrcZek0CQRN0kKjW0mTtv8ceIqXIkZcRUGbPOBaGyHK9HYDjPi+8RVuMk2T7LNXQcbG692sLHxagcbG6928kFV8W1rLb5NUhhIwpOqik5SaJIwISkMJBFNVTEhKTRJ6NZaTFQV31ZVTJx8Jr4vfJlthsSzRGM7XIkB2/yCGLDNB+IqzIjvEwMHGxuvdrCx8WoHGxuvdjIkKdyURHyZpNDYZkJSaJKIpqroJIUmiRiQFJokoqkq7pIUBpJwl6Rwk206SaFJQicpNElEczJkm7/MNnfZZkg0tsNNthkSN9lmSNxkmyfZ5gPR2A4DBxsbr3awsfFqBxsbr3byx0kKTRLuWmvRVRV3VRWdpNDY5tskhSYJd0kKjW0mqopurcVEVdFJCo1tOkmhOfnjbPOBuC9ciftEYzv8A7b5QNxkm18QV2FGNLbDgG26g42NVzvY2Hi1g42NVzv546qKCUlhIAkTkkKTRDSSQpOEuySFm5IwISkMJOFJVUW31uKuqqJba9Gd/H1iwDZDYsA2E7b5QNxkO9wnBmwzJJ4lrsJ94io0Bxsbr3awsfFqBxsbr3YyVFX8FZJCY5u7JIXGNndJCgNJxE1VRScpDNhmQlIYSCJuqio6SaFJwkRV0Z3MiT/CNk+yzZNs8x8Qje3wINv8B0RjO1yJGdEcbGy82sHGxqsdbGy82skHksKX2ebbqoonSQpNErq1Fl1VMVFVdGstJqqKb1tr0UkKD0rChKQwcPKBbV5CPMg2H4ircCVmxFWYEd8XGts8TAzYZuJgY+PVDjY2Xu1gY+PV/g8/WblifiTBwQAAAABJRU5ErkJggg==" 46 | } 47 | ``` 48 | ### 2.5 返回参数 49 | 字段 |字段类型 |字段说明 50 | ------------|-----------|----------- 51 | code |int |状态码 52 | qrcode |string |登录二维码base64编码字符串 53 | ### 2.6 状态码 54 | 状态码 |说明 55 | ------------|----------- 56 | 0 |获取二维码超时 57 | -1 |port错误 58 | 1 |成功 59 | --- 60 | ## 3. 登出微信 61 | ### 3.1 功能描述 62 | 用户主动退出PC微信客户端登录 63 | ### 3.2 请求说明 64 | > 请求方式:GET
65 | 请求URL :[/user_logout/\]() 66 | 67 | ### 3.3 请求参数 68 | 字段 |字段类型 |字段说明 69 | ------------|-----------|----------- 70 | port |int |微信客户端标识 71 | ### 3.4 返回结果 72 | ```json 73 | { 74 | "code": 1 75 | } 76 | ``` 77 | ### 3.5 返回参数 78 | 字段 |字段类型 |字段说明 79 | ------------|-----------|----------- 80 | code |int |状态码 81 | ### 3.6 状态码 82 | 状态码 |说明 83 | ------------|----------- 84 | 0 |失败 85 | -1 |port错误 86 | 1 |成功 87 | --- 88 | ## 4. 关闭微信客户端 89 | ### 4.1 功能描述 90 | 用户关闭服务器上的微信客户端 91 | ### 4.2 请求说明 92 | > 请求方式:GET
93 | 请求URL :[/close_wechat/\]() 94 | 95 | ### 4.3 请求参数 96 | 字段 |字段类型 |字段说明 97 | ------------|-----------|----------- 98 | port |int |微信客户端标识 99 | ### 4.4 返回结果 100 | ```json 101 | { 102 | "code": 1 103 | } 104 | ``` 105 | ### 4.5 返回参数 106 | 字段 |字段类型 |字段说明 107 | ------------|-----------|----------- 108 | code |int |状态码 109 | ### 4.6 状态码 110 | 状态码 |说明 111 | ------------|----------- 112 | 0 |失败 113 | -1 |port错误 114 | 1 |成功 115 | --- 116 | ## 5. 获取微信登录状态 117 | ### 5.1 功能描述 118 | 获取微信登录状态 119 | ### 5.2 请求说明 120 | > 请求方式:GET
121 | 请求URL :[/get_login_status/\]() 122 | 123 | ### 5.3 请求参数 124 | 字段 |字段类型 |字段说明 125 | ------------|-----------|----------- 126 | port |int |微信客户端标识 127 | ### 5.4 返回结果 128 | ```json 129 | { 130 | "code": 1, 131 | "status": "0" 132 | } 133 | ``` 134 | ### 5.5 返回参数 135 | 字段 |字段类型 |字段说明 136 | ------------|-----------|----------- 137 | code |int |状态码 138 | status |string |登录状态 "0":未登录/'1":登录 139 | ### 5.6 状态码 140 | 状态码 |说明 141 | ------------|----------- 142 | 0 |获取二维码超时 143 | -1 |port错误 144 | 1 |成功 145 | --- 146 | ## 6. 获取登录信息 147 | ### 6.1 功能描述 148 | 获取用户当前登录微信账号基本信息 149 | ### 6.2 请求说明 150 | > 请求方式:GET
151 | 请求URL :[/get_login_info/\]() 152 | 153 | ### 6.3 请求参数 154 | 字段 |字段类型 |字段说明 155 | ------------|-----------|----------- 156 | port |int |微信客户端标识 157 | ### 6.4 返回结果 158 | ```json 159 | { 160 | "code": 1, 161 | "wxid": "", 162 | "nickname":"", 163 | "wechatid":"", 164 | "profile_photo_hd":"", 165 | "profile_photo":"", 166 | "phone":"", 167 | "sex":"" 168 | } 169 | ``` 170 | ### 6.5 返回参数 171 | 字段 |字段类型 |字段说明 172 | ------------|-----------|----------- 173 | code |int |状态码 174 | wxid |string |微信唯一标识 175 | nickname |string |昵称 176 | wechatid |string |微信号 177 | profile_photo_hd |string |高清头像url 178 | profile_photo |string |头像url 179 | phone |string |手机号 180 | sex |string |性别 181 | ### 6.6 状态码 182 | 状态码 |说明 183 | ------------|----------- 184 | 0 |获取登录信息超时 185 | -1 |port错误 186 | 1 |成功 187 | --- 188 | ## 7. 获取联系人列表 189 | ### 7.1 功能描述 190 | 获取微信联系人列表,包括好友与群 191 | ### 7.2 请求说明 192 | > 请求方式:GET
193 | 请求URL :[/get_contact_list/\]() 194 | 195 | ### 7.3 请求参数 196 | 字段 |字段类型 |字段说明 197 | ------------|-----------|----------- 198 | port |int |微信客户端标识 199 | ### 7.4 返回结果 200 | ```json 201 | { 202 | "code": 1, 203 | "contacts": [{"wxid":"", "nickname":"", "remark":""},.....] 204 | } 205 | ``` 206 | ### 7.5 返回参数 207 | 字段 |字段类型 |字段说明 208 | ------------|-----------|----------- 209 | code |int |状态码 210 | contacts |list |联系人列表 211 | 212 | 字段 |字段类型 |字段说明 213 | ------------|-----------|----------- 214 | wxid |string |联系人微信唯一标识 215 | nickname |string |联系人昵称 216 | remark |string |联系人备注 217 | 218 | ### 7.6 状态码 219 | 状态码 |说明 220 | ------------|----------- 221 | 0 |获取联系人列表超时 222 | -1 |port错误 223 | 1 |成功 224 | --- 225 | ## 8. 获取联系人详情 226 | ### 8.1 功能描述 227 | 获取联系人、群成员详情或获取群成员列表 228 | ### 8.2 请求说明 229 | > 请求方式:POST(json)
230 | 请求URL :[/get_contact_details/\]() 231 | 232 | ### 8.3 请求参数 233 | 字段 |字段类型 |字段说明 234 | ------------|-----------|----------- 235 | port |int |微信客户端标识 236 | wxid |string |联系人唯一标识 237 | ### 8.4 返回结果 238 | ```json 239 | { 240 | "code": 1, 241 | "wxid": "", 242 | "nickname":"", 243 | "remark":"", 244 | "profile_photo:"", 245 | "is_group":False, 246 | "group_owner":"", 247 | "group_member_count":0, 248 | "group_members":[{"wxid":"", "nickname":""},......] 249 | } 250 | ``` 251 | ### 8.5 返回参数 252 | 字段 |字段类型 |字段说明 253 | ------------|-----------|----------- 254 | code |int |状态码 255 | wxid |string |联系人唯一标识 256 | nickname |string |联系人昵称 257 | remark |string |联系人备注 258 | profile_photo |string |联系人头像 259 | is_group |bool |该联系人是否为群聊 260 | group_owner |string |群主 261 | group_member_count |int |群成员数量 262 | group_members |list |群成员列表 263 | 264 | 字段 |字段类型 |字段说明 265 | ------------|-----------|----------- 266 | wxid |string |群成员微信唯一标识 267 | nickname |string |群成员微信昵称 268 | ### 8.6 状态码 269 | 状态码 |说明 270 | ------------|----------- 271 | 0 |获取联系人详情超时 272 | -1 |port错误 273 | -2 |请求参数提交模式错误,应当以json提交 274 | -3 |请求参数缺失 275 | 1 |成功 276 | --- 277 | ## 9. 发送文本 278 | ### 9.1 功能描述 279 | 发送文本消息给指定联系人 280 | ### 9.2 请求说明 281 | > 请求方式:POST(json)
282 | 请求URL :[/send_text/\]() 283 | 284 | ### 9.3 请求参数 285 | 字段 |字段类型 |字段说明 286 | ------------|-----------|----------- 287 | port |int |微信客户端标识 288 | wxid |string |消息接收方唯一标识 289 | text |string |消息内容 290 | at_wxid |string |消息需@提醒人唯一标识 291 | ### 9.4 返回结果 292 | ```json 293 | { 294 | "code": 1 295 | } 296 | ``` 297 | ### 9.5 返回参数 298 | 字段 |字段类型 |字段说明 299 | ------------|-----------|----------- 300 | code |int |状态码 301 | ### 9.6 状态码 302 | 状态码 |说明 303 | ------------|----------- 304 | 0 |失败 305 | -1 |port错误 306 | -2 |请求参数提交模式错误,应当以json提交 307 | -3 |请求参数缺失 308 | 1 |成功 309 | --- 310 | ## 10. 发送文件 311 | ### 10.1 功能描述 312 | 发送文件、图片消息 313 | ### 10.2 请求说明 314 | > 请求方式:POST(form)
315 | 请求URL :[/send_file/\]() 316 | 317 | ### 10.3 请求参数 318 | 字段 |字段类型 |字段说明 319 | ------------|-----------|----------- 320 | port |int |微信客户端标识 321 | wxid |string |消息接收方唯一标识 322 | file |file |文件 323 | ### 10.4 返回结果 324 | ```json 325 | { 326 | "code": 1 327 | } 328 | ``` 329 | ### 10.5 返回参数 330 | 字段 |字段类型 |字段说明 331 | ------------|-----------|----------- 332 | code |int |状态码 333 | ### 10.6 状态码 334 | 状态码 |说明 335 | ------------|----------- 336 | 0 |失败 337 | -1 |port错误 338 | -4 |请求参数提交模式错误,应当以表单提交 339 | -3 |请求参数缺失 340 | 1 |成功 341 | --- 342 | ## 11. 发布群公告 343 | ### 11.1 功能描述 344 | 发布群公告 345 | ### 11.2 请求说明 346 | > 请求方式:POST(json)
347 | 请求URL :[/send_announcement/\]() 348 | 349 | ### 11.3 请求参数 350 | 字段 |字段类型 |字段说明 351 | ------------|-----------|----------- 352 | port |int |微信客户端标识 353 | wxid |string |群唯一标识 354 | text |string |群公告内容 355 | ### 11.4 返回结果 356 | ```json 357 | { 358 | "code": 1 359 | } 360 | ``` 361 | ### 11.5 返回参数 362 | 字段 |字段类型 |字段说明 363 | ------------|-----------|----------- 364 | code |int |状态码 365 | ### 11.6 状态码 366 | 状态码 |说明 367 | ------------|----------- 368 | 0 |失败 369 | -1 |port错误 370 | -2 |请求参数提交模式错误,应当以json提交 371 | -3 |请求参数缺失 372 | 1 |成功 373 | --- 374 | ## 12. 接收好友请求 375 | ### 12.1 功能描述 376 | 通过新联系人好友验证 377 | ### 12.2 请求说明 378 | > 请求方式:POST(json)
379 | 请求URL :[/verify_new_contact/\]() 380 | 381 | ### 12.3 请求参数 382 | 字段 |字段类型 |字段说明 383 | ------------|-----------|----------- 384 | port |int |微信客户端标识 385 | encryptusername |string |好友验证参数1 386 | ticket |string |好友验证参数2 387 | ### 12.4 返回结果 388 | ```json 389 | { 390 | "code": 1 391 | } 392 | ``` 393 | ### 12.5 返回参数 394 | 字段 |字段类型 |字段说明 395 | ------------|-----------|----------- 396 | code |int |状态码 397 | ### 12.6 状态码 398 | 状态码 |说明 399 | ------------|----------- 400 | 0 |失败 401 | -1 |port错误 402 | -2 |请求参数提交模式错误,应当以json提交 403 | -3 |请求参数缺失 404 | 1 |成功 405 | --- 406 | ## 13. 设置联系人备注 407 | ### 13.1 功能描述 408 | 设置、修改联系人备注 409 | ### 13.2 请求说明 410 | > 请求方式:POST(json)
411 | 请求URL :[/set_remark/\]() 412 | 413 | ### 13.3 请求参数 414 | 字段 |字段类型 |字段说明 415 | ------------|-----------|----------- 416 | port |int |微信客户端标识 417 | wxid |string |联系人唯一标识 418 | remark |string |备注 419 | ### 13.4 返回结果 420 | ```json 421 | { 422 | "code": 1 423 | } 424 | ``` 425 | ### 13.5 返回参数 426 | 字段 |字段类型 |字段说明 427 | ------------|-----------|----------- 428 | code |int |状态码 429 | ### 13.6 状态码 430 | 状态码 |说明 431 | ------------|----------- 432 | 0 |失败 433 | -1 |port错误 434 | -2 |请求参数提交模式错误,应当以json提交 435 | -3 |请求参数缺失 436 | 1 |成功 437 | --- 438 | ## 14. 分享群聊 439 | ### 14.1 功能描述 440 | 发送群聊邀请链接给指定好友 441 | ### 14.2 请求说明 442 | > 请求方式:POST(json)
443 | 请求URL :[/share_chatroom/\]() 444 | 445 | ### 14.3 请求参数 446 | 字段 |字段类型 |字段说明 447 | ------------|-----------|----------- 448 | port |int |微信客户端标识 449 | wxid |string |好友唯一标识 450 | group_wxid |string |群聊唯一标识 451 | ### 14.4 返回结果 452 | ```json 453 | { 454 | "code": 1 455 | } 456 | ``` 457 | ### 14.5 返回参数 458 | 字段 |字段类型 |字段说明 459 | ------------|-----------|----------- 460 | code |int |状态码 461 | ### 14.6 状态码 462 | 状态码 |说明 463 | ------------|----------- 464 | 0 |失败 465 | -1 |port错误 466 | -2 |请求参数提交模式错误,应当以json提交 467 | -3 |请求参数缺失 468 | 1 |成功 469 | --- 470 | ## 15. 移除群成员 471 | ### 15.1 功能描述 472 | 从群聊中将指定群成员移出该群 473 | ### 15.2 请求说明 474 | > 请求方式:POST(json)
475 | 请求URL :[/remove_chatroom_member/\]() 476 | 477 | ### 15.3 请求参数 478 | 字段 |字段类型 |字段说明 479 | ------------|-----------|----------- 480 | port |int |微信客户端标识 481 | group_wxid |string |群聊唯一标识 482 | wxid |string |群成员唯一标识 483 | ### 15.4 返回结果 484 | ```json 485 | { 486 | "code": 1 487 | } 488 | ``` 489 | ### 15.5 返回参数 490 | 字段 |字段类型 |字段说明 491 | ------------|-----------|----------- 492 | code |int |状态码 493 | ### 15.6 状态码 494 | 状态码 |说明 495 | ------------|----------- 496 | 0 |失败 497 | -1 |port错误 498 | -2 |请求参数提交模式错误,应当以json提交 499 | -3 |请求参数缺失 500 | 1 |成功 501 | --- 502 | ## 16. 移除联系人 503 | ### 16.1 功能描述 504 | 删除指定好友 505 | ### 16.2 请求说明 506 | > 请求方式:POST(json)
507 | 请求URL :[/remove_contact/\]() 508 | 509 | ### 16.3 请求参数 510 | 字段 |字段类型 |字段说明 511 | ------------|-----------|----------- 512 | port |int |微信客户端标识 513 | wxid |string |好友唯一标识 514 | ### 16.4 返回结果 515 | ```json 516 | { 517 | "code": 1 518 | } 519 | ``` 520 | ### 16.5 返回参数 521 | 字段 |字段类型 |字段说明 522 | ------------|-----------|----------- 523 | code |int |状态码 524 | ### 16.6 状态码 525 | 状态码 |说明 526 | ------------|----------- 527 | 0 |失败 528 | -1 |port错误 529 | -2 |请求参数提交模式错误,应当以json提交 530 | -3 |请求参数缺失 531 | 1 |成功 532 | --- 533 | ## 17. 发送小程序 534 | ### 17.1 功能描述 535 | 发送小程序给指定联系人 536 | ### 17.2 请求说明 537 | > 请求方式:POST(form)
538 | 请求URL :[/send_mini_program/\]() 539 | 540 | ### 17.3 请求参数 541 | 字段 |字段类型 |字段说明 542 | ------------|-----------|----------- 543 | port |int |微信客户端标识 544 | wxid |string |联系人唯一标识 545 | title |string |小程序标题 546 | app_id |string |小程序id 547 | route |string |小程序路由 548 | username |string |小程序用户名 549 | weappiconurl|string |小程序图标url 550 | appname |string |小程序名称 551 | ### 17.4 返回结果 552 | ```json 553 | { 554 | "code": 1 555 | } 556 | ``` 557 | ### 17.5 返回参数 558 | 字段 |字段类型 |字段说明 559 | ------------|-----------|----------- 560 | code |int |状态码 561 | ### 17.6 状态码 562 | 状态码 |说明 563 | ------------|----------- 564 | 0 |失败 565 | -1 |port错误 566 | -4 |请求参数提交模式错误,应当以表单提交 567 | -3 |请求参数缺失 568 | 1 |成功 569 | --- 570 | ## 18. 发送链接卡片 571 | ### 18.1 功能描述 572 | 发送链接卡片给指定联系人 573 | ### 18.2 请求说明 574 | > 请求方式:POST(form)
575 | 请求URL :[/send_link_card/\]() 576 | 577 | ### 18.3 请求参数 578 | 字段 |字段类型 |字段说明 579 | ------------|-----------|----------- 580 | port |int |微信客户端标识 581 | wxid |string |联系人唯一标识 582 | title |string |链接卡片标题 583 | desc |string |链接卡片描述 584 | url |string |链接卡片链接 585 | app_id |string |链接卡片id 586 | ### 18.4 返回结果 587 | ```json 588 | { 589 | "code": 1 590 | } 591 | ``` 592 | ### 18.5 返回参数 593 | 字段 |字段类型 |字段说明 594 | ------------|-----------|----------- 595 | code |int |状态码 596 | ### 18.6 状态码 597 | 状态码 |说明 598 | ------------|----------- 599 | 0 |失败 600 | -1 |port错误 601 | -4 |请求参数提交模式错误,应当以表单提交 602 | -3 |请求参数缺失 603 | 1 |成功 604 | --- 605 | ## 19. 解密图片 606 | ### 19.1 功能描述 607 | 将接收到的图片解密成jpg格式 608 | ### 19.2 请求说明 609 | > 请求方式:POST(json)
610 | 请求URL :[/decrypt_image/\]() 611 | 612 | ### 19.3 请求参数 613 | 字段 |字段类型 |字段说明 614 | ------------|-----------|----------- 615 | port |int |微信客户端标识 616 | filename |string |图片加密文件名称 617 | ### 19.4 返回结果 618 | 解密后图片bytes 619 | ### 19.5 返回参数 620 | 621 | ### 19.6 状态码 622 | 623 | --- 624 | ## 20. 新建群聊 625 | ### 20.1 功能描述 626 | 创建一个新的群聊 627 | ### 20.2 请求说明 628 | > 请求方式:POST(json)
629 | 请求URL :[/create_chatroom/\]() 630 | 631 | ### 20.3 请求参数 632 | 字段 |字段类型 |字段说明 633 | ------------|-----------|----------- 634 | port |int |微信客户端标识 635 | wxids |string |联系人wxid合集字符串 ","分隔 636 | ### 20.4 返回结果 637 | ```json 638 | { 639 | "code": 1, 640 | "wxid": "" 641 | } 642 | ``` 643 | ### 20.5 返回参数 644 | 字段 |字段类型 |字段说明 645 | ------------|-----------|----------- 646 | code |int |状态码 647 | wxid |string |新群聊唯一标识 648 | ### 20.6 状态码 649 | 状态码 |说明 650 | ------------|----------- 651 | 0 |失败 652 | -1 |port错误 653 | -2 |请求参数提交模式错误,应当以json提交 654 | -3 |请求参数缺失 655 | 1 |成功 656 | --- 657 | ## 21. 设置群聊名称 658 | ### 21.1 功能描述 659 | 设置、修改群聊名称 660 | ### 21.2 请求说明 661 | > 请求方式:POST(json)
662 | 请求URL :[/set_chatroom_name/\]() 663 | 664 | ### 21.3 请求参数 665 | 字段 |字段类型 |字段说明 666 | ------------|-----------|----------- 667 | port |int |微信客户端标识 668 | wxid |string |群聊唯一标识 669 | name |string |群聊名称 670 | ### 21.4 返回结果 671 | ```json 672 | { 673 | "code": 1 674 | } 675 | ``` 676 | ### 21.5 返回参数 677 | 字段 |字段类型 |字段说明 678 | ------------|-----------|----------- 679 | code |int |状态码 680 | ### 21.6 状态码 681 | 状态码 |说明 682 | ------------|----------- 683 | 0 |失败 684 | -1 |port错误 685 | -2 |请求参数提交模式错误,应当以json提交 686 | -3 |请求参数缺失 687 | 1 |成功 688 | --- -------------------------------------------------------------------------------- /Library/PyWeChatSpy/service/__init__.py: -------------------------------------------------------------------------------- 1 | from .app import * 2 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/service/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from ..spy import WeChatSpy 3 | from queue import Queue 4 | from threading import Thread 5 | from ..proto.spy_pb2 import Response, ChatMessage 6 | from ..command import * 7 | from .config import MESSAGE_CALLBACK 8 | import requests 9 | 10 | 11 | class SpyService(Flask): 12 | def __init__(self, import_name, 13 | static_url_path=None, 14 | static_folder="static", 15 | static_host=None, 16 | host_matching=False, 17 | subdomain_matching=False, 18 | template_folder="templates", 19 | instance_path=None, 20 | instance_relative_config=False, 21 | root_path=None, 22 | key=None): 23 | self.last_client_count = 0 24 | self.response_queue = Queue() 25 | self.client2pid = dict() 26 | self.client2wxid = dict() 27 | self.client2login = dict() 28 | self.client2user_logout = dict() 29 | self.client2response = dict() 30 | self.__chat_message = [] 31 | self.spy = WeChatSpy(response_queue=self.response_queue, key=key) 32 | super().__init__(import_name, 33 | static_url_path=static_url_path, 34 | static_folder=static_folder, 35 | static_host=static_host, 36 | host_matching=host_matching, 37 | subdomain_matching=subdomain_matching, 38 | template_folder=template_folder, 39 | instance_path=instance_path, 40 | instance_relative_config=instance_relative_config, 41 | root_path=root_path) 42 | t = Thread(target=self.parse) 43 | t.setDaemon(True) 44 | t.start() 45 | 46 | def parse(self): 47 | while True: 48 | data = self.response_queue.get() 49 | if data.type == WECHAT_CONNECTED: 50 | self.client2pid[data.port] = data.pid 51 | self.client2login[data.port] = "0" 52 | elif data.type == WECHAT_DISCONNECT: 53 | self.last_client_count -= 1 54 | elif data.type == WECHAT_LOGIN: 55 | self.client2login[data.port] = "1" 56 | elif data.type == WECHAT_LOGOUT: 57 | self.client2login[data.port] = "0" 58 | elif data.type == CHAT_MESSAGE: 59 | self.__chat_message.append(data) 60 | elif data.type != HEART_BEAT: 61 | if data.type == GET_LOGIN_QRCODE and data.code: 62 | continue 63 | elif data.type == GET_CONTACTS_LIST and data.code: 64 | continue 65 | elif data.type == SEND_TEXT and data.code: 66 | continue 67 | elif data.type == SEND_FILE and data.code: 68 | continue 69 | elif data.type == SEND_MINI_PROGRAM and data.code: 70 | continue 71 | elif data.type == SEND_LINK_CARD and data.code: 72 | continue 73 | elif data.type == CREATE_CHATROOM and data.code: 74 | continue 75 | self.client2response[data.id] = data 76 | 77 | def push_message(self): 78 | while True: 79 | message_data: Response = self.__chat_message.pop() 80 | message_port = message_data.port 81 | chat_message = ChatMessage() 82 | chat_message.ParseFromString(message_data.bytes) 83 | post_data = { 84 | "port": message_port, 85 | "messages": [] 86 | } 87 | for message in chat_message.message: 88 | _from = message.wxidFrom.str # 消息发送方 89 | _from_group_member = "" 90 | if _from.endswith("@chatroom"): # 群聊消息 91 | _from_group_member = message.content.str.split(':\n', 1)[0] # 群内发言人 92 | content = message.content.str.split(':\n', 1)[-1] # 群聊消息内容 93 | _file = message.file 94 | post_data["messages"].append({ 95 | "type": message.type, 96 | "from": _from, 97 | "to": message.wxidTo.str, 98 | "from_group_member": _from_group_member, 99 | "content": message.content.str, 100 | "timestamp": message.timestamp, 101 | "file": _file 102 | }) 103 | try: 104 | requests.post(MESSAGE_CALLBACK, json=post_data) 105 | except Exception as e: 106 | print(e) 107 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/service/config.py: -------------------------------------------------------------------------------- 1 | MESSAGE_CALLBACK = "" 2 | -------------------------------------------------------------------------------- /Library/PyWeChatSpy/spy.py: -------------------------------------------------------------------------------- 1 | import os 2 | from socket import socket, AF_INET, SOCK_STREAM 3 | from threading import Thread 4 | import logging 5 | from .proto import spy_pb2 6 | from .command import * 7 | import subprocess 8 | from queue import Queue 9 | from uuid import uuid4 10 | import sys 11 | 12 | 13 | if not sys.version >= "3.8": 14 | logging.error("微信版本过低,请使用Python3.8.x或更高版本") 15 | exit() 16 | 17 | 18 | class WeChatSpy: 19 | def __init__(self, response_queue=None, key: str = None, logger: logging.Logger = None): 20 | # 付费key 21 | self.__key = key 22 | # 日志模块 23 | if isinstance(logger, logging.Logger): 24 | # 使用自定义logger 25 | self.logger = logger 26 | else: 27 | # 使用默认logger 28 | self.logger = logging.getLogger(__file__) 29 | formatter = logging.Formatter('%(asctime)s [%(threadName)s] %(levelname)s: %(message)s') 30 | sh = logging.StreamHandler() 31 | sh.setFormatter(formatter) 32 | sh.setLevel(logging.DEBUG) 33 | self.logger.addHandler(sh) 34 | self.logger.setLevel(logging.DEBUG) 35 | # response存放队列 36 | if isinstance(response_queue, Queue): 37 | self.__response_queue = response_queue 38 | else: 39 | raise Exception("response_queue must be Queue") 40 | self.pids = [] 41 | self.port2client = dict() 42 | host = "127.0.0.1" 43 | port = 9527 44 | self.__socket_server = socket(AF_INET, SOCK_STREAM) 45 | self.__socket_server.bind((host, port)) 46 | self.__socket_server.listen(1) 47 | t_start_server = Thread(target=self.__start_server) 48 | t_start_server.daemon = True 49 | t_start_server.name = "spy" 50 | t_start_server.start() 51 | current_path = os.path.split(os.path.abspath(__file__))[0] 52 | helper_path = os.path.join(current_path, "SpyK.exe") 53 | if not os.path.exists(helper_path): 54 | self.logger.error("请检查文件 SpyK.exe 是否被误删") 55 | exit(-1) 56 | subprocess.Popen(f"{helper_path} 3.0") 57 | 58 | def __start_server(self): 59 | while True: 60 | socket_client, client_address = self.__socket_server.accept() 61 | self.port2client[client_address[1]] = socket_client 62 | self.logger.debug(f"A WeChat process from {client_address} successfully connected") 63 | if self.__key: 64 | self.set_commercial(self.__key, port=client_address[1]) 65 | t_socket_client_receive = Thread(target=self.receive, args=(socket_client, client_address)) 66 | t_socket_client_receive.name = f"wechat {client_address}" 67 | t_socket_client_receive.daemon = True 68 | t_socket_client_receive.start() 69 | 70 | def receive(self, socket_client: socket, client_address: tuple): 71 | recv_bytes = b"" 72 | data_size = 0 73 | while True: 74 | try: 75 | _bytes = socket_client.recv(4096) 76 | except Exception as e: 77 | self.port2client.pop(client_address[1]) 78 | response = spy_pb2.Response() 79 | response.type = WECHAT_DISCONNECT 80 | response.port = client_address[1] 81 | self.__response_queue.put(response) 82 | return self.logger.warning(f"The WeChat process has disconnected: {e}") 83 | recv_bytes += _bytes 84 | while True: 85 | if not data_size: 86 | if len(recv_bytes) > 3: 87 | data_size = int.from_bytes(recv_bytes[:4], "little") 88 | else: 89 | break 90 | elif data_size <= len(recv_bytes) - 4: 91 | response = spy_pb2.Response() 92 | response.ParseFromString(recv_bytes[4: data_size + 4]) 93 | response.port = client_address[1] 94 | self.__response_queue.put(response) 95 | recv_bytes = recv_bytes[data_size + 4:] 96 | data_size = 0 97 | else: 98 | break 99 | 100 | def __send(self, request: spy_pb2.Request, port: int = 0, _id: str = None): 101 | if not port and self.port2client: 102 | socket_client: socket = list(self.port2client.values())[0] 103 | elif not (socket_client := self.port2client.get(port)): 104 | self.logger.error(f"Failure to find socket client by port:{port}") 105 | return False 106 | request.id = _id or uuid4().__str__() 107 | data = request.SerializeToString() 108 | data_length_bytes = int.to_bytes(len(data), length=4, byteorder="little") 109 | try: 110 | socket_client.send(data_length_bytes + data) 111 | return True 112 | except Exception as e: 113 | self.logger.warning(f"The WeChat process {port} has disconnected: {e}") 114 | return False 115 | 116 | def run(self, wechat: str): 117 | sp = subprocess.Popen(wechat) 118 | self.pids.append(sp.pid) 119 | return sp.pid 120 | 121 | def set_commercial(self, key: str, port: int = 0, _id: str = None): 122 | request = spy_pb2.Request() 123 | request.type = PROFESSIONAL_KEY 124 | request.bytes = bytes(key, encoding="utf8") 125 | return self.__send(request, port, _id) 126 | 127 | def get_account_details(self, port: int = 0, _id: str = None): 128 | request = spy_pb2.Request() 129 | request.type = GET_ACCOUNT_DETAILS 130 | return self.__send(request, port, _id) 131 | 132 | def get_contacts(self, port: int = 0, _id: str = None): 133 | request = spy_pb2.Request() 134 | request.type = GET_CONTACTS_LIST 135 | return self.__send(request, port, _id) 136 | 137 | def get_contact_details(self, wxid: str, port: int = 0, _id: str = None): 138 | request = spy_pb2.Request() 139 | request.type = GET_CONTACT_DETAILS 140 | request.bytes = bytes(wxid, encoding="utf8") 141 | return self.__send(request, port, _id) 142 | 143 | def send_text(self, wxid: str, text: str, at_wxid: str = "", port: int = 0, _id: str = None): 144 | if not wxid.endswith("chatroom"): 145 | at_wxid = "" 146 | request = spy_pb2.Request() 147 | request.type = SEND_TEXT 148 | text_message = spy_pb2.TextMessage() 149 | text_message.wxid = wxid 150 | text_message.wxidAt = at_wxid 151 | text_message.text = text 152 | request.bytes = text_message.SerializeToString() 153 | return self.__send(request, port, _id) 154 | 155 | def send_file(self, wxid: str, file_path: str, port: int = 0, _id: str = None): 156 | if not os.path.exists(file_path): 157 | self.logger.error(f"File Not Found {file_path}") 158 | return False 159 | if len(file_path.split("\\")) > 8: 160 | self.logger.error(f"File path is too long: {file_path}") 161 | return False 162 | request = spy_pb2.Request() 163 | request.type = SEND_FILE 164 | file_message = spy_pb2.FileMessage() 165 | file_message.wxid = wxid 166 | file_message.filePath = file_path 167 | request.bytes = file_message.SerializeToString() 168 | return self.__send(request, port, _id) 169 | 170 | def user_logout(self, port: int = 0, _id: str = None): 171 | request = spy_pb2.Request() 172 | request.type = USER_LOGOUT 173 | return self.__send(request, port, _id) 174 | 175 | def accept_new_contact(self, encryptusername: str, ticket: str, port: int = 0, _id: str = None): 176 | request = spy_pb2.Request() 177 | request.type = ACCEPT_NEW_CONTACT 178 | application = spy_pb2.ContactApplication() 179 | application.encryptusername = encryptusername 180 | application.ticket = ticket 181 | request.bytes = application.SerializeToString() 182 | return self.__send(request, port, _id) 183 | 184 | def send_announcement(self, wxid: str, content: str, port: int = 0, _id: str = None): 185 | if not wxid.endswith("chatroom"): 186 | return self.logger.warning("Can only send announcements to chatrooms") 187 | request = spy_pb2.Request() 188 | request.type = SEND_ANNOUNCEMENT 189 | text_message = spy_pb2.TextMessage() 190 | text_message.wxid = wxid 191 | text_message.text = content 192 | request.bytes = text_message.SerializeToString() 193 | return self.__send(request, port, _id) 194 | 195 | def create_chatroom(self, wxid: str, port: int = 0, _id: str = None): 196 | if len(wxid.split(",")) < 2: 197 | return self.logger.warning("This function requires at least two wxids separated by ','") 198 | request = spy_pb2.Request() 199 | request.type = CREATE_CHATROOM 200 | request.bytes = bytes(wxid, encoding="utf8") 201 | return self.__send(request, port, _id) 202 | 203 | def share_chatroom(self, chatroom_wxid: str, wxid: str, port: int = 0, _id: str = None): 204 | request = spy_pb2.Request() 205 | request.type = SHARE_CHATROOM 206 | text_message = spy_pb2.TextMessage() 207 | text_message.wxid = wxid 208 | text_message.text = chatroom_wxid 209 | request.bytes = text_message.SerializeToString() 210 | return self.__send(request, port, _id) 211 | 212 | def remove_chatroom_member(self, chatroom_wxid: str, wxid: str, port: int = 0, _id: str = None): 213 | request = spy_pb2.Request() 214 | request.type = REMOVE_CHATROOM_MEMBER 215 | text_message = spy_pb2.TextMessage() 216 | text_message.wxid = wxid 217 | text_message.text = chatroom_wxid 218 | request.bytes = text_message.SerializeToString() 219 | return self.__send(request, port, _id) 220 | 221 | def remove_contact(self, wxid: str, port: int = 0, _id: str = None): 222 | request = spy_pb2.Request() 223 | request.type = REMOVE_CONTACT 224 | request.bytes = bytes(wxid, encoding="utf8") 225 | return self.__send(request, port, _id) 226 | 227 | def send_mini_program(self, wxid: str, title: str, image_path: str, route: str, app_id: str, 228 | username: str, weappiconurl: str, appname: str, port: int = 0, _id: str = None): 229 | if not os.path.exists(image_path): 230 | self.logger.error(f"Image Not Found {image_path}") 231 | return False 232 | request = spy_pb2.Request() 233 | request.type = SEND_MINI_PROGRAM 234 | xml = spy_pb2.XmlMessage() 235 | xml.wxid = wxid 236 | xml.title = title 237 | xml.appId = app_id 238 | xml.imagePath = image_path 239 | xml.route = route 240 | xml.username = username 241 | xml.weappiconurl = weappiconurl 242 | xml.appname = appname 243 | request.bytes = xml.SerializeToString() 244 | return self.__send(request, port, _id) 245 | 246 | def send_link_card(self, wxid: str, title: str, desc: str, app_id: str, 247 | url: str, image_path: str, port: int = 0, _id: str = None): 248 | if not os.path.exists(image_path): 249 | self.logger.error(f"Image Not Found {image_path}") 250 | return False 251 | request = spy_pb2.Request() 252 | request.type = SEND_LINK_CARD 253 | xml = spy_pb2.XmlMessage() 254 | xml.wxid = wxid 255 | xml.title = title 256 | xml.desc = desc 257 | xml.url = url 258 | xml.appId = app_id 259 | xml.imagePath = image_path 260 | request.bytes = xml.SerializeToString() 261 | return self.__send(request, port, _id) 262 | 263 | def add_contact(self, wxid: str, chatroom_wxid: str = "", greeting: str = "", 264 | add_type: int = 0, port: int = 0, _id: str = None): 265 | # TODO: 266 | request = spy_pb2.Request() 267 | request.cmd = add_type 268 | request.param1 = wxid 269 | if add_type == 1 and not chatroom_wxid: 270 | return 271 | request.param2 = chatroom_wxid 272 | request.param3 = greeting 273 | return self.__send(request, port, _id) 274 | 275 | def get_contact_status(self, wxid: str, port: int = 0, _id: str = None): 276 | request = spy_pb2.Request() 277 | request.type = GET_CONTACT_STATUS 278 | request.bytes = bytes(wxid, encoding="utf8") 279 | return self.__send(request, port, _id) 280 | 281 | def set_chatroom_name(self, wxid: str, name: str, port: int = 0, _id: str = None): 282 | request = spy_pb2.Request() 283 | request.type = SET_CHATROOM_NAME 284 | text_message = spy_pb2.TextMessage() 285 | text_message.wxid = wxid 286 | text_message.text = name 287 | request.bytes = text_message.SerializeToString() 288 | return self.__send(request, port, _id) 289 | 290 | def get_login_qrcode(self, port: int = 0, _id: str = None): 291 | request = spy_pb2.Request() 292 | request.type = GET_LOGIN_QRCODE 293 | return self.__send(request, port, _id) 294 | 295 | def set_remark(self, wxid: str, remark: str, port: int = 0, _id: str = None): 296 | request = spy_pb2.Request() 297 | request.type = SET_REMARK 298 | text_message = spy_pb2.TextMessage() 299 | text_message.wxid = wxid 300 | text_message.text = remark 301 | request.bytes = text_message.SerializeToString() 302 | return self.__send(request, port, _id) 303 | 304 | def get_group_enter_url(self, wxid: str, url: str, port: int = 0, _id: str = None): 305 | request = spy_pb2.Request() 306 | request.type = GET_GROUP_ENTER_URL 307 | text_message = spy_pb2.TextMessage() 308 | text_message.wxid = wxid 309 | text_message.text = url 310 | request.bytes = text_message.SerializeToString() 311 | return self.__send(request, port, _id) 312 | 313 | def decrypt_image(self, source_file: str, target_file: str, port: int = 0, _id: str = None): 314 | if not os.path.exists(source_file): 315 | self.logger.error(f"File Not Found {source_file}") 316 | return False 317 | request = spy_pb2.Request() 318 | request.type = DECRYPT_IMAGE 319 | file_message = spy_pb2.FileMessage() 320 | file_message.wxid = source_file 321 | file_message.filePath = target_file 322 | request.bytes = file_message.SerializeToString() 323 | return self.__send(request, port, _id) 324 | 325 | def send_card(self, wxid: str, card_wxid: str, card_nickname: str, port: int = 0, _id: str = None): 326 | request = spy_pb2.Request() 327 | request.type = SEND_CARD 328 | xml = spy_pb2.XmlMessage() 329 | xml.wxid = wxid 330 | xml.title = card_nickname 331 | xml.username = card_wxid 332 | request.bytes = xml.SerializeToString() 333 | return self.__send(request, port, _id) 334 | -------------------------------------------------------------------------------- /Logs/spy.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Logs/spy.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### python 同步拼多多客户聊天到微信,并可通过微信回复拼多多待回复消息 2 | 3 | 4 | 5 | ##### 启动项目 6 | 7 | 1. 安装`WeChatSetup-3.0.0.57.exe`; 8 | 2. 配置`Config/*.py`,主要是`mysql`、`redis`以及微信的配置信息; 9 | 3. 导入`Temp/crawler.sql`,配置`tb_admin`、`tb_project`; 10 | 4. 安装项目所需扩展; 11 | 5. 启动,双击`boot.bat` 12 | 13 | > `tb_admin.wx_mark`字段是微信用户标识,可以通过启动`wx_robot.py`获取;`tb_project.login_mark`是拼多多接口cookie,当前只能在后台登录后手动获取,过期时间大约12 h - 24 h,过期之后需重新手动获取 14 | 15 | 16 | 17 | ##### 测试 18 | 19 | 1. 启动项目之后如下 20 | 21 | 22 | 23 | 2. 微信扫码登录微信机器人 24 | 25 | 26 | 27 | 3. 找一个拼多多用户,给拼多多店(需在tb_project添加并确保login_mark正确)发测试消息 28 | 29 | 30 | 31 | 4. 数秒之后,微信机器人给项目管理员微信发消息(格式及延迟秒数可定义),同时消息入库 32 | 33 | 34 | 35 | 36 | 37 | 5. 管理员微信中引用回复上述消息,回复的消息入库 38 | 39 | 40 | 41 | 42 | 43 | 6. 拼多多爬虫将回复的消息推送给用户 44 | 45 | 46 | 47 | 48 | 49 | ##### 资源参考: 50 | 51 | https://github.com/veikai/PyWeChatSpy 下载WeChatSetup-3.0.0.57.exe也在这里 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Temp/WeChatSetup-3.0.0.57.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/WeChatSetup-3.0.0.57.exe -------------------------------------------------------------------------------- /Temp/crawler.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : 本机 5 | Source Server Type : MySQL 6 | Source Server Version : 50726 7 | Source Host : localhost:3306 8 | Source Schema : blog 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50726 12 | File Encoding : 65001 13 | 14 | Date: 07/04/2021 10:01:01 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for tb_admin 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `tb_admin`; 24 | CREATE TABLE `tb_admin` ( 25 | `id` int(11) NOT NULL AUTO_INCREMENT, 26 | `wx_nickname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 27 | `mail` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 28 | `phone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 29 | `is_robot` tinyint(1) NOT NULL DEFAULT 0, 30 | `wx_mark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 31 | `create_time` datetime(0) NULL DEFAULT NULL, 32 | PRIMARY KEY (`id`) USING BTREE 33 | ) ENGINE = MyISAM AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 34 | 35 | -- ---------------------------- 36 | -- Table structure for tb_project 37 | -- ---------------------------- 38 | DROP TABLE IF EXISTS `tb_project`; 39 | CREATE TABLE `tb_project` ( 40 | `id` int(11) NOT NULL AUTO_INCREMENT, 41 | `admin_id` int(11) NOT NULL DEFAULT 0, 42 | `login_mark` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 43 | `project_mark` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 44 | `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 45 | `type` enum('pdd','tb') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'pdd', 46 | `create_time` datetime(0) NULL DEFAULT NULL, 47 | PRIMARY KEY (`id`) USING BTREE 48 | ) ENGINE = MyISAM AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 49 | 50 | -- ---------------------------- 51 | -- Table structure for tb_user 52 | -- ---------------------------- 53 | DROP TABLE IF EXISTS `tb_user`; 54 | CREATE TABLE `tb_user` ( 55 | `id` int(11) NOT NULL AUTO_INCREMENT, 56 | `type` enum('pdd','tb') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'pdd', 57 | `user_mark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 58 | `user_nick` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 59 | `is_white` tinyint(1) NOT NULL DEFAULT 0, 60 | `project_id` smallint(5) NOT NULL DEFAULT 0, 61 | `create_time` datetime(0) NULL DEFAULT NULL, 62 | `update_time` datetime(0) NULL DEFAULT NULL, 63 | PRIMARY KEY (`id`) USING BTREE 64 | ) ENGINE = MyISAM AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 65 | 66 | -- ---------------------------- 67 | -- Table structure for tb_warning 68 | -- ---------------------------- 69 | DROP TABLE IF EXISTS `tb_warning`; 70 | CREATE TABLE `tb_warning` ( 71 | `id` int(11) NOT NULL AUTO_INCREMENT, 72 | `content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', 73 | `done_mail` tinyint(1) NOT NULL DEFAULT 0, 74 | `done_sms` tinyint(1) NOT NULL DEFAULT 0, 75 | `project_id` int(11) NOT NULL DEFAULT 0, 76 | `create_time` datetime(0) NULL DEFAULT NULL, 77 | `update_time` datetime(0) NULL DEFAULT NULL, 78 | PRIMARY KEY (`id`) USING BTREE 79 | ) ENGINE = MyISAM AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 80 | 81 | -- ---------------------------- 82 | -- Table structure for tb_wx_robot 83 | -- ---------------------------- 84 | DROP TABLE IF EXISTS `tb_wx_robot`; 85 | CREATE TABLE `tb_wx_robot` ( 86 | `id` int(11) NOT NULL AUTO_INCREMENT, 87 | `type` enum('u2j','j2u') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'j2u' COMMENT 'u2j:管理员用户发给机器人,j2u:机器人发给管理员用户', 88 | `admin_id` int(11) NOT NULL DEFAULT 0 COMMENT '管理员id,用以获取wx_mark', 89 | `project_id` int(11) NOT NULL DEFAULT 0 COMMENT '项目id', 90 | `content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '内容', 91 | `msg_to` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '信息用于哪个功能,如(pdd:xx:user_xxx)', 92 | `is_done` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已处理', 93 | `create_time` datetime(0) NULL DEFAULT NULL, 94 | `update_time` datetime(0) NULL DEFAULT NULL, 95 | PRIMARY KEY (`id`) USING BTREE 96 | ) ENGINE = MyISAM AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 97 | 98 | SET FOREIGN_KEY_CHECKS = 1; 99 | -------------------------------------------------------------------------------- /Temp/pdd_last_order_ask.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | import random 4 | 5 | username = '13922453234' 6 | password = '19950215Zwr' 7 | 8 | selemiumConfig = { 9 | 'link': "http://127.0.0.1:4444/wd/hub", 10 | 'brower': { 11 | "browserName": "chrome", 12 | "version": "", 13 | "platform": "ANY", 14 | } 15 | } 16 | 17 | pdd_login_url = "https://mms.pinduoduo.com/login" 18 | 19 | # xpath 规则 20 | pdd_account_btn = "//div[contains(text(),'账户登录')]" 21 | pdd_user_input = "//input[@id='usernameId']" 22 | pdd_pass_input = "//input[@id='passwordId']" 23 | pdd_login_btn = "//button/span[text()='登录']/.." 24 | 25 | 26 | def brower(): 27 | """ 28 | :param config: 浏览器配置 29 | :return: 30 | """ 31 | seleniumServer = selemiumConfig['link'] 32 | browser = selemiumConfig['brower'] 33 | driver = webdriver.Remote(command_executor=seleniumServer, desired_capabilities=browser) 34 | return driver 35 | 36 | 37 | def browerSimple(): 38 | return webdriver.Chrome(executable_path=r'D:\ProgramFiles\selenium-server\chromedriver.exe') 39 | 40 | 41 | def rand(num=3): 42 | return int(random.random() * num)+1 43 | 44 | 45 | # 获取某个节点 46 | def getElement(xpath): 47 | try: 48 | return bw.find_element_by_xpath(xpath) 49 | except: 50 | return False 51 | 52 | 53 | # 持续请求直到获取某个节点 54 | def getElementAlive(xpath, sleep_sec=1, max_wait=10): 55 | wait = 0 56 | while wait < max_wait: 57 | ele = getElement(xpath) 58 | if ele is not False: 59 | time.sleep(sleep_sec * rand()) # 随机3秒再执行操作 60 | return ele 61 | time.sleep(sleep_sec) 62 | wait += 1 63 | exit("程序结束,未获取到节点:经过 {} 秒之后仍未获取到 {} 的节点".format(max_wait, xpath)) 64 | 65 | 66 | def main(): 67 | bw.get(pdd_login_url) # 打开登录页面 68 | getElementAlive(pdd_account_btn).click() # 切换到账号密码登录 69 | getElementAlive(pdd_user_input).send_keys(username) # 输入账号 70 | getElementAlive(pdd_pass_input).send_keys(password) # 输入密码 71 | getElementAlive(pdd_login_btn).click() # 点击登录 72 | 73 | 74 | if __name__ == '__main__': 75 | bw = brower() 76 | bw.maximize_window() # 最大化浏览器窗口 77 | main() 78 | -------------------------------------------------------------------------------- /Temp/wx_robot_image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/1.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/2.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/3.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/4-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/4-1.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/4.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/5-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/5-1.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/5.jpg -------------------------------------------------------------------------------- /Temp/wx_robot_image/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eashin-sudophp/pdd_crawler_python/10562fa7d99d1356aee98d722ea1609c91b32af5/Temp/wx_robot_image/6.jpg -------------------------------------------------------------------------------- /boot.bat: -------------------------------------------------------------------------------- 1 | start cmd /k "echo start wechat robot... && python wx_robot.py /t" 2 | start cmd /k "echo start pdd... && python pdd.py /t" 3 | -------------------------------------------------------------------------------- /pdd.py: -------------------------------------------------------------------------------- 1 | from Config.database import * 2 | from Config.pdd import * 3 | import datetime 4 | import time 5 | import requests 6 | import json 7 | import pymysql 8 | import redis 9 | import random 10 | 11 | # cookie请去tb_project表中添加 12 | cookie = "" 13 | project_id = "" 14 | admin_id = "" 15 | project_type = "" 16 | 17 | # sql语句 18 | sql_all_project = "SELECT * FROM tb_project" 19 | sql_project_mark = "SELECT id, login_mark FROM tb_project" 20 | sql_exists_user = "SELECT * FROM tb_user WHERE user_mark = '{}' AND project_id = {}" 21 | sql_insert_user = "INSERT tb_user (type, user_mark, project_id, create_time, update_time) " \ 22 | "values ('{}', '{}', {}, '{}', '{}')" 23 | sql_exists_warning = "SELECT * FROM tb_warning WHERE content = '{}' AND project_id = {}" 24 | sql_make_warning = "INSERT tb_warning (content, project_id, create_time, update_time) values ('{}', {}, '{}', '{}')" 25 | sql_exists_robot = "SELECT * FROM tb_wx_robot WHERE content = '{}' AND project_id = {}" 26 | sql_add_wx_robot = "INSERT tb_wx_robot (admin_id, content, msg_to, project_id, create_time, update_time) " \ 27 | "values ({}, '{}', '{}', {}, '{}', '{}')" 28 | sql_need_reply = "SELECT id, project_id, msg_to, content FROM tb_wx_robot WHERE type = 'u2j' AND is_done = 0" 29 | sql_done_robot = "UPDATE tb_wx_robot SET is_done = 1, update_time = '{}' WHERE id = {}" 30 | 31 | 32 | # todo ############################ 功能函数 ############################### 33 | # 获取header头 34 | def getHeader(data): 35 | return { 36 | 'Cookie': cookie, 37 | "content-length": str(getStrNum(data)), 38 | "Accept-Encoding": "gzip, deflate, br", 39 | "Content-Type": "application/json", 40 | "Accept": "*/*", 41 | "User-Agent": "PostmanRuntime/7.26.8" 42 | } 43 | 44 | 45 | # 处理爬虫爬取的数据 46 | def dataHandleRes(res): 47 | data_dict = json.loads(res) 48 | # 请求过期,如会话已过期 49 | if not data_dict['success']: 50 | raise Exception(data_dict['error_msg']) 51 | 52 | if "result" in data_dict and data_dict['result']: 53 | result = data_dict['result'] 54 | if "result" in result and result["result"] != "ok": 55 | raise Exception(result['error']) # 如“买家回复前,您不能继续发送消息” 56 | 57 | response = result["response"] if result["response"] != "" else "latest_conversations" 58 | if response not in data_mark: 59 | raise Exception("异常的response:" + response) 60 | 61 | major_data_mark = data_mark[response] 62 | if major_data_mark not in result: 63 | raise Exception("异常的mark:" + major_data_mark) 64 | return result[major_data_mark] 65 | 66 | 67 | # 获取最近联系人后的业务处理 68 | def handleLatestTalkPeople(data): 69 | for i, row in enumerate(data): 70 | # 记录tb_user 71 | if row['from']['role'] == buyer_role: 72 | uid = row['from']['uid'] 73 | elif row['to']['role'] == buyer_role: 74 | uid = row['to']['uid'] 75 | else: 76 | uid = '' 77 | if uid: 78 | if not execute(sql_exists_user.format(uid, project_id)): 79 | # 入库tb_user 80 | execute(sql_insert_user.format(project_type, uid, project_id, now_format, now_format)) 81 | exit() 82 | 83 | # 添加异步消息发送任务 84 | if row['from']['role'] == buyer_role and row['to']['role'] == seller_role: 85 | # 第 i+1 个最近联系人等待回复 86 | ts = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(row['ts']))) 87 | content = "第{}个最近联系人({})等待回复: {} -- {}".format(i + 1, row['from']['uid'], row['content'], ts) 88 | make_warning(content, row['from']['uid']) 89 | if reply_at_one: 90 | sendTalkMsg(reply_common, row['from']['uid']) 91 | 92 | # 只读10条 93 | if i >= 9: 94 | break 95 | return True 96 | 97 | 98 | # todo ############################ 爬虫相关 ############################### 99 | # 获取某个用户的聊天内容 100 | def getLatestTalk(uid): 101 | data = {"data": {"cmd": "list", "list": {"with": {"id": uid}}}, "client": "web"} 102 | headers = getHeader(data) 103 | res = requests.post(talk_list_url, data=json.dumps(data), headers=headers).text 104 | return res 105 | 106 | 107 | # 获取最近联系人列表 108 | def getLatestTalkPeople(): 109 | data = {"data": {"offset": 0, "size": 50}, "client": 1} 110 | headers = getHeader(data) 111 | res = requests.post(talk_people_url, data=json.dumps(data), headers=headers).text 112 | return res 113 | 114 | 115 | # 给指定联系人发送消息 116 | def sendTalkMsg(msg, uid): 117 | data = { 118 | "data": { 119 | "cmd": "send_message", 120 | "message": { 121 | "content": msg, 122 | "from": {"role": seller_role}, 123 | "type": 0, 124 | "to": {"role": buyer_role, "uid": uid}, 125 | "ts": int(time.time()) 126 | } 127 | }, 128 | "client": "web" 129 | } 130 | headers = getHeader(data) 131 | res = requests.post(send_msg_url, data=json.dumps(data), headers=headers).text 132 | return res 133 | 134 | 135 | # todo ############################ 辅助功能 ############################### 136 | # 获取字典的字符数 137 | def getStrNum(dict_str): 138 | return len(json.dumps(dict_str).replace(' ', '')) 139 | 140 | 141 | # 获取随机数 142 | def getRandint(big=9): 143 | return random.randint(0, big) 144 | 145 | 146 | # 数据库 147 | def execute(sql): 148 | db = pymysql.connect(MYSQL['host'], MYSQL['user'], MYSQL['pass'], MYSQL['database'], charset='utf8') 149 | cursor = db.cursor() 150 | cursor.execute(sql) 151 | results = cursor.fetchall() 152 | db.close() 153 | return results 154 | 155 | 156 | # redis 157 | def rds(name, value='', p_time=0): 158 | r = redis.Redis(host=REDIS['host'], port=REDIS['port'], db=0) 159 | if value == '': 160 | return r.get(name).decode('utf-8') 161 | else: 162 | return r.setex(name, value, p_time) 163 | 164 | 165 | # todo ############################ 其他 ############################### 166 | # 预警 167 | def make_warning(content, msg_to): 168 | # todo 发微信消息 169 | if not execute(sql_exists_robot.format(content, project_id)): 170 | execute(sql_add_wx_robot.format(admin_id, content, msg_to, project_id, now_format, now_format)) 171 | # todo 发短信 172 | # todo 发邮件 173 | if not execute(sql_exists_warning.format(content, project_id)): 174 | execute(sql_make_warning.format(content, project_id, now_format, now_format)) 175 | return True 176 | 177 | 178 | def getMarkList(): 179 | marks = execute(sql_project_mark) 180 | mark_list = {} 181 | for i in marks: 182 | mark_list[i[0]] = i[1] 183 | return mark_list 184 | 185 | 186 | def makeGlobalData(project): 187 | global cookie, project_id, admin_id, project_type 188 | cookie = project[2] 189 | project_id = project[0] 190 | admin_id = project[1] 191 | project_type = project[5] 192 | return True 193 | 194 | 195 | def main(): 196 | try: 197 | mark_list = getMarkList() 198 | while True: 199 | # 机器人回复客户 200 | robot_list = execute(sql_need_reply) 201 | for robot in robot_list: 202 | execute(sql_done_robot.format(now_format, robot[0])) 203 | global cookie 204 | cookie = mark_list[robot[1]] 205 | sendTalkMsg(robot[3], robot[2]) 206 | 207 | if getRandint() > 7: # 20%的概率跑以下逻辑 208 | # 监听最近联系人以获取待回复信息 209 | projects = execute(sql_all_project) 210 | for project in projects: 211 | makeGlobalData(project) 212 | 213 | # 跑接口(获取最近联系人)并处理得到结果 214 | res_json = getLatestTalkPeople() 215 | data = dataHandleRes(res_json) 216 | # 业务处理上述结果,发送预警消息 217 | handleLatestTalkPeople(data) 218 | 219 | time.sleep(time_sleep) 220 | except Exception as e: 221 | # print(e) 222 | raise e 223 | 224 | 225 | if __name__ == '__main__': 226 | now_format = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 227 | main() 228 | -------------------------------------------------------------------------------- /wx_robot.py: -------------------------------------------------------------------------------- 1 | from Library.PyWeChatSpy import WeChatSpy 2 | from Library.PyWeChatSpy.command import * 3 | from lxml import etree 4 | import time 5 | import logging 6 | from logging.handlers import TimedRotatingFileHandler 7 | from Library.PyWeChatSpy.proto import spy_pb2 8 | import os 9 | import pymysql 10 | import datetime 11 | import shutil 12 | from queue import Queue 13 | from Library.PyWeChatSpy.games.truth_or_dare import TruthOrDare 14 | from Config.wx import * 15 | from Config.database import * 16 | 17 | 18 | logger = logging.getLogger(__file__) 19 | logger.setLevel(logging.DEBUG) 20 | formatter = logging.Formatter('%(asctime)s [%(threadName)s] %(levelname)s: %(message)s') 21 | sh = logging.StreamHandler() 22 | sh.setFormatter(formatter) 23 | sh.setLevel(logging.INFO) 24 | fh = TimedRotatingFileHandler("Logs/spy.log", when="midnight") 25 | fh.setFormatter(formatter) 26 | logger.addHandler(fh) 27 | logger.addHandler(sh) 28 | 29 | 30 | if not os.path.exists(WECHAT_PROFILE): 31 | logger.error("请先设置计算机用户名,并完善WECHAT_PROFILE和PATCH_PATH") 32 | exit() 33 | if os.path.isdir(PATCH_PATH): 34 | shutil.rmtree(PATCH_PATH) 35 | if not os.path.exists(PATCH_PATH): 36 | with open(PATCH_PATH, "a") as wf: 37 | wf.write("") 38 | my_response_queue = Queue() 39 | spy = WeChatSpy(response_queue=my_response_queue, key="ab28d8c4768ab3bc2ba86841313f6e32", logger=logger) 40 | tod = TruthOrDare(spy) 41 | 42 | 43 | def pop_response(): 44 | while True: 45 | data = my_response_queue.get() 46 | handle_response(data) 47 | 48 | if has_login: 49 | # 微信机器人的核心部分 50 | robot_list = execute("SELECT id, admin_id, content FROM tb_wx_robot WHERE type = 'j2u' AND is_done = 0") 51 | for robot in robot_list: 52 | execute("UPDATE tb_wx_robot SET is_done = 1, update_time = '{}' WHERE id = {}" 53 | .format(now_format, robot[0])) 54 | spy.send_text(admin_list[robot[1]], robot[2]) 55 | 56 | 57 | def handle_response(data): 58 | if data.type == PROFESSIONAL_KEY: 59 | if not data.code: 60 | logger.warning(data.message) 61 | elif data.type == WECHAT_CONNECTED: # 微信接入 62 | print(f"微信客户端已接入 port:{data.port}") 63 | time.sleep(1) 64 | # spy.get_login_qrcode() # 获取登录二维码 65 | elif data.type == HEART_BEAT: # 心跳 66 | pass 67 | elif data.type == WECHAT_LOGIN: # 微信登录 68 | print("微信登录") 69 | spy.get_account_details() # 获取登录账号详情 70 | global has_login 71 | has_login = True 72 | elif data.type == WECHAT_LOGOUT: # 微信登出 73 | print("微信登出") 74 | elif data.type == CHAT_MESSAGE: # 微信消息 75 | chat_message = spy_pb2.ChatMessage() 76 | chat_message.ParseFromString(data.bytes) 77 | for message in chat_message.message: 78 | _type = message.type # 消息类型 1.文本|3.图片...自行探索 79 | _from = message.wxidFrom.str # 消息发送方 80 | _to = message.wxidTo.str # 消息接收方 81 | content = message.content.str # 消息内容 82 | if _type == 1: # 文本消息 83 | print(_from, _to, content) 84 | # if _to == "filehelper": 85 | # spy.send_text("wxid_xigdflxwillf21", "Hello PyWeChatSpy3.0 啊哈哈") 86 | # 87 | # spy.send_text("filehelper", "Hello PyWeChatSpy3.0\n" + content) 88 | # time.sleep(2) 89 | # spy.send_file("filehelper", r"D:\Project\PyWeChatSpy\images\1.jpg") 90 | elif _type == 49: # XML报文消息 91 | # print(_from, _to, message.file) 92 | xml = etree.XML(content) 93 | xml_type = xml.xpath("/msg/appmsg/type/text()")[0] 94 | if xml_type == "57": # 引用 95 | xml_title = xml.xpath("/msg/appmsg/title/text()")[0] # 输入的内容 96 | xml_refer_content = xml.xpath("/msg/appmsg/refermsg/content/text()")[0] # 被引用内容 97 | print(xml_title) 98 | # print(xml_refer_content) 99 | # 引用回复时,注入机器人任务(自动回复到pdd) 100 | robots = execute("SELECT * FROM tb_wx_robot WHERE content = '{}' AND is_done = 1". 101 | format(xml_refer_content)) 102 | if robots and len(robots) > 0: 103 | robot = robots[0] 104 | print(robot) 105 | execute("INSERT tb_wx_robot (type, admin_id, project_id, content, msg_to, " 106 | "create_time, update_time) " 107 | "VALUE ('u2j', {}, {}, '{}', '{}', '{}', '{}')" 108 | .format(robot[2], robot[3], xml_title, robot[5], now_format, now_format)) 109 | 110 | 111 | # 数据库 112 | def execute(sql): 113 | db = pymysql.connect(MYSQL['host'], MYSQL['user'], MYSQL['pass'], MYSQL['database'], charset='utf8') 114 | cursor = db.cursor() 115 | cursor.execute(sql) 116 | results = cursor.fetchall() 117 | db.close() 118 | return results 119 | 120 | 121 | if __name__ == '__main__': 122 | admins = execute("SELECT id, wx_mark FROM tb_admin") 123 | admin_list = {} 124 | for i in admins: 125 | admin_list[i[0]] = i[1] 126 | 127 | now_format = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 128 | has_login = False 129 | 130 | pid = spy.run(wx_exe_path) 131 | pop_response() 132 | --------------------------------------------------------------------------------