def weixinlogin(): api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) authorize_url = api.get_authorize_url(scope=("snsapi_base", )) #redirect_uri = api.get_authorize_login_url(scope=("snsapi_login",)) return redirect(authorize_url)
def login(): '''获取用户信息''' api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) redirect_uri = api.get_authorize_login_url(scope=("snsapi_login",)) return redirect(redirect_uri)
def login(): global APP_ID, APP_SECRET, REDIRECT_URI api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) redirect_uri = api.get_authorize_login_url(scope=("snsapi_base",)) return redirect(redirect_uri)
def weixin_login(request): api = WeixinAPI( appid=settings.APP_ID, app_secret=settings.APP_SECRERT, redirect_uri=settings.REDIRECT_URI ) redirect_uri = api.get_authorize_login_url(scope=('snsapi_login',)) return Response(data=redirect_uri, status=status.HTTP_200_OK)
def authorization(): code = request.args.get('code') api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) return jsonify(resp)
def authorization(): '''用户验证''' code = request.args.get('code') api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) with app.test_request_context(): if check_user(auth_info['openid']): requests.post(data=resp) else: requests.put(data=resp) return jsonify(code=0)
class WechatAuth(): def __init__(self): self.PC_api = WeixinAPI(appid = PC_APP_ID, app_secret = PC_APP_SECRET, redirect_uri = REDIRECT_URL) self.Mobile_api = WeixinMpAPI(appid = WX_APP_ID, app_secret = WX_APP_SECRET, redirect_uri = REDIRECT_URL) self.pc_auth_url = self.PC_api.get_authorize_url(scope=(PC_SCOPE,)) self.mobile_auth_url = self.Mobile_api.get_authorize_url(scope=(WX_SCOPE,)) def get_authorize_url(self, request): if checkMobile(request) == True: print self.mobile_auth_url return self.mobile_auth_url else: print self.pc_auth_url return self.pc_auth_url def get_user(self, request): try: code = "" if request.GET.has_key('code'): code = request.GET['code'] else: return None if checkMobile(request) == True: auth_info = self.Mobile_api.exchange_code_for_access_token(code=code) userApi = WeixinMpAPI(access_token=auth_info['access_token']) user_info = userApi.user(openid=auth_info['openid']) print auth_info, user_info return user_info else: auth_info = self.PC_api.exchange_code_for_access_token(code=code) userApi = WeixinAPI(access_token=auth_info['access_token']) user_info = userApi.user(openid=auth_info['openid']) return user_info except Exception, e: printError(e) return None
def __init__(self): self.PC_api = WeixinAPI(appid = PC_APP_ID, app_secret = PC_APP_SECRET, redirect_uri = REDIRECT_URL) self.Mobile_api = WeixinMpAPI(appid = WX_APP_ID, app_secret = WX_APP_SECRET, redirect_uri = REDIRECT_URL) self.pc_auth_url = self.PC_api.get_authorize_url(scope=(PC_SCOPE,)) self.mobile_auth_url = self.Mobile_api.get_authorize_url(scope=(WX_SCOPE,))
def authorization(request): """ 获取用户信息,登录,跳转 :param request: :return: """ """ https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx6fe7f0568b75d925&redirect_uri=http://www.yinzishao.cn/authorization&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect """ code = request.GET.get('code') auth_redirect_uri = DOMAIN + "authorization" api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=auth_redirect_uri) auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) request.session['info'] = resp openid = resp['openid'] try: user = User.objects.get(username=openid) except User.DoesNotExist,e: print "user not exist" user = User.objects.create_user(openid,password=openid)
def weixin_authorization(request): code = request.GET.get('code') api = WeixinAPI( appid=settings.APP_ID, app_secret=settings.APP_SECRERT, redirect_uri=settings.REDIRECT_URI ) auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) return Response(data=resp, status=status.HTTP_200_OK)
def get(self, request): print(1111111111) code = request.GET.get('code') print(code) api = WeixinAPI(appid="wxbb19e286afae10db", app_secret="064004a0dd2a8a4c0eeed40975e8907c", redirect_uri="http://127.0.0.1:8000/authorization") auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) return redirect( "http://127.0.0.1:8000/taskpub?nickname={}&headimgurl={}".format( resp["nickname"], resp["headimgurl"]))
def adminAuthorization(request): """ 获取用户信息,登录,跳转 :param request: :return: """ auth_redirect_uri = DOMAIN + "adminAuthorization" code = request.GET.get('code') api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=auth_redirect_uri) auth_info = api.exchange_code_for_access_token(code=code) api = WeixinAPI(access_token=auth_info['access_token']) resp = api.user(openid=auth_info['openid']) request.session['info'] = resp return redirect(DOMAIN + 'administor/view/index.html')
# -*- coding: utf-8 -*- from weixin.client import WeixinAPI from weixin.oauth2 import OAuth2AuthExchangeError APP_ID = 'your app id' APP_SECRET = 'your secret' REDIRECT_URI = 'http://www.exmple.com' code = '0418f2c46cd26e4f9eee5bf03320662M' api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) try: pass # print api.get_authorize_login_url(scope=("snsapi_login",)) # print api.exchange_code_for_access_token(code=code) except OAuth2AuthExchangeError as e: print(e) auth_info = { 'access_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw-NdEN9dPkEX8Yewsve2AktmzS0gmbvzRKO49l6sxHRfhXg1no5ObdGufYhRIubP2m3FUdv-Cop3t3S_xwMbBWQ', 'refresh_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw44bjXRXdmPsclqGIjWs777H3p00QI9a3hzX265Uq9fPJZttNQApdCRPbySXDfofbjniiwsVJiT7fTv7j5jCAxg', 'openid': u'oV02tuA8Wt6Kk7S0pVydThYvmSJA', 'expires_in': 7200, 'scope': u'snsapi_login' } try:
class WechatBasic(object): """ 微信基本功能类 仅包含官方 API 中所包含的内容, 如需高级功能支持请移步 ext.py 中的 WechatExt 类 """ def __init__(self, token=None, appid=None, appsecret=None, partnerid=None, partnerkey=None, paysignkey=None, access_token=None, access_token_expires_at=None, jsapi_ticket=None, jsapi_ticket_expires_at=None, weixinname=None, firsteye=None, menuMap=None, owner_db=None, open_appid=None, open_secrept=None, open_redirect_uri=None): """ :param token: 微信 Token :param appid: App ID :param appsecret: App Secret :param partnerid: 财付通商户身份标识, 支付权限专用 :param partnerkey: 财付通商户权限密钥 Key, 支付权限专用 :param paysignkey: 商户签名密钥 Key, 支付权限专用 :param access_token: 直接导入的 access_token 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param access_token_expires_at: 直接导入的 access_token 的过期日期,该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param jsapi_ticket: 直接导入的 jsapi_ticket 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param jsapi_ticket_expires_at: 直接导入的 jsapi_ticket 的过期日期,该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 """ self.__token = token self.__token = token self.__appid = appid self.__appsecret = appsecret self.__partnerid = partnerid self.__partnerkey = partnerkey self.__paysignkey = paysignkey self.__access_token = access_token self.__access_token_expires_at = access_token_expires_at self.__jsapi_ticket = jsapi_ticket self.__jsapi_ticket_expires_at = jsapi_ticket_expires_at self.__is_parse = False self.__message = None self.__weixinname = weixinname self.owner_db = owner_db #实例属性 self.token = token self.appid = appid self.open_appid = open_appid self.open_secrept = open_secrept self.appsecret = appsecret self.partnerid = partnerid self.partnerkey = partnerkey self.paysignkey = paysignkey self.firsteye = firsteye self.menuMap = menuMap self.weixinName = weixinname self.open_redirect_uri = open_redirect_uri self.openapi = WeixinAPI(appid=self.open_appid, app_secret=self.open_secrept, redirect_uri=self.open_redirect_uri) def getManager(self, openid=None): if openid == None: _ret = self.owner_db.query("SELECT * FROM Manager".format( self.weixinName)) ret = [] for mgr in _ret: ret.append(mgr) else: _ret = self.owner_db.query( "SELECT * FROM Manager WHERE openid = '{0}'".format( openid, self.weixinName)) if len(_ret) > 0: ret = _ret[0] else: ret = None return ret def getOwOpendid(self, data): auth_info = self.openapi.exchange_code_for_access_token(code=data.code) user = self.relateUserId(auth_info, "webopenid") return user.openid def getOpenid(self, data): if data.has_key('openid'): openid = data.openid elif data.has_key("state"): if data.state == "pcweb_login": openid = self.getOwOpendid(data) else: openid = self.getWxOpenid(data) else: openid = "error" return openid.encode("utf-8") def getWxOpenid(self, data): code = data.code self._check_appid_appsecret() reponse = self._get( url="https://api.weixin.qq.com/sns/oauth2/access_token", params={ "grant_type": "authorization_code", "appid": self.__appid, "secret": self.__appsecret, "code": code }) return reponse["openid"] def relateUserId(self, user, userid): _ret = db.query("SELECT * FROM Customer WHERE unionid='{0}'".format( user["unionid"])) weixin_user = None if len(_ret) == 1: weixin_user = _ret[0] db.query("UPDATE Customer SET {0} = '{1}' WHERE id={2}".format( userid, user['openid'], weixin_user.id)) return weixin_user def getAuth2Url(self, url): before = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=" % self.__appid after = "&response_type=code&scope=snsapi_base&state=123#wechat_redirect" return urllib.unquote(before + url + after) def check_signature(self, signature, timestamp, nonce): """ 验证微信消息真实性 :param signature: 微信加密签名 :param timestamp: 时间戳 :param nonce: 随机数 :return: 通过验证返回 True, 未通过验证返回 False """ self._check_token() if not signature or not timestamp or not nonce: return False tmp_list = [self.__token, timestamp, nonce] tmp_list.sort() tmp_str = ''.join(tmp_list) if signature == hashlib.sha1(tmp_str).hexdigest(): return True else: return False def generate_jsapi_signature(self, timestamp, noncestr, url, jsapi_ticket=None): """ 使用 jsapi_ticket 对 url 进行签名 :param timestamp: 时间戳 :param noncestr: 随机数 :param url: 要签名的 url,不包含 # 及其后面部分 :param jsapi_ticket: (可选参数) jsapi_ticket 值 (如不提供将自动通过 appid 和 appsecret 获取) :return: 返回sha1签名的hexdigest值 """ if not jsapi_ticket: jsapi_ticket = self.jsapi_ticket data = { 'jsapi_ticket': jsapi_ticket, 'noncestr': noncestr, 'timestamp': timestamp, 'url': url, } keys = data.keys() keys.sort() data_str = '&'.join(['%s=%s' % (key, data[key]) for key in keys]) signature = hashlib.sha1(data_str).hexdigest() return signature def parse_data(self, data): """ 解析微信服务器发送过来的数据并保存类中 :param data: HTTP Request 的 Body 数据 :raises ParseError: 解析微信服务器数据错误, 数据不合法 """ result = {} if type(data) == unicode: data = data.encode('utf-8') elif type(data) == str: pass else: raise ParseError() try: doc = minidom.parseString(data) except Exception: raise ParseError() params = [ ele for ele in doc.childNodes[0].childNodes if isinstance(ele, minidom.Element) ] for param in params: if param.childNodes: text = param.childNodes[0] result[param.tagName] = text.data result['raw'] = data result['type'] = result.pop('MsgType').lower() message_type = MESSAGE_TYPES.get(result['type'], UnknownMessage) self.__message = message_type(result) self.__is_parse = True def get_message(self): """ 获取解析好的 WechatMessage 对象 :return: 解析好的 WechatMessage 对象 """ self._check_parse() return self.__message def get_access_token(self): """ 获取 Access Token 及 Access Token 过期日期, 仅供缓存使用, 如果希望得到原生的 Access Token 请求数据请使用 :func:`grant_token` :return: dict 对象, key 包括 `access_token` 及 `access_token_expires_at` """ self._check_appid_appsecret() return { 'access_token': self.access_token, 'access_token_expires_at': self.__access_token_expires_at, } def get_jsapi_ticket(self): """ 获取 Jsapi Ticket 及 Jsapi Ticket 过期日期, 仅供缓存使用, 如果希望得到原生的 Jsapi Ticket 请求数据请使用 :func:`grant_jsapi_ticket` :return: dict 对象, key 包括 `jsapi_ticket` 及 `jsapi_ticket_expires_at` """ self._check_appid_appsecret() return { 'jsapi_ticket': self.jsapi_ticket, 'jsapi_ticket_expires_at': self.__jsapi_ticket_expires_at, } def response_text(self, content, escape=False): """ 将文字信息 content 组装为符合微信服务器要求的响应数据 :param content: 回复文字 :param escape: 是否转义该文本内容 (默认不转义) :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() content = self._transcoding(content) if escape: content = cgi.escape(content) return TextReply(message=self.__message, content=content).render() def response_image(self, media_id): """ 将 media_id 所代表的图片组装为符合微信服务器要求的响应数据 :param media_id: 图片的 MediaID :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() return ImageReply(message=self.__message, media_id=media_id).render() def response_voice(self, media_id): """ 将 media_id 所代表的语音组装为符合微信服务器要求的响应数据 :param media_id: 语音的 MediaID :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() return VoiceReply(message=self.__message, media_id=media_id).render() def response_video(self, media_id, title=None, description=None): """ 将 media_id 所代表的视频组装为符合微信服务器要求的响应数据 :param media_id: 视频的 MediaID :param title: 视频消息的标题 :param description: 视频消息的描述 :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() title = self._transcoding(title) description = self._transcoding(description) return VideoReply(message=self.__message, media_id=media_id, title=title, description=description).render() def response_music(self, music_url, title=None, description=None, hq_music_url=None, thumb_media_id=None): """ 将音乐信息组装为符合微信服务器要求的响应数据 :param music_url: 音乐链接 :param title: 音乐标题 :param description: 音乐描述 :param hq_music_url: 高质量音乐链接, WIFI环境优先使用该链接播放音乐 :param thumb_media_id: 缩略图的 MediaID :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() music_url = self._transcoding(music_url) title = self._transcoding(title) description = self._transcoding(description) hq_music_url = self._transcoding(hq_music_url) return MusicReply(message=self.__message, title=title, description=description, music_url=music_url, hq_music_url=hq_music_url, thumb_media_id=thumb_media_id).render() def response_news(self, articles): """ 将新闻信息组装为符合微信服务器要求的响应数据 :param articles: list 对象, 每个元素为一个 dict 对象, key 包含 `title`, `description`, `picurl`, `url` :return: 符合微信服务器要求的 XML 响应数据 """ self._check_parse() for article in articles: if article.get('title'): article['title'] = self._transcoding(article['title']) if article.get('description'): article['description'] = self._transcoding( article['description']) if article.get('picurl'): article['picurl'] = self._transcoding(article['picurl']) if article.get('url'): article['url'] = self._transcoding(article['url']) news = ArticleReply(message=self.__message) for article in articles: article = Article(**article) news.add_article(article) return news.render() def grant_token(self): """ 获取 Access Token 详情请参考 http://mp.weixin.qq.com/wiki/11/0e4b294685f817b95cbed85ba5e82b8f.html :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get(url="https://api.weixin.qq.com/cgi-bin/token", params={ "grant_type": "client_credential", "appid": self.__appid, "secret": self.__appsecret, }) def grant_jsapi_ticket(self): """ 获取 Jsapi Ticket 详情请参考 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.951-JS-SDK.E4.BD.BF.E7.94.A8.E6.9D.83.E9.99.90.E7.AD.BE.E5.90.8D.E7.AE.97.E6.B3.95 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get( url="https://api.weixin.qq.com/cgi-bin/ticket/getticket", params={ "access_token": self.access_token, "type": "jsapi", }) def create_menu(self, menu_data): """ 创建自定义菜单 :: wechat = WechatBasic(appid='appid', appsecret='appsecret') wechat.create_menu({ 'button':[ { 'type':'click', 'name':u'今日歌曲', 'key':'V1001_TODAY_MUSIC' }, { 'type':'click', 'name':u'歌手简介', 'key':'V1001_TODAY_SINGER' }, { 'name':u'菜单', 'sub_button':[ { 'type':'view', 'name':u'搜索', 'url':'http://www.soso.com/' }, { 'type':'view', 'name':u'视频', 'url':'http://v.qq.com/' }, { 'type':'click', 'name':u'赞一下我们', 'key':'V1001_GOOD' } ] } ]}) 详情请参考 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html :param menu_data: Python 字典 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post(url='https://api.weixin.qq.com/cgi-bin/menu/create', data=menu_data) def get_menu(self): """ 查询自定义菜单 详情请参考 http://mp.weixin.qq.com/wiki/16/ff9b7b85220e1396ffa16794a9d95adc.html :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get('https://api.weixin.qq.com/cgi-bin/menu/get') def delete_menu(self): """ 删除自定义菜单 详情请参考 http://mp.weixin.qq.com/wiki/16/8ed41ba931e4845844ad6d1eeb8060c8.html :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get('https://api.weixin.qq.com/cgi-bin/menu/delete') def upload_media(self, media_type, media_file, extension=''): """ 上传多媒体文件 详情请参考 http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html :param media_type: 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) :param media_file: 要上传的文件,一个 File object 或 StringIO object :param extension: 如果 media_file 传入的为 StringIO object,那么必须传入 extension 显示指明该媒体文件扩展名,如 ``mp3``, ``amr``;如果 media_file 传入的为 File object,那么该参数请留空 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() if not isinstance(media_file, file) and not isinstance( media_file, StringIO): raise ValueError( 'Parameter media_file must be file object or StringIO.StringIO object.' ) if isinstance(media_file, StringIO) and extension.lower() not in [ 'jpg', 'jpeg', 'amr', 'mp3', 'mp4' ]: raise ValueError( 'Please provide \'extension\' parameters when the type of \'media_file\' is \'StringIO.StringIO\'.' ) if isinstance(media_file, file): extension = media_file.name.split('.')[-1] if extension.lower() not in ['jpg', 'jpeg', 'amr', 'mp3', 'mp4']: raise ValueError('Invalid file type.') ext = { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'amr': 'audio/amr', 'mp3': 'audio/mpeg', 'mp4': 'video/mp4', } if isinstance(media_file, StringIO): filename = 'temp.' + extension else: filename = media_file.name return self._post( url='http://file.api.weixin.qq.com/cgi-bin/media/upload', params={ 'access_token': self.access_token, 'type': media_type, }, files={'media': (filename, media_file, ext[extension])}) def upload_media2(self, media_type, media_file, extension): """ 上传多媒体文件 详情请参考 http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html :param media_type: 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb) :param media_file: 要上传的文件,一个 File object 或 StringIO object :param extension: 如果 media_file 传入的为 StringIO object,那么必须传入 extension 显示指明该媒体文件扩展名,如 ``mp3``, ``amr``;如果 media_file 传入的为 File object,那么该参数请留空 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ #self._check_appid_appsecret() #if not isinstance(media_file, str): # raise ValueError('Parameter media_file({0}) must be str object.'.format(type(media_file))) #if isinstance(media_file, str) and extension.lower() not in ['jpg', 'jpeg', 'amr', 'mp3', 'mp4']: # raise ValueError('Please provide \'extension\' parameters when the type of \'media_file\' is \'StringIO.StringIO\'.') ext = { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'amr': 'audio/amr', 'mp3': 'audio/mpeg', 'mp4': 'video/mp4', } filename = 'temp.' + extension return self._post( url='http://file.api.weixin.qq.com/cgi-bin/media/upload', params={ 'access_token': self.access_token, 'type': media_type, }, files={'file': (filename, media_file, ext[extension])}) def send_template_msg(self, msg): """ 第一步:获取模板ID 通过在模板消息功能的模板库中使用需要的模板,可以获得模板ID。 第二步:请求接口 请注意,URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。 POST请求 https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN """ #print("send_template_msg:{0}".format(msg)) self._check_appid_appsecret() return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' + self.access_token, data=msg) #记录发给用户的消息时间间隔,避免重复的给用户发消息,至少间隔1分钟 #1分钟间隔 3次 #10分钟 1次 #30分钟 1次 #1小时 1次 #超过1小时 不再发 #24小时后 重新开始 def customser_msg_is_frequent(self, openid, cmd, continue_decide="yes", minutes_span=1): is_frequent = True valid_time = datetime.datetime.now() - datetime.timedelta(hours=24) _ret = db.query( "SELECT * FROM CmdLog WHERE openid='{0}' AND cmd='{1}' AND create_at>'{2}' ORDER BY create_at DESC" .format(openid, cmd, valid_time)) if len(_ret) == 0: is_frequent = False else: cmd_num = len(_ret) cmd_log = _ret[0] min_span = (datetime.datetime.now() - cmd_log.create_at).total_seconds() / 60.0 if continue_decide == "yes": if cmd_num <= 2: is_frequent = (True if min_span < minutes_span else False) elif cmd_num == 3: is_frequent = (True if min_span < minutes_span * 10 else False) elif cmd_num == 4: is_frequent = (True if min_span < minutes_span * 30 else False) elif cmd_num == 5: is_frequent = (True if min_span < minutes_span * 60 else False) else: is_frequent = True else: if min_span > minutes_span: is_frequent = False else: is_frequent = True if is_frequent == False: _ret = db.insert("CmdLog", openid=openid, cmd=cmd, create_at=datetime.datetime.now()) return is_frequent def send_customer_text_msg(self, openid, msg, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "text", "text": { "content": msg } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) def send_customer_voice_msg(self, openid, media_id, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "voice", "voice": { "media_id": media_id } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) def send_customer_image_msg(self, openid, media_id, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "image", "image": { "media_id": media_id } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) def send_customer_video_msg(self, openid, title, media_id, thumb_media_id, description, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "video", "video": { "media_id": media_id, "thumb_media_id": thumb_media_id, "title": title, "description": description } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) def send_customer_music_msg(self, openid, title, music_url, hq_music_url, thumb_media_id, description, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "music", "music": { "title": title, "description": description, "musicurl": music_url, "hqmusicurl": hq_music_url, "thumb_media_id": thumb_media_id } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) #发送图文消息 图文消息条数限制在10条以内,注意,如果图文数超过10,则将会无响应。 #{ # "touser":"******", # "msgtype":"news", # "news":{ # "articles": [ # { # "title":"Happy Day", # "description":"Is Really A Happy Day", # "url":"URL", # "picurl":"PIC_URL" # }, # { # "title":"Happy Day", # "description":"Is Really A Happy Day", # "url":"URL", # "picurl":"PIC_URL" # } # ] # } #} def send_customer_news_msg(self, openid, news, customservice=None): self._check_appid_appsecret() params = { "touser": openid, "msgtype": "news", "news": { "articles": news } } if customservice is not None: params["customservice"] = {"kf_account": customservice} return self._post( url= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + self.access_token, data=params) def download_media(self, media_id): """ 下载多媒体文件 详情请参考 http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html :param media_id: 媒体文件 ID :return: requests 的 Response 实例 """ self._check_appid_appsecret() with closing( requests.get( 'http://file.api.weixin.qq.com/cgi-bin/media/get', params={ 'access_token': self.access_token, 'media_id': media_id, }, stream=True, )) as r: ret = r.content return ret def download_media2file(self, media_id, file_name): content = self.download_media(media_id) WriteFileData = open(file_name, 'wb') WriteFileData.write(content) WriteFileData.close() return def create_group(self, name): """ 创建分组 详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html :param name: 分组名字(30个字符以内) :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/groups/create', data={ 'group': { 'name': name, }, }) def get_groups(self): """ 查询所有分组 详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get('https://api.weixin.qq.com/cgi-bin/groups/get') def get_group_by_id(self, openid): """ 查询用户所在分组 详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html :param openid: 用户的OpenID :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post(url='https://api.weixin.qq.com/cgi-bin/groups/getid', data={ 'openid': openid, }) def update_group(self, group_id, name): """ 修改分组名 详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html :param group_id: 分组id,由微信分配 :param name: 分组名字(30个字符以内) :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/groups/update', data={'group': { 'id': int(group_id), 'name': name, }}) def move_user(self, user_id, group_id): """ 移动用户分组 详情请参考 http://mp.weixin.qq.com/wiki/13/be5272dc4930300ba561d927aead2569.html :param user_id: 用户 ID 。 就是你收到的 WechatMessage 的 source :param group_id: 分组 ID :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/groups/members/update', data={ 'openid': user_id, 'to_groupid': group_id, }) #内部数据库中获取用户信息 def get_user_info2(self, openid, format="orign"): _ret = self.owner_db.query( "SELECT * FROM Customer WHERE openid = '{0}'".format(openid)) if len(_ret) > 0: user = _ret[0] if (user.upload_time is None) or ( (datetime.datetime.now() - user.upload_time).total_seconds() > 10 * 24 * 60 * 60): #大于10天,重新刷新一下用户信息 user = self.update_user_info(openid) else: user = self.update_user_info(openid) ret = {} for key in user: if format == "orign": ret[key] = user[key] else: ret[key] = user[key].strftime( "%Y-%m-%d %H:%M:%S") if isinstance( user[key], datetime.datetime) else user[key] return ret def get_user_info(self, user_id, lang='zh_CN'): """ 获取用户基本信息 详情请参考 http://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param lang: 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._get(url='https://api.weixin.qq.com/cgi-bin/user/info', params={ 'access_token': self.access_token, 'openid': user_id, 'lang': lang, }) def update_user_info(self, openid): user = self.get_user_info(openid) _ret = self.owner_db.query( "SELECT * FROM Customer WHERE openid='{0}'".format(openid)) if user.has_key("subscribe_time"): #关注或者已经关注 if len(_ret) == 0: self.owner_db.insert( "Customer", openid=openid, unionid=user['unionid'], subscribe_at=datetime.datetime.fromtimestamp( user["subscribe_time"]).strftime("%Y-%m-%d %H:%M:%S"), nickname=user['nickname'], city=user['city'], province=user['province'], country=user['country'], headimgurl=user['headimgurl'], groupid=user['groupid'], upload_time=datetime.datetime.now(), ) else: self.owner_db.update( "Customer", where='openid=$openid', vars=locals(), unionid=user['unionid'], subscribe_at=datetime.datetime.fromtimestamp( user["subscribe_time"]).strftime("%Y-%m-%d %H:%M:%S"), weixinname=self.weixinName, nickname=user['nickname'], city=user['city'], province=user['province'], country=user['country'], headimgurl=user['headimgurl'], groupid=user['groupid'], upload_time=datetime.datetime.now(), ) elif len(_ret) > 0: #是不关注事件 self.owner_db.update("Customer", where='openid=$openid', vars=locals(), unsubscribe_at=datetime.datetime.now()) _ret = self.owner_db.query( "SELECT * FROM Customer WHERE openid = '{0}' ".format(openid)) ret = None if len(_ret) == 0 else _ret[0] return ret def get_followers(self, first_user_id=None): """ 获取关注者列表 详情请参考 http://mp.weixin.qq.com/wiki/3/17e6919a39c1c53555185907acf70093.html :param first_user_id: 可选。第一个拉取的OPENID,不填默认从头开始拉取 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() params = { 'access_token': self.access_token, } if first_user_id: params['next_openid'] = first_user_id return self._get('https://api.weixin.qq.com/cgi-bin/user/get', params=params) def send_text_message(self, user_id, content): """ 发送文本消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param content: 消息正文 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'text', 'text': { 'content': content, }, }) def send_image_message(self, user_id, media_id): """ 发送图片消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param media_id: 图片的媒体ID。 可以通过 :func:`upload_media` 上传。 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'image', 'image': { 'media_id': media_id, }, }) def send_voice_message(self, user_id, media_id): """ 发送语音消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param media_id: 发送的语音的媒体ID。 可以通过 :func:`upload_media` 上传。 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'voice', 'voice': { 'media_id': media_id, }, }) def send_video_message(self, user_id, media_id, title=None, description=None): """ 发送视频消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param media_id: 发送的视频的媒体ID。 可以通过 :func:`upload_media` 上传。 :param title: 视频消息的标题 :param description: 视频消息的描述 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() video_data = { 'media_id': media_id, } if title: video_data['title'] = title if description: video_data['description'] = description return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'video', 'video': video_data, }) def send_music_message(self, user_id, url, hq_url, thumb_media_id, title=None, description=None): """ 发送音乐消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param url: 音乐链接 :param hq_url: 高品质音乐链接,wifi环境优先使用该链接播放音乐 :param thumb_media_id: 缩略图的媒体ID。 可以通过 :func:`upload_media` 上传。 :param title: 音乐标题 :param description: 音乐描述 :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() music_data = { 'musicurl': url, 'hqmusicurl': hq_url, 'thumb_media_id': thumb_media_id, } if title: music_data['title'] = title if description: music_data['description'] = description return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'music', 'music': music_data, }) def send_article_message(self, user_id, articles): """ 发送图文消息 详情请参考 http://mp.weixin.qq.com/wiki/7/12a5a320ae96fecdf0e15cb06123de9f.html :param user_id: 用户 ID, 就是你收到的 WechatMessage 的 source :param articles: list 对象, 每个元素为一个 dict 对象, key 包含 `title`, `description`, `picurl`, `url` :return: 返回的 JSON 数据包 """ self._check_appid_appsecret() articles_data = [] for article in articles: article = Article(**article) articles_data.append({ 'title': article.title, 'description': article.description, 'url': article.url, 'picurl': article.picurl, }) return self._post( url='https://api.weixin.qq.com/cgi-bin/message/custom/send', data={ 'touser': user_id, 'msgtype': 'news', 'news': { 'articles': articles_data, }, }) def _genQRCode(self, info, file_name): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(info) qr.make(fit=True) img = qr.make_image() img.save(file_name, 'JPEG') return #创建二维码,并保存到文件 def create_temp_qrcode2(self, scene_id, file_name, expire_seconds=604800): ret = self.create_temp_qrcode(scene_id, expire_seconds) self._genQRCode(ret["url"], file_name) def create_temp_qrcode(self, scene_id, expire_seconds=604800): """ 创建二维码 详情请参考 http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html :param data: 你要发送的参数 dict :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() data = { "access_token": self.access_token, "expire_seconds": expire_seconds, "action_name": "QR_SCENE", "action_info": { "scene": { "scene_id": scene_id } } } return self._post( url='https://api.weixin.qq.com/cgi-bin/qrcode/create', data=data) #创建二维码,并保存到文件 def create_perm_qrcode2(self, scene_str, qrcode_url, file_name): ret = self.create_perm_qrcode(scene_str) orgUrl = ret["url"] #创建二维码 self._genQRCode(orgUrl, file_name) #是永久二维码,还需要计入数据库,进行备案 db.update("WeixinQRcodeScene", where="qrcode_url=$qrcode_url", url=orgUrl, vars=locals()) def create_perm_qrcode(self, scene_str): """ 创建二维码 详情请参考 http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html :param data: 你要发送的参数 dict :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() data = {"access_token": self.access_token} if (type(scene_str) is str): #字符串类型scene_id data["action_name"] = "QR_LIMIT_STR_SCENE" data["action_info"] = {"scene": {"scene_str": scene_str}} else: #整数类型scene_id data["action_name"] = "QR_LIMIT_SCENE" data["action_info"] = {"scene": {"scene_id": scene_str}} return self._post( url='https://api.weixin.qq.com/cgi-bin/qrcode/create', data=data) def create_qrcode(self, **data): """ 创建二维码 详情请参考 http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html :param data: 你要发送的参数 dict :return: 返回的 JSON 数据包 :raise HTTPError: 微信api http 请求失败 """ self._check_appid_appsecret() return self._post( url='https://api.weixin.qq.com/cgi-bin/qrcode/create', data=data) def show_qrcode(self, ticket): """ 通过ticket换取二维码 详情请参考 http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html :param ticket: 二维码 ticket 。可以通过 :func:`create_qrcode` 获取到 :return: 返回的 Request 对象 """ self._check_appid_appsecret() return requests.get(url='https://mp.weixin.qq.com/cgi-bin/showqrcode', params={'ticket': ticket}) def markOuttimeWeixinPara(self): for key in ['access_token', 'jsapi_ticket']: #检查access_token 是否过期 _ret = db.query( "SELECT * FROM GlobalPara WHERE name='{0}'".format(key)) for token in _ret: now = time.time() if token.expired_at - now < 300: db.query("DELETE FROM GlobalPara WHERE id = {0}".format( token.id)) def get_jdk_sign(self, url): #处理url中#字符情况 temp = url.split("#")[0] ret = { 'nonceStr': self.__create_nonce_str(), 'jsapi_ticket': self.jsapi_ticket, 'timestamp': self.__create_timestamp(), 'url': temp } string = '&'.join( ['%s=%s' % (key.lower(), ret[key]) for key in sorted(ret)]) ret['signature'] = hashlib.sha1(string).hexdigest() ret['appid'] = self.__appid ret['url'] = url return ret def get_pay_sign(self, prepay_id): ret = { 'appId': self.__appid, 'timestamp': self.__create_timestamp(), 'nonceStr': self.__create_nonce_str(), 'package': 'prepay_id={0}'.format(prepay_id), 'signType': 'MD5', } string = '&'.join( ['%s=%s' % (key.lower(), ret[key]) for key in sorted(ret)]) ret['paySign'] = hashlib.sha1(string).hexdigest().upper() if test: ret['string'] = string return ret @property def access_token(self): self._check_appid_appsecret() #来自上次查询的token _ret = db.query( "SELECT * FROM GlobalPara WHERE owner='{0}' AND name='access_token' ORDER BY create_at DESC LIMIT 0,3" .format(self.__weixinname)) if len(_ret) >= 1: self.__access_token = _ret[0].value.encode('utf-8') return self.__access_token #if self.__access_token: # now = time.time() # if self.__access_token_expires_at - now > 60: # return self.__access_token response_json = self.grant_token() self.__access_token = response_json['access_token'] #self.__access_token_expires_at = int(time.time()) + response_json['expires_in'] - 60*60 self.__access_token_expires_at = int(time.time()) + 20 * 60 db.insert("GlobalPara", name='access_token', owner=self.__weixinname, value=self.__access_token, create_at=datetime.datetime.now(), expired_at=self.__access_token_expires_at) return self.__access_token @property def jsapi_ticket(self): self._check_appid_appsecret() #如果数据库中有数据,则认为有效 _ret = db.query( "SELECT * FROM GlobalPara WHERE owner='{0}' AND name='jsapi_ticket' ORDER BY create_at DESC LIMIT 0,3" .format(self.__weixinname)) if len(_ret) >= 1: self.__jsapi_ticket = _ret[0].value.encode('utf-8') return self.__jsapi_ticket #if self.__jsapi_ticket: # now = time.time() # if self.__jsapi_ticket_expires_at - now > 60: # return self.__jsapi_ticket response_json = self.grant_jsapi_ticket() self.__jsapi_ticket = response_json['ticket'].encode("utf-8") self.__jsapi_ticket_expires_at = int( time.time()) + response_json['expires_in'] - 300 #将新生成的ticket值入库 db.insert("GlobalPara", name='jsapi_ticket', owner=self.__weixinname, value=self.__jsapi_ticket, create_at=datetime.datetime.now(), expired_at=self.__jsapi_ticket_expires_at) return self.__jsapi_ticket def _check_token(self): """ 检查 Token 是否存在 :raises NeedParamError: Token 参数没有在初始化的时候提供 """ if not self.__token: raise NeedParamError( 'Please provide Token parameter in the construction of class.') def _check_appid_appsecret(self): """ 检查 AppID 和 AppSecret 是否存在 :raises NeedParamError: AppID 或 AppSecret 参数没有在初始化的时候完整提供 """ if not self.__appid or not self.__appsecret: raise NeedParamError( 'Please provide app_id and app_secret parameters in the construction of class.' ) def _check_parse(self): """ 检查是否成功解析微信服务器传来的数据 :raises NeedParseError: 需要解析微信服务器传来的数据 """ if not self.__is_parse: raise NeedParseError() def _check_official_error(self, json_data, times=0): """ 检测微信公众平台返回值中是否包含错误的返回码 :raises OfficialAPIError: 如果返回码提示有错误,抛出异常;否则返回 True """ if "errcode" in json_data and json_data["errcode"] != 0: #删除过期access_token,jsapi_ticket值 db.query( "DELETE FROM GlobalPara WHERE owner='{0}' AND (name='jsapi_ticket' OR name='access_token')" .format(self.__weixinname)) raise OfficialAPIError("{}: {}".format(json_data["errcode"], json_data["errmsg"])) def _request(self, method, url, **kwargs): """ 向微信服务器发送请求 :param method: 请求方法 :param url: 请求地址 :param kwargs: 附加数据 :return: 微信服务器响应的 json 数据 :raise HTTPError: 微信api http 请求失败 """ if "params" not in kwargs: kwargs["params"] = { "access_token": self.access_token, } if isinstance(kwargs.get("data", ""), dict): body = json.dumps(kwargs["data"], ensure_ascii=False) body = body.encode('utf8') kwargs["data"] = body r = requests.request(method=method, url=url, **kwargs) r.raise_for_status() response_json = r.json() self._check_official_error(response_json) return response_json def _get(self, url, **kwargs): """ 使用 GET 方法向微信服务器发出请求 :param url: 请求地址 :param kwargs: 附加数据 :return: 微信服务器响应的 json 数据 :raise HTTPError: 微信api http 请求失败 """ return self._request(method="get", url=url, **kwargs) def _post(self, url, **kwargs): """ 使用 POST 方法向微信服务器发出请求 :param url: 请求地址 :param kwargs: 附加数据 :return: 微信服务器响应的 json 数据 :raise HTTPError: 微信api http 请求失败 """ return self._request(method="post", url=url, **kwargs) def _transcoding(self, data): """ 编码转换 :param data: 需要转换的数据 :return: 转换好的数据 """ if not data: return data result = None if type(data) == unicode: result = data elif type(data) == str: result = data.decode('utf-8') else: raise ParseError() return result def __create_nonce_str(self): nonce_str = ''.join( random.choice(string.ascii_letters + string.digits) for _ in range(15)) return nonce_str def __create_timestamp(self): stamp = int(time.time()) return stamp
def getUrl(url): WechatUser.api = WeixinAPI(appid=WechatUser.APP_ID, app_secret=WechatUser.APP_SECRET, redirect_uri=url) return WechatUser.api.get_authorize_url(scope=WechatUser.scope)
def getUserInfo(code): auth_info = WechatUser.api.exchange_code_for_access_token(code=code) data = WeixinAPI(access_token=auth_info['access_token']) return data.user(openid=auth_info['openid'])
try: import __builtin__ input = getattr(__builtin__, 'raw_input') except (ImportError, AttributeError): pass appid = input("App ID: ").strip() app_secret = input("App Secret: ").strip() redirect_uri = input("Redirect URI: ").strip() raw_scope = input("Requested scope (separated by spaces, blank for just basic read): ").strip() scope = raw_scope.split(' ') # For basic, API seems to need to be set explicitly if not scope or scope == [""]: scope = ["snsapi_login"] api = WeixinAPI(appid=appid, app_secret=app_secret, redirect_uri=redirect_uri) redirect_uri = api.get_authorize_login_url(scope=scope) print ("Visit this page and authorize access in your browser: "+ redirect_uri) code = (str(input("Paste in code in query string after redirect: ").strip())) access_token = api.exchange_code_for_access_token(code) print ("access token: " ) print (access_token)
# -*- coding: utf-8 -*- from weixin.client import WeixinAPI from weixin.oauth2 import OAuth2AuthExchangeError APP_ID = 'your app id' APP_SECRET = 'your secret' REDIRECT_URI = 'http://www.exmple.com' code = '0418f2c46cd26e4f9eee5bf03320662M' api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) try: pass # print api.get_authorize_login_url(scope=("snsapi_login",)) # print api.exchange_code_for_access_token(code=code) except OAuth2AuthExchangeError, e: print e auth_info = { 'access_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw-NdEN9dPkEX8Yewsve2AktmzS0gmbvzRKO49l6sxHRfhXg1no5ObdGufYhRIubP2m3FUdv-Cop3t3S_xwMbBWQ', 'refresh_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw44bjXRXdmPsclqGIjWs777H3p00QI9a3hzX265Uq9fPJZttNQApdCRPbySXDfofbjniiwsVJiT7fTv7j5jCAxg', 'openid': u'oV02tuA8Wt6Kk7S0pVydThYvmSJA', 'expires_in': 7200, 'scope': u'snsapi_login'}
# -*- coding: utf-8 -*- from weixin.client import WeixinAPI from weixin.oauth2 import OAuth2AuthExchangeError APP_ID = 'wxbdc5610cc59c1631' APP_SECRET = 'your app secret' REDIRECT_URI = 'https://passport.yhd.com/wechat/callback.do' code = '021b66a31b7179822b01e7e2c12528cV' api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) try: print(api.get_authorize_login_url(scope=("snsapi_login", ))) print(api.exchange_code_for_access_token(code=code)) except OAuth2AuthExchangeError as e: print(e) auth_info = { 'access_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw-NdEN9dPkEX8Yewsve2AktmzS0gmbvzRKO49l6sxHRfhXg1no5ObdGufYhRIubP2m3FUdv-Cop3t3S_xwMbBWQ', 'refresh_token': 'OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw44bjXRXdmPsclqGIjWs777H3p00QI9a3hzX265Uq9fPJZttNQApdCRPbySXDfofbjniiwsVJiT7fTv7j5jCAxg', 'openid': u'oV02tuA8Wt6Kk7S0pVydThYvmSJA', 'expires_in': 7200, 'scope': u'snsapi_login' } print( api.exchange_refresh_token_for_access_token(
# -*- coding: utf-8 -*- from weixin.client import WeixinAPI from weixin.oauth2 import OAuth2AuthExchangeError APP_ID = "wxbdc5610cc59c1631" APP_SECRET = "your app secret" REDIRECT_URI = "https://passport.yhd.com/wechat/callback.do" code = "021b66a31b7179822b01e7e2c12528cV" api = WeixinAPI(appid=APP_ID, app_secret=APP_SECRET, redirect_uri=REDIRECT_URI) try: print api.get_authorize_login_url(scope=("snsapi_login",)) print api.exchange_code_for_access_token(code=code) except OAuth2AuthExchangeError, e: print e auth_info = { "access_token": "OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw-NdEN9dPkEX8Yewsve2AktmzS0gmbvzRKO49l6sxHRfhXg1no5ObdGufYhRIubP2m3FUdv-Cop3t3S_xwMbBWQ", "refresh_token": "OezXcEiiBSKSxW0eoylIeGXVgVFIUy2pK5I7TVatC5MGtVqTIWjtyV5Pax8ZLiWw44bjXRXdmPsclqGIjWs777H3p00QI9a3hzX265Uq9fPJZttNQApdCRPbySXDfofbjniiwsVJiT7fTv7j5jCAxg", "openid": u"oV02tuA8Wt6Kk7S0pVydThYvmSJA", "expires_in": 7200, "scope": u"snsapi_login", } print api.exchange_refresh_token_for_access_token(refresh_token=auth_info["refresh_token"])
def __init__(self, token=None, appid=None, appsecret=None, partnerid=None, partnerkey=None, paysignkey=None, access_token=None, access_token_expires_at=None, jsapi_ticket=None, jsapi_ticket_expires_at=None, weixinname=None, firsteye=None, menuMap=None, owner_db=None, open_appid=None, open_secrept=None, open_redirect_uri=None): """ :param token: 微信 Token :param appid: App ID :param appsecret: App Secret :param partnerid: 财付通商户身份标识, 支付权限专用 :param partnerkey: 财付通商户权限密钥 Key, 支付权限专用 :param paysignkey: 商户签名密钥 Key, 支付权限专用 :param access_token: 直接导入的 access_token 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param access_token_expires_at: 直接导入的 access_token 的过期日期,该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param jsapi_ticket: 直接导入的 jsapi_ticket 值, 该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 :param jsapi_ticket_expires_at: 直接导入的 jsapi_ticket 的过期日期,该值需要在上一次该类实例化之后手动进行缓存并在此处传入, 如果不传入, 将会在需要时自动重新获取 """ self.__token = token self.__token = token self.__appid = appid self.__appsecret = appsecret self.__partnerid = partnerid self.__partnerkey = partnerkey self.__paysignkey = paysignkey self.__access_token = access_token self.__access_token_expires_at = access_token_expires_at self.__jsapi_ticket = jsapi_ticket self.__jsapi_ticket_expires_at = jsapi_ticket_expires_at self.__is_parse = False self.__message = None self.__weixinname = weixinname self.owner_db = owner_db #实例属性 self.token = token self.appid = appid self.open_appid = open_appid self.open_secrept = open_secrept self.appsecret = appsecret self.partnerid = partnerid self.partnerkey = partnerkey self.paysignkey = paysignkey self.firsteye = firsteye self.menuMap = menuMap self.weixinName = weixinname self.open_redirect_uri = open_redirect_uri self.openapi = WeixinAPI(appid=self.open_appid, app_secret=self.open_secrept, redirect_uri=self.open_redirect_uri)