|
@@ -32,27 +32,21 @@ class WXBot:
|
|
|
self.sid = ''
|
|
|
self.skey = ''
|
|
|
self.pass_ticket = ''
|
|
|
- self.deviceId = 'e' + repr(random.random())[2:17]
|
|
|
- self.BaseRequest = {}
|
|
|
- self.synckey = ''
|
|
|
- self.SyncKey = []
|
|
|
- self.User = []
|
|
|
- self.MemberList = []
|
|
|
- self.ContactList = []
|
|
|
- self.GroupList = []
|
|
|
- self.is_auto_reply = False
|
|
|
- self.syncHost = ''
|
|
|
+ self.device_id = 'e' + repr(random.random())[2:17]
|
|
|
+ self.base_request = {}
|
|
|
+ self.sync_key_str = ''
|
|
|
+ self.sync_key = []
|
|
|
+ self.user = []
|
|
|
+ self.member_list = []
|
|
|
+ self.contact_list = [] # contact list
|
|
|
+ self.public_list = [] # public account list
|
|
|
+ self.group_list = [] # group chat list
|
|
|
+ self.special_list = [] # special list account
|
|
|
+ self.sync_host = ''
|
|
|
self.session = requests.Session()
|
|
|
self.session.headers.update({'User-Agent': 'Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5'})
|
|
|
|
|
|
- try:
|
|
|
- with open('auto.json') as f:
|
|
|
- cfg = json.load(f)
|
|
|
- self.auto_reply_url = cfg['url']
|
|
|
- self.auto_reply_key = cfg['key']
|
|
|
- except Exception, e:
|
|
|
- self.auto_reply_url = None
|
|
|
- self.auto_reply_key = None
|
|
|
+ self.conf = {'qr': 'png',}
|
|
|
|
|
|
def get_uuid(self):
|
|
|
url = 'https://login.weixin.qq.com/jslogin'
|
|
@@ -73,10 +67,15 @@ class WXBot:
|
|
|
return code == '200'
|
|
|
return False
|
|
|
|
|
|
- def gen_qr_code(self):
|
|
|
+ def gen_qr_code(self, qr_file_path):
|
|
|
string = 'https://login.weixin.qq.com/l/' + self.uuid
|
|
|
qr = pyqrcode.create(string)
|
|
|
- qr.png('qr.jpg')
|
|
|
+ if self.conf['qr'] == 'png':
|
|
|
+ qr.png(qr_file_path)
|
|
|
+ elif self.conf['qr'] == 'tty':
|
|
|
+ print 'Not support tty'
|
|
|
+ pass
|
|
|
+ #qr.print_tty()
|
|
|
|
|
|
def wait4login(self, tip):
|
|
|
time.sleep(tip)
|
|
@@ -96,9 +95,9 @@ class WXBot:
|
|
|
self.base_uri = redirect_uri[:redirect_uri.rfind('/')]
|
|
|
return True
|
|
|
elif code == '408':
|
|
|
- print '[login timeout]'
|
|
|
+ print '[ERROR] WeChat login timeout .'
|
|
|
else:
|
|
|
- print '[login exception]'
|
|
|
+ print '[ERROR] WeChat login exception .'
|
|
|
return False
|
|
|
|
|
|
def login(self):
|
|
@@ -121,108 +120,90 @@ class WXBot:
|
|
|
if '' in (self.skey, self.sid, self.uin, self.pass_ticket):
|
|
|
return False
|
|
|
|
|
|
- self.BaseRequest = {
|
|
|
+ self.base_request = {
|
|
|
'Uin': self.uin,
|
|
|
'Sid': self.sid,
|
|
|
'Skey': self.skey,
|
|
|
- 'DeviceID': self.deviceId,
|
|
|
+ 'DeviceID': self.device_id,
|
|
|
}
|
|
|
return True
|
|
|
|
|
|
def init(self):
|
|
|
url = self.base_uri + '/webwxinit?r=%i&lang=en_US&pass_ticket=%s' % (int(time.time()), self.pass_ticket)
|
|
|
params = {
|
|
|
- 'BaseRequest': self.BaseRequest
|
|
|
+ 'BaseRequest': self.base_request
|
|
|
}
|
|
|
- r = self.session.post(url, json=params)
|
|
|
+ r = self.session.post(url, data=json.dumps(params))
|
|
|
r.encoding = 'utf-8'
|
|
|
dic = json.loads(r.text)
|
|
|
- self.SyncKey = dic['SyncKey']
|
|
|
- self.User = dic['User']
|
|
|
- self.synckey = '|'.join([ str(keyVal['Key']) + '_' + str(keyVal['Val']) for keyVal in self.SyncKey['List'] ])
|
|
|
+ self.sync_key = dic['SyncKey']
|
|
|
+ self.user = dic['User']
|
|
|
+ self.sync_key_str = '|'.join([ str(keyVal['Key']) + '_' + str(keyVal['Val']) for keyVal in self.sync_key['List'] ])
|
|
|
return dic['BaseResponse']['Ret'] == 0
|
|
|
|
|
|
def status_notify(self):
|
|
|
url = self.base_uri + '/webwxstatusnotify?lang=zh_CN&pass_ticket=%s' % (self.pass_ticket)
|
|
|
- self.BaseRequest['Uin'] = int(self.BaseRequest['Uin'])
|
|
|
+ self.base_request['Uin'] = int(self.base_request['Uin'])
|
|
|
params = {
|
|
|
- 'BaseRequest': self.BaseRequest,
|
|
|
+ 'BaseRequest': self.base_request,
|
|
|
"Code": 3,
|
|
|
- "FromUserName": self.User['UserName'],
|
|
|
- "ToUserName": self.User['UserName'],
|
|
|
+ "FromUserName": self.user['UserName'],
|
|
|
+ "ToUserName": self.user['UserName'],
|
|
|
"ClientMsgId": int(time.time())
|
|
|
}
|
|
|
- r = self.session.post(url, json=params)
|
|
|
+ r = self.session.post(url, data=json.dumps(params))
|
|
|
r.encoding = 'utf-8'
|
|
|
dic = json.loads(r.text)
|
|
|
return dic['BaseResponse']['Ret'] == 0
|
|
|
|
|
|
def get_contact(self):
|
|
|
url = self.base_uri + '/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s' % (self.pass_ticket, self.skey, int(time.time()))
|
|
|
- r = self.session.post(url, json={})
|
|
|
+ r = self.session.post(url, data='{}')
|
|
|
r.encoding = 'utf-8'
|
|
|
if self.DEBUG:
|
|
|
with open('contacts.json', 'w') as f:
|
|
|
f.write(r.text.encode('utf-8'))
|
|
|
dic = json.loads(r.text)
|
|
|
- self.MemberList = dic['MemberList']
|
|
|
-
|
|
|
- ContactList = self.MemberList[:]
|
|
|
- SpecialUsers = [
|
|
|
- 'newsapp',
|
|
|
- 'fmessage',
|
|
|
- 'filehelper',
|
|
|
- 'weibo',
|
|
|
- 'qqmail',
|
|
|
- 'fmessage',
|
|
|
- 'tmessage',
|
|
|
- 'qmessage',
|
|
|
- 'qqsync',
|
|
|
- 'floatbottle',
|
|
|
- 'lbsapp',
|
|
|
- 'shakeapp',
|
|
|
- 'medianote',
|
|
|
- 'qqfriend',
|
|
|
- 'readerapp',
|
|
|
- 'blogapp',
|
|
|
- 'facebookapp',
|
|
|
- 'masssendapp',
|
|
|
- 'meishiapp',
|
|
|
- 'feedsapp',
|
|
|
- 'voip',
|
|
|
- 'blogappweixin',
|
|
|
- 'weixin',
|
|
|
- 'brandsessionholder',
|
|
|
- 'weixinreminder',
|
|
|
- 'wxid_novlwrv3lqwv11',
|
|
|
- 'gh_22b87fa7cb3c',
|
|
|
- 'officialaccounts',
|
|
|
- 'notification_messages',
|
|
|
- 'wxid_novlwrv3lqwv11',
|
|
|
- 'gh_22b87fa7cb3c',
|
|
|
- 'wxitil',
|
|
|
- 'userexperience_alarm',
|
|
|
- 'notification_messages']
|
|
|
- for contact in ContactList:
|
|
|
+ self.member_list = dic['MemberList']
|
|
|
+
|
|
|
+ SpecialUsers = ['newsapp','fmessage','filehelper','weibo','qqmail','fmessage','tmessage','qmessage','qqsync','floatbottle','lbsapp','shakeapp','medianote',
|
|
|
+ 'qqfriend','readerapp','blogapp','facebookapp','masssendapp','meishiapp','feedsapp','voip','blogappweixin','weixin','brandsessionholder','weixinreminder','wxid_novlwrv3lqwv11',
|
|
|
+ 'gh_22b87fa7cb3c','officialaccounts','notification_messages','wxid_novlwrv3lqwv11','gh_22b87fa7cb3c','wxitil','userexperience_alarm','notification_messages']
|
|
|
+
|
|
|
+ self.contact_list = []
|
|
|
+ self.public_list = []
|
|
|
+ self.special_list = []
|
|
|
+ self.group_list = []
|
|
|
+ for contact in self.member_list:
|
|
|
if contact['VerifyFlag'] & 8 != 0: # public account
|
|
|
- ContactList.remove(contact)
|
|
|
+ self.public_list.append(contact)
|
|
|
elif contact['UserName'] in SpecialUsers: # special account
|
|
|
- ContactList.remove(contact)
|
|
|
+ self.special_list.append(contact)
|
|
|
elif contact['UserName'].find('@@') != -1: # group
|
|
|
- self.GroupList.append(contact)
|
|
|
- ContactList.remove(contact)
|
|
|
- elif contact['UserName'] == self.User['UserName']: # self
|
|
|
- ContactList.remove(contact)
|
|
|
- self.ContactList = ContactList
|
|
|
+ self.group_list.append(contact)
|
|
|
+ elif contact['UserName'] == self.user['UserName']: # self
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ self.contact_list.append(contact)
|
|
|
+
|
|
|
+ if self.DEBUG:
|
|
|
+ with open('contact_list.json', 'w') as f:
|
|
|
+ f.write(json.dumps(self.contact_list))
|
|
|
+ with open('special_list.json', 'w') as f:
|
|
|
+ f.write(json.dumps(self.special_list))
|
|
|
+ with open('group_list.json', 'w') as f:
|
|
|
+ f.write(json.dumps(self.group_list))
|
|
|
+ with open('public_list.json', 'w') as f:
|
|
|
+ f.write(json.dumps(self.public_list))
|
|
|
|
|
|
return True
|
|
|
|
|
|
def batch_get_contact(self):
|
|
|
url = self.base_uri + '/webwxbatchgetcontact?type=ex&r=%s&pass_ticket=%s' % (int(time.time()), self.pass_ticket)
|
|
|
params = {
|
|
|
- 'BaseRequest': self.BaseRequest,
|
|
|
- "Count": len(self.GroupList),
|
|
|
- "List": [ {"UserName": g['UserName'], "EncryChatRoomId":""} for g in self.GroupList ]
|
|
|
+ 'BaseRequest': self.base_request,
|
|
|
+ "Count": len(self.group_list),
|
|
|
+ "List": [ {"UserName": g['UserName'], "EncryChatRoomId":""} for g in self.group_list ]
|
|
|
}
|
|
|
r = self.session.post(url, data=params)
|
|
|
r.encoding = 'utf-8'
|
|
@@ -231,7 +212,7 @@ class WXBot:
|
|
|
|
|
|
def test_sync_check(self):
|
|
|
for host in ['webpush', 'webpush2']:
|
|
|
- self.syncHost = host
|
|
|
+ self.sync_host = host
|
|
|
[retcode, selector] = self.sync_check()
|
|
|
if retcode == '0':
|
|
|
return True
|
|
@@ -243,11 +224,11 @@ class WXBot:
|
|
|
'sid': self.sid,
|
|
|
'uin': self.uin,
|
|
|
'skey': self.skey,
|
|
|
- 'deviceid': self.deviceId,
|
|
|
- 'synckey': self.synckey,
|
|
|
+ 'deviceid': self.device_id,
|
|
|
+ 'synckey': self.sync_key_str,
|
|
|
'_': int(time.time()),
|
|
|
}
|
|
|
- url = 'https://' + self.syncHost + '.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?' + urllib.urlencode(params)
|
|
|
+ url = 'https://' + self.sync_host + '.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?' + urllib.urlencode(params)
|
|
|
r = self.session.get(url)
|
|
|
r.encoding = 'utf-8'
|
|
|
data = r.text
|
|
@@ -259,18 +240,16 @@ class WXBot:
|
|
|
def sync(self):
|
|
|
url = self.base_uri + '/webwxsync?sid=%s&skey=%s&lang=en_US&pass_ticket=%s' % (self.sid, self.skey, self.pass_ticket)
|
|
|
params = {
|
|
|
- 'BaseRequest': self.BaseRequest,
|
|
|
- 'SyncKey': self.SyncKey,
|
|
|
+ 'BaseRequest': self.base_request,
|
|
|
+ 'SyncKey': self.sync_key,
|
|
|
'rr': ~int(time.time())
|
|
|
}
|
|
|
- r = self.session.post(url, json=params)
|
|
|
+ r = self.session.post(url, data=json.dumps(params))
|
|
|
r.encoding = 'utf-8'
|
|
|
dic = json.loads(r.text)
|
|
|
- if self.DEBUG:
|
|
|
- print json.dumps(dic, indent=4)
|
|
|
if dic['BaseResponse']['Ret'] == 0:
|
|
|
- self.SyncKey = dic['SyncKey']
|
|
|
- self.synckey = '|'.join([ str(keyVal['Key']) + '_' + str(keyVal['Val']) for keyVal in self.SyncKey['List'] ])
|
|
|
+ self.sync_key = dic['SyncKey']
|
|
|
+ self.sync_key_str = '|'.join([ str(keyVal['Key']) + '_' + str(keyVal['Val']) for keyVal in self.sync_key['List'] ])
|
|
|
return dic
|
|
|
|
|
|
def get_icon(self, id):
|
|
@@ -291,6 +270,9 @@ class WXBot:
|
|
|
f.write(data)
|
|
|
return fn
|
|
|
|
|
|
+ def get_msg_img_url(self, msgid):
|
|
|
+ return self.base_uri + '/webwxgetmsgimg?MsgID=%s&skey=%s' % (msgid, self.skey)
|
|
|
+
|
|
|
def get_msg_img(self, msgid):
|
|
|
url = self.base_uri + '/webwxgetmsgimg?MsgID=%s&skey=%s' % (msgid, self.skey)
|
|
|
r = self.session.get(url)
|
|
@@ -300,15 +282,8 @@ class WXBot:
|
|
|
f.write(data)
|
|
|
return fn
|
|
|
|
|
|
- # Not work now for weixin haven't support this API
|
|
|
- def get_video(self, msgid):
|
|
|
- url = self.base_uri + '/webwxgetvideo?msgid=%s&skey=%s' % (msgid, self.skey)
|
|
|
- r = self.session.get(url)
|
|
|
- data = r.content
|
|
|
- fn = 'video_'+msgid+'.mp4'
|
|
|
- with open(fn, 'wb') as f:
|
|
|
- f.write(data)
|
|
|
- return fn
|
|
|
+ def get_voice_url(self, msgid):
|
|
|
+ return self.base_uri + '/webwxgetvoice?msgid=%s&skey=%s' % (msgid, self.skey)
|
|
|
|
|
|
def get_voice(self, msgid):
|
|
|
url = self.base_uri + '/webwxgetvoice?msgid=%s&skey=%s' % (msgid, self.skey)
|
|
@@ -322,130 +297,218 @@ class WXBot:
|
|
|
#Get the NickName or RemarkName of an user by user id
|
|
|
def get_user_remark_name(self, uid):
|
|
|
name = 'unknown group' if uid[:2] == '@@' else 'stranger'
|
|
|
- for member in self.MemberList:
|
|
|
+ for member in self.member_list:
|
|
|
if member['UserName'] == uid:
|
|
|
name = member['RemarkName'] if member['RemarkName'] else member['NickName']
|
|
|
return name
|
|
|
|
|
|
#Get user id of an user
|
|
|
def get_user_id(self, name):
|
|
|
- for member in self.MemberList:
|
|
|
+ for member in self.member_list:
|
|
|
if name == member['RemarkName'] or name == member['NickName'] or name == member['UserName']:
|
|
|
return member['UserName']
|
|
|
return None
|
|
|
|
|
|
- def auto_reply(self, word):
|
|
|
- if self.auto_reply_key == None or self.auto_reply_url == None:
|
|
|
- return 'hi'
|
|
|
-
|
|
|
- body = {'key': self.auto_reply_key, 'info':word}
|
|
|
- r = requests.post(self.auto_reply_url, data=body)
|
|
|
- resp = json.loads(r.text)
|
|
|
- if resp['code'] == 100000:
|
|
|
- return resp['text']
|
|
|
- else:
|
|
|
- return None
|
|
|
+ def get_user_type(self, wx_user_id):
|
|
|
+ for account in self.contact_list:
|
|
|
+ if wx_user_id == account['UserName']:
|
|
|
+ return 'contact'
|
|
|
+ for account in self.public_list:
|
|
|
+ if wx_user_id == account['UserName']:
|
|
|
+ return 'public'
|
|
|
+ for account in self.special_list:
|
|
|
+ if wx_user_id == account['UserName']:
|
|
|
+ return 'special'
|
|
|
+ for account in self.group_list:
|
|
|
+ if wx_user_id == account['UserName']:
|
|
|
+ return 'group'
|
|
|
+ return 'unknown'
|
|
|
|
|
|
+ '''
|
|
|
+ msg:
|
|
|
+ user_type
|
|
|
+ msg_id
|
|
|
+ msg_type_id
|
|
|
+ user_id
|
|
|
+ user_name
|
|
|
+ content
|
|
|
+ '''
|
|
|
+ def handle_msg_all(self, msg):
|
|
|
+ pass
|
|
|
+
|
|
|
+ '''
|
|
|
+ msg_type_id:
|
|
|
+ 1 -> Location
|
|
|
+ 2 -> FileHelper
|
|
|
+ 3 -> Self
|
|
|
+ 4 -> Group
|
|
|
+ 5 -> User Text Message
|
|
|
+ 6 -> Image
|
|
|
+ 7 -> Voice
|
|
|
+ 8 -> Recommend
|
|
|
+ 9 -> Animation
|
|
|
+ 10 -> Share
|
|
|
+ 11 -> Video
|
|
|
+ 12 -> Video Call
|
|
|
+ 13 -> Redraw
|
|
|
+ 14 -> Init Message
|
|
|
+ 99 -> Unknown
|
|
|
+ '''
|
|
|
def handle_msg(self, r):
|
|
|
for msg in r['AddMsgList']:
|
|
|
- msgType = msg['MsgType']
|
|
|
- name = self.get_user_remark_name(msg['FromUserName']) #FromUserName is user id
|
|
|
+ mtype = msg['MsgType']
|
|
|
+
|
|
|
+ wx_user_id = msg['FromUserName']
|
|
|
+ user_type = self.get_user_type(wx_user_id)
|
|
|
+
|
|
|
+ name = self.get_user_remark_name(wx_user_id)
|
|
|
content = msg['Content'].replace('<','<').replace('>','>')
|
|
|
- msgid = msg['MsgId']
|
|
|
- if msgType == 51: #init message
|
|
|
- pass
|
|
|
- elif msgType == 1:
|
|
|
+ msg_id = msg['MsgId']
|
|
|
+ msg_type_id = 99
|
|
|
+
|
|
|
+
|
|
|
+ if mtype == 51: #init message
|
|
|
+ msg_type_id = 14
|
|
|
+ elif mtype == 1:
|
|
|
if content.find('http://weixin.qq.com/cgi-bin/redirectforward?args=') != -1:
|
|
|
r = self.session.get(content)
|
|
|
r.encoding = 'gbk'
|
|
|
data = r.text
|
|
|
pos = self.search_content('title', data, 'xml')
|
|
|
- print '[Location] %s : I am at %s ' % (name, pos)
|
|
|
+ msg_type_id = 1
|
|
|
+ content = {'location': pos, 'xml': data}
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Location] %s : I am at %s ' % (name, pos)
|
|
|
+
|
|
|
elif msg['ToUserName'] == 'filehelper':
|
|
|
- print '[File] %s : %s' % (name, content.replace('<br/>','\n'))
|
|
|
- elif msg['FromUserName'] == self.User['UserName']: #self
|
|
|
- pass
|
|
|
+ msg_type_id = 2
|
|
|
+ content = content.replace('<br/>','\n')
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[File] %s : %s' % (name, )
|
|
|
+
|
|
|
+ elif msg['FromUserName'] == self.user['UserName']: #self
|
|
|
+ msg_type_id = 3
|
|
|
+
|
|
|
elif msg['FromUserName'][:2] == '@@':
|
|
|
[people, content] = content.split(':<br/>')
|
|
|
group = self.get_user_remark_name(msg['FromUserName'])
|
|
|
name = self.get_user_remark_name(people)
|
|
|
- print '[Group] |%s| %s: %s' % (group, name, content.replace('<br/>','\n'))
|
|
|
+ msg_type_id = 4
|
|
|
+ content = {'group_id': msg['FromUserName'], 'group_name': group, 'user': people, 'user_name': name, 'msg': content}
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Group] |%s| %s: %s' % (group, name, content.replace('<br/>','\n'))
|
|
|
+
|
|
|
else:
|
|
|
- print '[Text] ', name, ' : ', content
|
|
|
- if self.is_auto_reply:
|
|
|
- ans = self.auto_reply(content)
|
|
|
- if ans:
|
|
|
- if self.send_msg(msg['FromUserName'], ans):
|
|
|
- print '[AUTO] Me : ', ans
|
|
|
- else:
|
|
|
- print '[AUTO] Failed'
|
|
|
- elif msgType == 3:
|
|
|
- image = self.get_msg_img(msgid)
|
|
|
- print '[Image] %s : %s' % (name, image)
|
|
|
- elif msgType == 34:
|
|
|
- voice = self.get_voice(msgid)
|
|
|
- print '[Voice] %s : %s' % (name, voice)
|
|
|
- elif msgType == 42:
|
|
|
+ msg_type_id = 5
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Text] ', name, ' : ', content
|
|
|
+
|
|
|
+ elif mtype == 3:
|
|
|
+ msg_type_id = 6
|
|
|
+ content = self.get_msg_img_url(msg_id)
|
|
|
+ if self.DEBUG:
|
|
|
+ image = self.get_msg_img(msg_id)
|
|
|
+ print '[Image] %s : %s' % (name, image)
|
|
|
+
|
|
|
+ elif mtype == 34:
|
|
|
+ msg_type_id = 7
|
|
|
+ content = self.get_voice_url(msg_id)
|
|
|
+ if self.DEBUG:
|
|
|
+ voice = self.get_voice(msg_id)
|
|
|
+ print '[Voice] %s : %s' % (name, voice)
|
|
|
+
|
|
|
+ elif mtype == 42:
|
|
|
+ msg_type_id = 8
|
|
|
+
|
|
|
info = msg['RecommendInfo']
|
|
|
- print '[Recommend] %s : ' % name
|
|
|
- print '========================='
|
|
|
- print '= NickName: %s' % info['NickName']
|
|
|
- print '= Alias: %s' % info['Alias']
|
|
|
- print '= Local: %s %s' % (info['Province'], info['City'])
|
|
|
- print '= Gender: %s' % ['unknown', 'male', 'female'][info['Sex']]
|
|
|
- print '========================='
|
|
|
- elif msgType == 47:
|
|
|
+ content = {}
|
|
|
+ content['nickname'] = info['NickName']
|
|
|
+ content['alias'] = info['Alias']
|
|
|
+ content['province'] = info['Province']
|
|
|
+ content['city'] = info['City']
|
|
|
+ content['gender'] = ['unknown', 'male', 'female'][info['Sex']]
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Recommend] %s : ' % name
|
|
|
+ print '========================='
|
|
|
+ print '= NickName: %s' % info['NickName']
|
|
|
+ print '= Alias: %s' % info['Alias']
|
|
|
+ print '= Local: %s %s' % (info['Province'], info['City'])
|
|
|
+ print '= Gender: %s' % ['unknown', 'male', 'female'][info['Sex']]
|
|
|
+ print '========================='
|
|
|
+
|
|
|
+ elif mtype == 47:
|
|
|
+ msg_type_id = 9
|
|
|
url = self.search_content('cdnurl', content)
|
|
|
- print '[Animation] %s : %s' % (name, url)
|
|
|
- elif msgType == 49:
|
|
|
+ content = url
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Animation] %s : %s' % (name, url)
|
|
|
+
|
|
|
+ elif mtype == 49:
|
|
|
+ msg_type_id = 10
|
|
|
appMsgType = defaultdict(lambda : "")
|
|
|
appMsgType.update({5:'link', 3:'music', 7:'weibo'})
|
|
|
- print '[Share] %s : %s' % (name, appMsgType[msg['AppMsgType']])
|
|
|
- print '========================='
|
|
|
- print '= title: %s' % msg['FileName']
|
|
|
- print '= desc: %s' % self.search_content('des', content, 'xml')
|
|
|
- print '= link: %s' % msg['Url']
|
|
|
- print '= from: %s' % self.search_content('appname', content, 'xml')
|
|
|
- print '========================='
|
|
|
- elif msgType == 62:
|
|
|
- print '[Video] ', name, ' sent you a video, please check on mobiles'
|
|
|
- elif msgType == 53:
|
|
|
- print '[Video Call] ', name, ' call you'
|
|
|
- elif msgType == 10002:
|
|
|
- print '[Redraw] ', name, ' redraw back a message'
|
|
|
+ content = {'type': appMsgType[msg['AppMsgType']], 'title': msg['FileName'], 'desc': self.search_content('des', content, 'xml'), 'url': msg['Url'], 'from': self.search_content('appname', content, 'xml')}
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Share] %s : %s' % (name, appMsgType[msg['AppMsgType']])
|
|
|
+ print '========================='
|
|
|
+ print '= title: %s' % msg['FileName']
|
|
|
+ print '= desc: %s' % self.search_content('des', content, 'xml')
|
|
|
+ print '= link: %s' % msg['Url']
|
|
|
+ print '= from: %s' % self.search_content('appname', content, 'xml')
|
|
|
+ print '========================='
|
|
|
+
|
|
|
+ elif mtype == 62:
|
|
|
+ msg_type_id = 11
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Video] ', name, ' sent you a video, please check on mobiles'
|
|
|
+
|
|
|
+ elif mtype == 53:
|
|
|
+ msg_type_id = 12
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Video Call] ', name, ' call you'
|
|
|
+ elif mtype == 10002:
|
|
|
+ msg_type_id = 13
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Redraw] ', name, ' redraw back a message'
|
|
|
else:
|
|
|
- print '[Maybe] : %s,maybe image or link' % str(msg['MsgType'])
|
|
|
- print msg
|
|
|
+ msg_type_id = 99
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[Unknown] : %s' % str(mtype)
|
|
|
+ print msg
|
|
|
+ message = {'user_type': user_type, 'msg_id':msg_id, 'msg_type_id': msg_type_id, 'content': content, 'user_id': msg['FromUserName'], 'user_name': name}
|
|
|
+ self.handle_msg_all(message)
|
|
|
+
|
|
|
+ def schedule(self):
|
|
|
+ pass
|
|
|
|
|
|
def proc_msg(self):
|
|
|
- print 'proc start'
|
|
|
self.test_sync_check()
|
|
|
while True:
|
|
|
[retcode, selector] = self.sync_check()
|
|
|
- if retcode == '1100':
|
|
|
+ if retcode == '1100': # User have login on mobile
|
|
|
pass
|
|
|
- #print '[*] you have login on mobile'
|
|
|
elif retcode == '0':
|
|
|
if selector == '2':
|
|
|
r = self.sync()
|
|
|
if r is not None:
|
|
|
self.handle_msg(r)
|
|
|
- elif selector == '7': # play WeChat on mobile
|
|
|
+ elif selector == '7': # Play WeChat on mobile
|
|
|
r = self.sync()
|
|
|
if r is not None:
|
|
|
self.handle_msg(r)
|
|
|
elif selector == '0':
|
|
|
time.sleep(1)
|
|
|
+ self.schedule()
|
|
|
|
|
|
def send_msg_by_uid(self, word, dst = 'filehelper'):
|
|
|
url = self.base_uri + '/webwxsendmsg?pass_ticket=%s' % (self.pass_ticket)
|
|
|
msg_id = str(int(time.time()*1000)) + str(random.random())[:5].replace('.','')
|
|
|
params = {
|
|
|
- 'BaseRequest': self.BaseRequest,
|
|
|
+ 'BaseRequest': self.base_request,
|
|
|
'Msg': {
|
|
|
"Type": 1,
|
|
|
"Content": make_unicode(word),
|
|
|
- "FromUserName": self.User['UserName'],
|
|
|
+ "FromUserName": self.user['UserName'],
|
|
|
"ToUserName": dst,
|
|
|
"LocalID": msg_id,
|
|
|
"ClientMsgId": msg_id
|
|
@@ -478,8 +541,10 @@ class WXBot:
|
|
|
else:
|
|
|
return False
|
|
|
else:
|
|
|
- print '[*] this user does not exist'
|
|
|
- return False
|
|
|
+ if self.DEBUG:
|
|
|
+ print '[ERROR] This user does not exist .'
|
|
|
+ return True
|
|
|
+
|
|
|
def search_content(self, key, content, fmat = 'attr'):
|
|
|
if fmat == 'attr':
|
|
|
pm = re.search(key+'\s?=\s?"([^"<]+)"', content)
|
|
@@ -491,40 +556,23 @@ class WXBot:
|
|
|
|
|
|
def run(self):
|
|
|
self.get_uuid()
|
|
|
- print 'get uuid end'
|
|
|
- self.gen_qr_code()
|
|
|
- print 'gen qr code end'
|
|
|
+ self.gen_qr_code('qr.png')
|
|
|
+ print '[INFO] Please use WeCaht to scan the QR code .'
|
|
|
self.wait4login(1)
|
|
|
- print 'wait4login end'
|
|
|
+ print '[INFO] Please confirm to login .'
|
|
|
self.wait4login(0)
|
|
|
- print 'wait4login end'
|
|
|
if self.login():
|
|
|
- print 'login succeed'
|
|
|
+ print '[INFO] Web WeChat login succeed .'
|
|
|
else:
|
|
|
- print 'login failed'
|
|
|
+ print '[ERROR] Web WeChat login failed .'
|
|
|
return
|
|
|
if self.init():
|
|
|
- print 'init succeed'
|
|
|
+ print '[INFO] Web WeChat init succeed .'
|
|
|
else:
|
|
|
- print 'init failed'
|
|
|
+ print '[INFO] Web WeChat init failed'
|
|
|
return
|
|
|
- print 'init end'
|
|
|
self.status_notify()
|
|
|
- print 'status notify end'
|
|
|
self.get_contact()
|
|
|
- print 'get %d contacts' % len(self.ContactList)
|
|
|
-
|
|
|
- if raw_input('auto reply?(y/n): ') == 'y':
|
|
|
- self.is_auto_reply = True
|
|
|
- print 'auto reply opened'
|
|
|
- else:
|
|
|
- print 'auto reply closed'
|
|
|
-
|
|
|
+ print '[INFO] Get %d contacts' % len(self.contact_list)
|
|
|
+ print '[INFO] Start to process messages .'
|
|
|
self.proc_msg()
|
|
|
-
|
|
|
-def main():
|
|
|
- bot = WXBot()
|
|
|
- bot.run()
|
|
|
-
|
|
|
-if __name__ == '__main__':
|
|
|
- main()
|