Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复1120的问题, 同步接口变更 #141

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ Web微信协议参考资料:

[qwx: WeChat Qt frontend 微信Qt前端](https://github.com/xiangzhai/qwx)

**master-dev 分支为开发版本,用于测试新特性,欢迎使用后提出建议!**


## 1 环境与依赖

此版本只能运行于Python 2环境 。

**wxBot** 用到了Python **requests** , **pypng** , **Pillow* 以及 **pyqrcode** 库。
**wxBot** 用到了Python **requests** , **pypng** , **Pillow** 以及 **pyqrcode** 库。

使用之前需要所依赖的库:

Expand Down Expand Up @@ -264,3 +266,9 @@ python test.py
[Urinx/WeixinBot](https://github.com/Urinx/WeixinBot) 网页版微信API,包含终端版微信及微信机器人

[zixia/wechaty](https://github.com/zixia/wechaty) Wechaty is wechat for bot in Javascript(ES6). It's a Personal Account Robot Framework/Library.

## 7 交流讨论

问题可以直接开 **issue**

**QQ** 交流群: **429134510**
180 changes: 156 additions & 24 deletions wxbot.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,11 @@ def extract_msg_content(self, msg_type_id, msg):
if self.DEBUG:
voice = self.get_voice(msg_id)
print ' %s[Voice] %s' % (msg_prefix, voice)
elif mtype == 37:
msg_content['type'] = 37
msg_content['data'] = msg['RecommendInfo']
if self.DEBUG:
print ' %s[useradd] %s' % (msg_prefix,msg['RecommendInfo']['NickName'])
elif mtype == 42:
msg_content['type'] = 5
info = msg['RecommendInfo']
Expand Down Expand Up @@ -493,7 +498,7 @@ def extract_msg_content(self, msg_type_id, msg):
print ' | desc: %s' % self.search_content('des', content, 'xml')
print ' | link: %s' % msg['Url']
print ' | from: %s' % self.search_content('appname', content, 'xml')
print ' | content: %s' % msg.get('content')[:20]
print ' | content: %s' % (msg.get('content')[:20] if msg.get('content') else "unknown")
print ' --------------------------'

elif mtype == 62:
Expand Down Expand Up @@ -542,17 +547,17 @@ def handle_msg(self, r):
if msg['MsgType'] == 51: # init message
msg_type_id = 0
user['name'] = 'system'
elif msg['MsgType'] == 37:# 有人加好友 ,37为加好友信息?
weixinhao=msg['Content']
weixinhao=weixinhao[weixinhao.index('fromusername='):weixinhao.index('encryptusername')]
weixinhao=weixinhao[weixinhao.index('"')+1:weixinhao.rindex('"')]
print u'[INFO] 请求加好友!'
print u' 昵称:' + msg['RecommendInfo']['NickName']
#print u'ID:' + msg['RecommendInfo']['UserName']
print u' 附加消息:'+msg['RecommendInfo']['Content']
#print u'Ticket:'+msg['RecommendInfo']['Ticket'] # Ticket添加好友时要用
print u' 微信号:'+weixinhao #未设置微信号的 腾讯会自动生成一段微信ID 但是无法通过搜索 搜索到此人
return
elif msg['MsgType'] == 37: # friend request
msg_type_id = 37
pass
# content = msg['Content']
# username = content[content.index('fromusername='): content.index('encryptusername')]
# username = username[username.index('"') + 1: username.rindex('"')]
# print u'[Friend Request]'
# print u' Nickname:' + msg['RecommendInfo']['NickName']
# print u' 附加消息:'+msg['RecommendInfo']['Content']
# # print u'Ticket:'+msg['RecommendInfo']['Ticket'] # Ticket添加好友时要用
# print u' 微信号:'+username #未设置微信号的 腾讯会自动生成一段微信ID 但是无法通过搜索 搜索到此人
elif msg['FromUserName'] == self.my_account['UserName']: # Self
msg_type_id = 1
user['name'] = 'self'
Expand All @@ -579,7 +584,7 @@ def handle_msg(self, r):
user['name'] = HTMLParser.HTMLParser().unescape(user['name'])

if self.DEBUG and msg_type_id != 0:
print '[MSG] %s:' % user['name']
print u'[MSG] %s:' % user['name']
content = self.extract_msg_content(msg_type_id, msg)
message = {'msg_type_id': msg_type_id,
'msg_id': msg['MsgId'],
Expand Down Expand Up @@ -615,6 +620,10 @@ def proc_msg(self):
r = self.sync()
if r is not None:
self.handle_msg(r)
elif selector == '4': # 通讯录更新
r = self.sync()
if r is not None:
self.get_contact()
elif selector == '6': # 可能是红包
r = self.sync()
if r is not None:
Expand All @@ -640,6 +649,125 @@ def proc_msg(self):
if check_time < 0.8:
time.sleep(1 - check_time)

def apply_useradd_requests(self,RecommendInfo):
url = self.base_uri + '/webwxverifyuser?r='+str(int(time.time()))+'&lang=zh_CN'
params = {
"BaseRequest": self.base_request,
"Opcode": 3,
"VerifyUserListSize": 1,
"VerifyUserList": [
{
"Value": RecommendInfo['UserName'],
"VerifyUserTicket": RecommendInfo['Ticket'] }
],
"VerifyContent": "",
"SceneListCount": 1,
"SceneList": [
33
],
"skey": self.skey
}
headers = {'content-type': 'application/json; charset=UTF-8'}
data = json.dumps(params, ensure_ascii=False).encode('utf8')
try:
r = self.session.post(url, data=data, headers=headers)
except (ConnectionError, ReadTimeout):
return False
dic = r.json()
return dic['BaseResponse']['Ret'] == 0

def add_groupuser_to_friend_by_uid(self,uid,VerifyContent):
"""
主动向群内人员打招呼,提交添加好友请求
uid-群内人员得uid VerifyContent-好友招呼内容
慎用此接口!封号后果自负!慎用此接口!封号后果自负!慎用此接口!封号后果自负!
"""
if self.is_contact(uid):
return True
url = self.base_uri + '/webwxverifyuser?r='+str(int(time.time()))+'&lang=zh_CN'
params ={
"BaseRequest": self.base_request,
"Opcode": 2,
"VerifyUserListSize": 1,
"VerifyUserList": [
{
"Value": uid,
"VerifyUserTicket": ""
}
],
"VerifyContent": VerifyContent,
"SceneListCount": 1,
"SceneList": [
33
],
"skey": self.skey
}
headers = {'content-type': 'application/json; charset=UTF-8'}
data = json.dumps(params, ensure_ascii=False).encode('utf8')
try:
r = self.session.post(url, data=data, headers=headers)
except (ConnectionError, ReadTimeout):
return False
dic = r.json()
return dic['BaseResponse']['Ret'] == 0

def add_friend_to_group(self,uid,group_name):
"""
将好友加入到群聊中
"""
gid = ''
#通过群名获取群id,群没保存到通讯录中的话无法添加哦
for group in self.group_list:
if group['NickName'] == group_name:
gid = group['UserName']
if gid == '':
return False
#通过群id判断uid是否在群中
for user in self.group_members[gid]:
if user['UserName'] == uid:
#已经在群里面了,不用加了
return True
url = self.base_uri + '/webwxupdatechatroom?fun=addmember&pass_ticket=%s' % self.pass_ticket
params ={
"AddMemberList": uid,
"ChatRoomName": gid,
"BaseRequest": self.base_request
}
headers = {'content-type': 'application/json; charset=UTF-8'}
data = json.dumps(params, ensure_ascii=False).encode('utf8')
try:
r = self.session.post(url, data=data, headers=headers)
except (ConnectionError, ReadTimeout):
return False
dic = r.json()
return dic['BaseResponse']['Ret'] == 0

def delete_user_from_group(self,uname,gid):
"""
将群用户从群中剔除,只有群管理员有权限
"""
uid = ""
for user in self.group_members[gid]:
if user['NickName'] == uname:
uid = user['UserName']
if uid == "":
return False
url = self.base_uri + '/webwxupdatechatroom?fun=delmember&pass_ticket=%s' % self.pass_ticket
params ={
"DelMemberList": uid,
"ChatRoomName": gid,
"BaseRequest": self.base_request
}
headers = {'content-type': 'application/json; charset=UTF-8'}
data = json.dumps(params, ensure_ascii=False).encode('utf8')
try:
r = self.session.post(url, data=data, headers=headers)
except (ConnectionError, ReadTimeout):
return False
dic = r.json()
return dic['BaseResponse']['Ret'] == 0


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('.', '')
Expand Down Expand Up @@ -668,8 +796,8 @@ def upload_media(self, fpath, is_img=False):
if not os.path.exists(fpath):
print '[ERROR] File not exists.'
return None
url_1 = 'https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json'
url_2 = 'https://file2.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json'
url_1 = 'https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json'
url_2 = 'https://file2.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json'
flen = str(os.path.getsize(fpath))
ftype = mimetypes.guess_type(fpath)[0] or 'application/octet-stream'
files = {
Expand All @@ -689,7 +817,7 @@ def upload_media(self, fpath, is_img=False):
})),
'webwx_data_ticket': (None, self.session.cookies['webwx_data_ticket']),
'pass_ticket': (None, self.pass_ticket),
'filename': (os.path.basename(os.path.join(self.temp_pwd,fpath)), open(os.path.join(self.temp_pwd,fpath), 'rb'),ftype.split('/')[1]),
'filename': (os.path.basename(fpath), open(fpath, 'rb'),ftype.split('/')[1]),
}
self.file_index += 1
try:
Expand Down Expand Up @@ -783,7 +911,7 @@ def send_msg(self, name, word, isfile=False):
uid = self.get_user_id(name)
if uid is not None:
if isfile:
with open(os.path.join(self.temp_pwd,word), 'r') as f:
with open(word, 'r') as f:
result = True
for line in f.readlines():
line = line.replace('\n', '')
Expand Down Expand Up @@ -988,12 +1116,15 @@ def status_notify(self):
return dic['BaseResponse']['Ret'] == 0

def test_sync_check(self):
for host in ['webpush', 'webpush2']:
self.sync_host = host
retcode = self.sync_check()[0]
if retcode == '0':
return True
return False
for host1 in ['webpush.', 'webpush2.']:
for host2 in ['weixin','wx','wx2']:
self.sync_host = host1+host2
try:
retcode = self.sync_check()[0]
except:
retcode == -1
if retcode == '0':
return True

def sync_check(self):
params = {
Expand All @@ -1005,7 +1136,7 @@ def sync_check(self):
'synckey': self.sync_key_str,
'_': int(time.time()),
}
url = 'https://' + self.sync_host + '.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?' + urllib.urlencode(params)
url = 'https://' + self.sync_host + '.qq.com/cgi-bin/mmwebwx-bin/synccheck?' + urllib.urlencode(params)
try:
r = self.session.get(url, timeout=60)
r.encoding = 'utf-8'
Expand Down Expand Up @@ -1118,3 +1249,4 @@ def set_remarkname(self,uid,remarkname):#设置联系人的备注名
return dic['BaseResponse']['ErrMsg']
except:
return None