微信公众平台(公众号)与第三方服务集成

wechat oap message service

微信提供了多种机制为第三方服务提供支持,比如公众号小程序开放平台等。公众号可以通过消息、网页的方式与用户互动并提供服务,小程序让用户在微信中获得本地应用的体验,开放平台为第三方平台整合微信服务从而满足不同用户需求提供支撑。

本篇文章介绍如何把微信公众号服务(消息)同第三方的服务整合,包括服务器配置、程序开发等内容。

一、申请并配置微信公众号

按照官方文档的说明申请一个公众号(免费),然后登录到公众号后台管理界面,在设置与开发菜单中选择基本配置,然后在 URL 部分输入自己服务器微信所使用的访问地址,比如 https://www.example.xyz/weixin,微信后台会使用这个地址和服务器通信;接着输入令牌(token),仅是验证服务器使用,按照要求输入即可;然后点击“随机生成”按钮产生加密密钥;加密方式选择“明文模式”,后期可根据需要调整。完成后不要提交,因为服务代码还没有。

最后在设置与开发菜单中选择安全中心,在 IP 白名单中加入自己服务器的 IP 地址。

二、配置服务器

在服务器配置(nginx)中首先就是要配置 URL 响应机制,可按照这篇文章的步骤配置好,只把 location 部分改成 weixin(同第一步)。这样微信后台就可以访问到服务器了,所有的信息都通过这个路径发给服务器后端。

在 uWSGI 的配置文件中,把主程序文件换个名:<module>myuwsgiapp.py</module>改成<module>index.py</module>

三、服务端代码

有两个部分,即服务器有效性验证代码和用户输入信息的响应代码。

第一步的配置是为了验证自己服务器的有效性,微信后台会发验证信息到设置好的URL 所指向的服务器。首先安装一个 python 模块 wechatpy文档),

$pip3 install wechatpy

主程序代码 index.py

import sys
import web
from handle import Handle

sys.path.append('/home/user/webpy')

urls = (
    '/weixin', 'Handle',
)

app = web.application(urls, globals())

if __name__ == '__main__':
    app.run()

application = app.wsgifunc()

服务代码 handle.py,注意token要和第一步配置的相同。

from utils import check_signature
import web
from wechatpy import parse_message 
from wechatpy.replies import TextReply
from wechatpy.replies import ArticlesReply
from wechatpy import create_reply

class Handle(object):
""" 校验部分代码,微信后台通过GET方法发过来 """
    def GET(self):
        try:
            data = web.input()
            if len(data) == 0:
                return "欢迎来到客飞翱的公众号"
            echostr = data.echostr
            signature = data.signature
            timestamp = data.timestamp
            nonce = data.nonce
            token = "验证服务器配置时定义的token"
            isok = check_signature(token, signature, timestamp, nonce)

            print ("handle/GET func: timestamp, signature: ", timestamp, signature)
            if isok==1:
               return echostr
            else:
               return ""
        except Exception as Argument:
            return Argument
""" 用户输入响应代码,微信后台通过POST方法发过来 """
    def POST(self):
        try:
            data = web.data()
            print ("Handle Post webdata is ", data)
            msg = parse_message(data)
            """ 用户输入“微博”的响应代码 """
            if msg.content == '微博':
               articles = [
		{
			'title': msg.content,
			'description': '关注客飞翱的微博',
			'image': 'https://www.kflyo.com/wp-content/uploads/...',
			'url': u'https://weibo.com/kflyo',
		},
		]
               fast_reply = create_reply(articles, message=msg)
               return fast_reply.render()
            """ 用户输入其它文字的响应代码 """
            reply = ArticlesReply(message=msg, articles=[
    		{
        		'title': u'欢迎来到客飞翱的公众号',
		        'description': u'旅行游记,信息技术,游戏攻略分享。',
		        'url': u'https://www.kflyo.com',
		        'image': u'https://www.kflyo.com/wp-content/uploads/...',
		},
		{
		        'title': u'博客网站',
		        'description': u'技术经验、技巧分享',
		        'url': u'https://www.kflyo.com',
		        'image': u'https://www.kflyo.com/wp-content/uploads/...',
		},
            ])

            reply.add_article({
		'title': u'微博',
		'description': u'旅行感悟',
		'url': u'https://weibo.com/kflyo',
            })
            return reply.render()
        except Exception as Argument:
            return Argument

服务器校验代码 utils.py

import hashlib
class WeChatSigner:

    def __init__(self, delimiter=b""):
        self._data = []
        self._delimiter = to_binary(delimiter)

    def add_data(self, *args):
        """Add data to signer"""
        for data in args:
            self._data.append(to_binary(data))

    @property
    def signature(self):
        """Get data signature"""
        self._data.sort()
        str_to_sign = self._delimiter.join(self._data)
        return hashlib.sha1(str_to_sign).hexdigest()


def check_signature(token, signature, timestamp, nonce):
    signer = WeChatSigner()
    signer.add_data(token, timestamp, nonce)
    if signer.signature != signature:
        return 0

    else:
    	return 1
def to_binary(value, encoding="utf-8"):
    if not value:
        return b""
    if isinstance(value, bytes):
        return value
    if isinstance(value, str):
        return value.encode(encoding)
    return to_text(value).encode(encoding)

四、启动服务,微信提交服务器校验请求

按照这篇文章的步骤启动后台相关服务,然后在公众号后台管理界面提交第一步配置的信息,提示验证成功后,启用服务器配置

启用后,打开微信关注新建的公众号,输入“微博”并回车,会看到服务器返回微博相关的消息,输入其它内容回车,会返回其它相关消息。

需要注意一下,微信官方给出的示例代码在 python3 下运行有问题。

五、关于调用微信应用接口的说明

以上消息相关的服务不涉及调用微信应用接口的情况,如需访问微信应用接口,首先需要公众号(认证)有权限,然后需要配置 AccessToken 服务,就是当调用微信后台应用接口的时候需要访问令牌,这个令牌可以动态从微信后台获取,有2个小时的有效期,因此需要配置一个统一的令牌管理服务,给需要调用微信后台应用接口的代码使用。这个令牌管理服务可以使用Redis,安装配置方法可以参考这篇文章

获取令牌的方法参照官方文档,保存、提取令牌的方法参考这里。在后续的文章中会介绍如何调用微信应用接口实现一些客户化的功能。

发表评论

邮箱地址不会被公开。 必填项已用*标注