自定义服务端接收微信消息

如上图所示,微信公众号自带一些自动回复的功能,但是很弱,通常我们需要接收用户发给公众号的消息,并做一些个性化的相应。

1、配置部分

打开“开发”》“基本配置”


image.png

找到服务器配置,点修改配置


image.png

设置一个接收微信请求的url,这个是我们提前开发好的一个服务,等下说这个服务需要做什么。token随便填一个。key随机生成。然后提交,就绑定成功了。


image.png

2、代码部分

服务怎么开发呢?微信有说明,在这里
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
我这里简述一下:
点击提交的时候,微信会发送几个参数给你:

timestamp=1540176606
echostr=3892692869596528638
nonce=1854606751
signature=6a62fc79ddf83b3ff96e5cbd068b983f88f192ba

你需要校验一下,如果这个请求是微信来的(而不是某个黑客假冒的),就给微信返回他发过来的echostr。

校验规则是这样的的:1)将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

当然如果你只是个人demo,懒得校验可以无脑直接返回echostr就行了

python-flask示例代码(不校验的):

@app.route('/msg',methods=['GET'])
def msg():
    return request.args['echostr']

python-flask示例代码(带校验的):

@app.route('/msg',methods=['GET'])
def msg():
    #获取参数
    timestamp = request.args['timestamp']
    nonce = request.args['nonce']
    signature = request.args['signature']
    echostr = request.args['echostr']
    token = 'weixin'

    #排序
    sortedlist = sorted((timestamp,nonce,token))
    #连接字符串
    s = ''.join(sortedlist)
    #sha1加密
    s1 = hashlib.sha1(s.encode('utf8')).hexdigest()
    if(s1==signature):
        return echostr
    else:
        return "error"

上面的校验可以有效防止别人非法调用你的接口,所以提供给微信调用的所有接口,大家也都务必要加上验证。

3、最后有个跟本文无关的彩蛋

微信调用接口只能在服务器端,无法调用局域网地址,为了方便调试可以加一个log,把微信传的params、headers都记录到log里面:


def logRequest():
    with codecs.open("wechat.log",'w','utf-8') as f:
        for obj in request.args:
            f.write("%s=%s"%(obj, request.args[obj]))
            f.write("\r\n")
        f.write("\r\n")
        f.write("\r\n")
        for obj in request.headers:
            f.writelines("%s=%s"%(obj[0], obj[1]))
            f.write("\r\n")