我们在上一篇 Salesforce Force.com Site 集成微信公众平台 (一) 后台配置 给大家介绍了如何通过 Salesforce 中的 Force.com Site 来连接微信公众平台。这次我们来介绍 Salesforce 怎样接收从微信公众平台发送过来的文本消息,同时做一个简单的自动回复。
首先我们来介绍一下信息的发送流程。当用户向微信发送信息时,微信公众平台服务器接收到消息后,检查当前公众帐号是否开启了开发者模式。如果开发者模式打开了,微信服务器会以 POST 的方式将 XML 数据包发送到我们在微信后台配置的 URL 上,也就是 Salesforce 系统中,这样我们就可以在 Apex 代码中处理这些消息了。
微信的消息类型有文本信息、图片信息、语音信息、视频信息、地理位置信息和链接信息,下面介绍如果处理最基本的文本消息。
文本消息的XML数据包
<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>
数据包结构说明
Apex 中处理文本消息
分析了上面的数据结果后,在 WeChatRestController
类中添加 doPost
方法来处理微信的请求。
@HttpPost
global static void doPost()
{
// 存储XML各节点数据变量
String toUserName = '';
String fromUserName = '';
String msgType = '';
String content = '';
// 获取XML数据包
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
string strMsg = req.requestBody.toString();
XmlStreamReader reader = new XmlStreamReader(strMsg);
// 解析XML数据包,Force.com这块的处理能力并不强,简单的结构也需要较多代码来解析
while(reader.hasNext())
{
if(parseXML(reader, 'ToUserName') != null)
{
toUserName = parseXML(reader, 'ToUserName');
}
else if(parseXML(reader, 'FromUserName') != null)
{
fromUserName = parseXML(reader, 'FromUserName');
}
else if(parseXML(reader, 'MsgType') != null)
{
msgType = parseXML(reader, 'MsgType');
}
else if(parseXML(reader, 'Content') != null)
{
content = parseXML(reader, 'Content');
System.debug('@@@' + reader.getText());
}
reader.next();
}
}
private static String parseXML(XmlStreamReader reader, String node)
{
if(reader.getLocalName() == node)
{
reader.next();
if(String.isNotBlank(reader.getText()))
{
return reader.getText();
}
}
return null;
}
查看测试结果
为了更容易看到结果,我在上面的代码中加入了 System.debug
方法。打开 Debug Logs
(Setup->Monitor->Logs->Debug Logs) 页面,添加一个要跟踪的 User, 需要找到上一篇中创建 Site 对应的 Guest User,并设置跟踪时间。如下图所示:
在微信客户端输入了 “你是在发信息到Salesforce吗?” 测试消息内容。发送完成后,在 Salesfore 的打开 Debug log, 在 Log 中我们可以看到从微信端发过来的消息,说明接收成功。Debug Log 如下图所示:
自动回复信息
当我们成功接收消息后,就可以针对消息做相应的逻辑处理了,这里我们做一个简单的自动回复。
回复的数据也是XML结构,和发送过来的文本消息基本一致。添加了一个新的方法,代码如下:
private static void replyMsg(RestResponse res, String fromUserName, String toUserName, String rtnMsg)
{
Datetime dt = System.now();
String returnDT = dt.format('EEEE, MMMM d, yyyy');
String replyMSG = '<xml>' +
'<ToUserName><![CDATA[{0}]]></ToUserName>' +
'<FromUserName><![CDATA[{1}]]></FromUserName>' +
'<CreateTime>' + returnDT + '</CreateTime>' +
'<MsgType><![CDATA[text]]></MsgType>' +
'<Content><![CDATA[{2}]]></Content>' +
'</xml>';
String[] arguments = new String[]{fromUserName, toUserName, rtnMsg};
String formattedReplyMSG = String.format(replyMSG, arguments);
res.addHeader('Content-Type', 'text/plain');
res.responseBody = Blob.valueOf(formattedReplyMSG);
}
之后添加 replyMsg(res, fromUserName, toUserName, 'Yes')
这行代码到我们的 doPost
方法中。
else if(parseXML(reader, 'Content') != null)
{
content = parseXML(reader, 'Content');
System.debug('@@@' + content);
// 自动回复 Yes 给微信用户
replyMsg(res, fromUserName, toUserName, 'Yes');
}
当再次在微信客户端发送 “你是在发信息到Salesforce吗?” 的时候,系统将自动回复"Yes"。如下图如示:
到此文本消息已经讲完了,后续我们将继续推出其它类型的信息处理。希望大家继续关注。