Back to Top

技术博客

有关语言云的更新、应用以及其他

使用语言云API开发微信公众平台相关应用

2014-03-21 by gcniu


微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,可以群发文字、图片、语音、视频、图文消息五个类别的内容。目前微信公众平台支持PC,移动互联网网页登录,并可以绑定私人帐号进行群发信息。 微信公众平台是一个自媒体平台,它提供出色的消息推送与交互的方式。本文将介绍如何使用语言云API开发微信公众平台相关应用。

使用语言云API开发微信公众平台APP需要具备以下三种条件:

  • 语言云API_KEY:开发者需要先持有语言云服务的API_KEY,注册方式:http://www.ltp-cloud.com/accounts/register/
  • 微信公众平台帐号:开发者需要首先是微信用户,并且需要申请一个微信公众平台帐号,申请地址:https://mp.weixin.qq.com/。为了演示方便,本文使用的是微信公众平台开发者测试帐号,读者也可以申请测试帐号用于开发调试使用,申请地址: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login。 在开发者申请测试号成功后,可以管理测试号的相关信息,如下图所示:
  • 服务器:开发者需要有一台能够接入互联网的服务器,这个条件是必要的。读者应该注意到在申请微信公众帐号测试号的时候需要填写接口配置信息并验证,其中的URL即是依赖于开发者自己的服务器的(Token可以随意填写,用签名验证)。在本文中,使用了新浪公有云计算平台SAE,读者也可以申请,申请地址为:http://sae.sina.com.cn/ 。本文在SAE上部署了Django Web框架,使用Python语言来演示此应用。有关在SAE部署Python应用请参考:http://sae.sina.com.cn/doc/python/tutorial.html。开发者当然可以使用其他语言开发,但本文不提供其他语言的开发代码实例,聪明的读者可以自己完成。本文的代码示例完全基于Python语言和Django Web框架。有关Django,读者可以参考文档:https://docs.djangoproject.com/

本文使用一张活动图来具体描述使用语言云API开发微信公众平台APP的开发方法。

如上图所示,开发者首先需要成为申请成为微信公众平台开发者,并持有语言云API_KEY。开发微信公众帐号APP需要分为两个阶段:验证配置信息阶段和消息处理阶段,分别需要在服务器上开发配置消息验证模块和微信消息处理模块。

开发者如果想成功获取微信用户发送的消息并返回响应给微信用户需要首先得到微信服务器对于开发者服务器资源的验证。因而,开发者在申请微信公众平台开发者帐号的时候填写的URL和Token就显的特别重要。

假设填写的URL为:http://weixintest.sinaapp.com ;填写的Token为:helloworld。

开发者提交信息后,微信服务器将发送GET请求到填写的URL(URL对应开发者自己的服务器)上,并且带上四个参数:

参数 描述
signature 微信加密签名
timestamp 时间戳
nonce 随机数
echostr 随机字符串
开发者需要通过检验signature对请求进行校验。若确认此GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。

signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。校验流程为:

  • 将token、timestamp、nonce三个参数进行字典序排序
  • 将三个参数字符串拼接成一个字符串进行sha1加密
  • 开发者获得加密后的字符串与signature对比,标识该请求来源于微信

在Django中,我们在views.py中建立名为check_signature的视图函数来验证签名:

#views.py
def check_signature(request):
    token = "helloworld"
    signature = request.GET.get("signature")
    timestamp = request.GET.get("timestamp")
    nonce = request.GET.get("nonce")
    echostr = request.GET.get("echostr")
    signature_tmp = [token,timestamp,nonce]
    #lexicographical sorting
    signature_tmp.sort()
    #string concatenation
    signature_tmp = ''.join(signature_tmp)
    #sha1 encryption
    signature_tmp = hashlib.sha1(signature_tmp).hexdigest()
    #compare with signature
    if signature_tmp == signature:
        return echostr

由于微信平台会发送GET请求到填写的URL上对请求进行校验,因而需要在urls.py中配置url以及处理此url的视图函数:

#urls.py  
…  
urlpatterns = patterns('',  
    url(r'^$',handle_request),  
)

