Esempio n. 1
0
    def _get_qr_code(self):
        """
        生成微信登录二维码
        :return:
        """
        params = {
            'appid': WECHAT_APP_ID,
            'fun': 'new',
            'lang': 'zh_CN',
            '_': now() * 1000 + random.randint(1, 999),
        }
        r = self.session.get(WECHAT_FIRST_LOGIN_URL, params=params)
        r.encoding = 'utf-8'
        data = r.text
        regex = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)"'
        pm = re.search(regex, data)
        if pm:
            code = pm.group(1)
            self.params['uuid'] = pm.group(2)
            assert code == '200'
        else:
            raise BotServerException(BotErrorCode.GET_UUID_ERROR)

        img = qrcode.make(WECHAT_QR_CODE_STRING.format(self.params['uuid']))
        img_in_memory = io.BytesIO()
        img.save(img_in_memory, 'png')
        img_in_memory.seek(0)
        files = {'smfile': img_in_memory}
        resp = requests.post(UPLOAD_IMG_URL, files=files)
        qr_code_url = json.loads(resp.content)['data']['url']
        self.logger.info(red_alert(u"请打开此网页并扫描二维码:{}".format(qr_code_url)))
        img_in_memory.truncate()
Esempio n. 2
0
    def sync_check(self):
        """
        sync check.
        """

        params = {
            'r': now(),
            'skey': self.params['skey'],
            'sid': self.params['sid'],
            'uin': self.params['uin'],
            'deviceid': self.params['device_id'],
            'synckey': self.params['sync_key_str'],
            '_': now()
        }

        url = WECHAT_BOT_SYNC_CHECK_URL.format(
            sync_host=self.params['sync_host'],
            params=urllib.urlencode(params))

        while True:
            try:
                r = self.session.get(url, timeout=20)
                r.encoding = 'utf-8'
                data = r.text
                pm = re.search(
                    r'window.synccheck=\{retcode:"(\d+)",selector:"(\d+)"\}',
                    data)
                retcode = pm.group(1)
                selector = pm.group(2)
                return [retcode, selector]
            except requests.exceptions.ReadTimeout:
                pass
            except:
                raise BotServerException(BotErrorCode.SYNC_CHECK_ERROR)
Esempio n. 3
0
 def sync_host_check(self):
     for host in ['webpush.', 'webpush2.']:
         self.params['sync_host'] = host + self.params['base_host']
         try:
             code, selector = self.sync_check()
             if code == '0':
                 return True
         except Exception as e:
             self.logger.info(e)
     raise BotServerException(BotErrorCode.SYNC_HOST_CHECK_ERROR)
Esempio n. 4
0
 def send_msg(self, reply):
     url = self.params['base_uri'] + '/webwxsendmsg'
     msg_id = str(now() * 1000) + str(random.random())[:5].replace('.', '')
     reply['Msg'].update({'LocalId': msg_id, 'ClientMsgId': msg_id})
     data = json.dumps(reply, ensure_ascii=False).encode('utf-8')
     for i in range(5):
         try:
             r = self.session.post(url,
                                   data=data,
                                   headers=WECHAT_SEND_MSG_HEADER)
         except (requests.exceptions.ConnectTimeout,
                 requests.exceptions.ReadTimeout):
             pass
         if r.status_code == 200:
             return
     raise BotServerException(BotErrorCode.SEND_MSG_ERROR)
Esempio n. 5
0
    def sync(self):
        url = WECHAT_BOT_SYNC_URL.format(
            base_uri=self.params['base_uri'],
            sid=self.params['sid'],
            skey=self.params['skey'],
            pass_ticket=self.params['pass_ticket'])

        params = {
            'BaseRequest': self.params['base_request'],
            'SyncKey': self.params['sync_key'],
            'rr': ~int(now())
        }
        try:
            r = self.session.post(url, data=json.dumps(params), timeout=60)
            r.encoding = 'utf-8'
            dic = json.loads(r.text)
            if dic['BaseResponse']['Ret'] == 0:
                self.params['sync_key'] = dic['SyncKey']
                self.params['sync_key_str'] = '|'.join(
                    str(data['Key']) + '_' + str(data['Val'])
                    for data in self.params['sync_key']['List'])
            return dic
        except Exception:
            raise BotServerException(BotErrorCode.SYNC_ERROR)
Esempio n. 6
0
    def login(self, using_snap_shot=True):
        """
        登录
        :return:
        """
        self._get_qr_code() if not using_snap_shot else self.read_snapshot()

        redirect_url = None
        tip = 1

        while not redirect_url:
            url = WECHAT_SECONT_LOGIN_URL.format(tip=tip,
                                                 uuid=self.params['uuid'],
                                                 now=now())
            resp = self.session.get(url, headers=WECHAT_HEADERS)

            param = re.search(r'window.code=(\d+);', resp.text)
            code = param.group(1)

            if code == '201':
                tip = 0
            elif code == '200':
                redirect_urls = re.search(r'\"(?P<redirect_url>.*)\"',
                                          resp.content)
                if redirect_urls:
                    redirect_url = redirect_urls.group(
                        'redirect_url') + '&fun=new'
                    self.params['base_uri'] = redirect_url[:redirect_url.
                                                           rfind('/')]
                    temp_host = self.params['base_uri'][8:]
                    self.params['base_host'] = temp_host[:temp_host.find("/")]
            elif code == '400':
                raise BotServerException(BotErrorCode.SNAPSHOT_EXPIRED)
            else:
                tip = 1

        resp = self.session.get(redirect_url)

        doc = xml.dom.minidom.parseString(resp.text.encode('utf-8'))
        root = doc.documentElement

        for node in root.childNodes:
            if node.nodeName == 'skey':
                self.params['skey'] = node.childNodes[0].data
            elif node.nodeName == 'wxsid':
                self.params['sid'] = node.childNodes[0].data
            elif node.nodeName == 'wxuin':
                self.params['uin'] = node.childNodes[0].data
            elif node.nodeName == 'pass_ticket':
                self.params['pass_ticket'] = node.childNodes[0].data
        if all([
                self.params['skey'], self.params['sid'], self.params['uin'],
                self.params['pass_ticket']
        ]):
            self.params['base_request'] = {
                'DeviceID': self.params['device_id'],
                'Sid': self.params['sid'],
                'Skey': self.params['skey'],
                'Uin': self.params['uin']
            }
            self.init()
            self.save_snapshot()
            return True
        raise BotServerException(BotErrorCode.LOGIN_ERROR)