微信公众号最佳实践 ( 8.8)智能聊天机器人
程序员文章站
2022-06-04 09:58:18
...
智能聊天机器人
小i机器人,是上海至臻网络科技有限公司开发的智能机器人产品,是全球用户量最大的中文聊天机器人。该机器人,能查询新闻、地图、餐饮、机票等各类生活资讯。
iBotCloud
iBotCloud全称为”小i机器人智能云服务平台”,是”小i机器人“在开放自身的核心能力的基础上,为广大开发者、合作伙伴和企业提供的一系列基于云计算和大数据平台的在线服务和开发接口。
开发者可以利用uBotCloud提供的在线服务,定义机器人属性,编辑机器人的智能回答,打造属于您的智能交互机器人。此外,iBotCloud支持多种渠道(微信接入,网站接入)的快速接入。
iBotCloud的官方网址如下:http://cloud.xiaoi.com/
用户通过注册即可获得”初级测试权限“,获得智能回答,自定义知识模块的基础测试权限,
同时,iBotCloud会为开发者提供API接口(Key 和 Secret),开发者可以通过访问API接口与iBotCloud进行快速对接,从而为自己的应用程序增加丰富的智能语音交互体验。
iBotCloud智能问答接口地址如下:http://nlp.xiaoi.com/robot/ask.do
开发实现
微信公众号在收到文本消息之后,即调用小i机器人来自动回复,需要将用户id及用户的内容都传递给机器人。相关代码如下:
private function receiveText($object)
{
$keyword = trim($object->Content);
include("xiaoi.php");
$content = getXiaoiInfo($object->FromUserName, $keyword);
$result = $this->transmitText($object, $content);
return $result;
}
小i机器人的逻辑实现比较复杂,其智能问答的实现代码如下:
xiaoi.php整体代码如下
<?php
//var_dump(getXiaoiInfo("asdf", "你是谁?"));
function getXiaoiInfo($openid, $content)
{
//定义api接口,即申请到的接口
$app_key="0266e*****";
$app_secret="Je5VbXA*******";
//签名算法的实现,小i机器人API需要通过签名来访问,签名的过程是将APP的key和secret以及随机数等参数
//根据一定签名算法生成的签名值作为新的请求头中的一部分,以此来提高访问过程中的防篡改性。
$realm = "xiaoi.com";
$method = "POST";
$uri = "/robot/ask.do";
$nonce = "";
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
for ($i = 0; $i < 40; $i++) {
$nonce .= $chars[ mt_rand(0, strlen($chars) - 1) ];
}
//签名算法如下:
//sha1加密(app_key:realm:app_secret)其中realm为xiaoi.com
$HA1 = sha1($app_key.":".$realm.":".$app_secret);
//sha1加密(method:um)其中method为请求方法,如POST,uri为"/robot/ask.do"
$HA2 = sha1($method.":".$uri);
//sha1加密(HA1:nonce:HA2)其中HA1为步骤1的值,HA2为步骤2的值,nonce为40位随机数
$sign = sha1($HA1.":".$nonce.":".$HA2);
//接口调用,使用cURL获取调用智能问答的结果
$url = "http://nlp.xiaoi.com/robot/ask.do";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//小i机器人API的有效访问都必须包含签名请求头,signature为签名算法步骤3的值,最后为该字符串添加请求头:“X-Auth”
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Auth: app_key="'.$app_key.'", nonce="'.$nonce.'", signature="'.$sign.'"'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
//将请求参数连接成字符串,通过POST提交给接口
curl_setopt($ch, CURLOPT_POSTFIELDS, "question=".urlencode($content)."&userId=".$openid."&platform=custom&type=0");
$output = curl_exec($ch);
if ($output === FALSE){
return "cURL Error: ". curl_error($ch);
}
//返回接口的内容。
return trim($output);
}
index.php整体代码如下
<?php
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
$wechatObj->responseMsg();
}else{
$wechatObj->valid();
}
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if($tmpStr == $signature){
return true;
}else{
return false;
}
}
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$this->logger("R ".$postStr);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
switch ($RX_TYPE)
{
case "event":
$result = $this->receiveEvent($postObj);
break;
case "text":
$result = $this->receiveText($postObj);
break;
}
$this->logger("T ".$result);
echo $result;
}else {
echo "";
exit;
}
}
private function receiveEvent($object)
{
$content = "";
switch ($object->Event)
{
case "subscribe":
$content = "欢迎关注 德强1012 ";
break;
case "unsubscribe":
$content = "取消关注";
break;
}
$result = $this->transmitText($object, $content);
return $result;
}
private function receiveText($object)
{
$keyword = trim($object->Content);
include("xiaoi.php");
$content = getXiaoiInfo($object->FromUserName, $keyword);
$result = $this->transmitText($object, $content);
return $result;
}
private function transmitText($object, $content)
{
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
}
private function logger($log_content)
{
if(isset($_SERVER['HTTP_BAE_ENV_APPID'])){ //BAE
require_once "BaeLog.class.php";
$logger = BaeLog::getInstance();
$logger ->logDebug($log_content);
}else if(isset($_SERVER['HTTP_APPNAME'])){ //SAE
sae_set_display_errors(false);
sae_debug($log_content);
sae_set_display_errors(true);
}else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
$max_size = 10000;
$log_filename = "log.xml";
if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
}
}
}
?>
xiaoi.php整体代码如下:
<?php
//var_dump(getXiaoiInfo("asdf", "你是谁?"));
function getXiaoiInfo($openid, $content)
{
//定义app
$app_key="0266e*****";
$app_secret="Je5VbXAh3Pg*****";
//签名算法
$realm = "xiaoi.com";
$method = "POST";
$uri = "/robot/ask.do";
$nonce = "";
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
for ($i = 0; $i < 40; $i++) {
$nonce .= $chars[ mt_rand(0, strlen($chars) - 1) ];
}
$HA1 = sha1($app_key.":".$realm.":".$app_secret);
$HA2 = sha1($method.":".$uri);
$sign = sha1($HA1.":".$nonce.":".$HA2);
//接口调用
$url = "http://nlp.xiaoi.com/robot/ask.do";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Auth: app_key="'.$app_key.'", nonce="'.$nonce.'", signature="'.$sign.'"'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "question=".urlencode($content)."&userId=".$openid."&platform=custom&type=0");
$output = curl_exec($ch);
if ($output === FALSE){
return "cURL Error: ". curl_error($ch);
}
return trim($output);
}
上一篇: 邻居家飘咱家来了