在views.py中编写名为handle_request的主视图函数:

#views.py  
def handle_request(request):  
    if request.method == 'GET':  
        response = HttpResponse(check_signature(request),content_type="text/plain")  
        return response

在开发者自己的服务器中编写以上代码并且运行。如果开发者在微信配置url和token后,收到“配置成功“的提示,说明配置信息验证成功。

完成配置信息验证后,开发者就可以放心的开发真正和微信消息处理相关的工作了。本文只演示文本消息的相关开发任务,有关其他消息类型,请参考更为详细的开发文档:http://mp.weixin.qq.com/wiki/index.php

当普通微信用户向公众账号发消息时,微信服务器将POST该消息到填写的URL上,该消息结构如下:

<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>1348831860</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[this is a test]]></Content>
    <MsgId>1234567890123456</MsgId>
</xml>

此xml中参数及其描述如下:

参数 描述
ToUserName 开发者微信号
FromUserName 发送方帐号(一个OpenID)
CreateTime 消息创建时间 (整型)
MsgType text
Content 文本消息内容
MsgId 消息id,64位整型

对于每一个POST请求,开发者在需要在响应包中返回特定xml结构,对该消息进行响应,回复xml结构如下:

<xml>  
    <ToUserName><![CDATA[toUser]]></ToUserName>  
    <FromUserName><![CDATA[fromUser]]></FromUserName>  
    <CreateTime>12345678</CreateTime>  
    <MsgType><![CDATA[text]]></MsgType>  
    <Content><![CDATA[content]]></Content>  
    <FuncFlag>0</FuncFlag>  
</xml>

此xml中参数及其描述如下:

参数 描述
ToUserName 接收方帐号(收到的OpenID)
FromUserName 开发者微信号
CreateTime 消息创建时间 (整型)
MsgType text
Content 回复的消息内容,长度不超过2048字节
FuncFlag 位0x0001被标志时,星标刚收到的消息

因此,开发者需要在views.py中建立一个视图函数用于获取微信服务器发来的xml格式的消息,并解析该消息获取信息文本,调用语言云API对此文本进行处理,并将结果进行二次开发后返回给同一个用户。

为节省篇幅,下面在views.py中建立一个名为response_msg的视图函数,使用语言云API获取文本的词性标注结果反馈给用户:

#views.py  
...  
from django.utils.encoding import smart_str  
import xml.etree.ElementTree as ET  
...  
def response_msg(request):
    #get post message
    msg = request.raw_post_data
    #parser xml format  
    msg_xml = ET.fromstring(msg)  
    msg = {}
    for element in msg_xml:
        msg[element.tag] = smart_str(element.text)  
    content = msg.get('Content')  
    url_get_base = "http://api.ltp-cloud.com/analysis/?"  
    api_key = "YourApikey"  
    format = "plain"  
    pattern = "pos"
    #call for ltp-cloud api
    result = urllib2.urlopen(url_get_base + 'api_key='+api_key+'&text='+content+'&format='+format+'&pattern='+pattern)  
    content = result.read().strip()  
    response = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag></xml>"
    #generate xml formt response
    response = response % (msg['FromUserName'],msg['ToUserName'],str(int(time.time())),'text',content)  
    return response

我们还需要在handle_request视图函数中处理post请求,最终形成的handle_request视图函数如下:

@csrf_exempt  
def handle_request(request):  
    if request.method == 'GET':  
        response = HttpResponse(check_signature(request),content_type="text/plain")  
        return response  
    elif request.method == 'POST':
        response = HttpResponse(response_msg(request),content_type="application/xml")  
        return response

到目前为止,这个使用语言云API开发的对微信用户发来的信息做中文词性标注,并将结果发送给微信用户的简单APP就做好了。效果图如下:

开发者也可以开发的交互更为友好,譬如:
具体怎么做,留给聪明的读者。

本文只是演示了如何使用语言云API开发微信公众平台应用的基本方法,起到的是抛砖引玉的作用。期待各位语言云的用户以语言云为工具,作为开发者,开发出功能强大、具有创造力和的APP!

comments powered by Disqus