基于新浪云服务器的微信公众号
本微信公众号是智能浴室排雾及浴室滑倒报警系统的一个分支,通过设备上传到ONENET云平台,新浪云服务器调用云平台数据再反馈给微信公众号,从而实现微信公众号实时获取设备数据和发送报警信息给指定用户。
因为只是代码放置在服务器,不需要数据库,相比较一下,新浪云三个月才十块钱。这也是我选择它的原因。
文章目录
一、 前提准备
查阅 ONENET平台的开发者文档 https://open.iot.10086.cn/doc/
查阅微信公众号的开发者文档: https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html/
php的curl函数:https://www.cnblogs.com/Renyi-Fan/p/10551453.html/
新浪云服务器的注册
微信测试号的申请
二、 配置新浪云服务器
1、打开新浪云服务器官网:**https://login.sina.com.cn 点注册
2、实名认证(我因为没有实名认证,微信公众号的token一直验证失败),点用户中心就可以找到(学生认证有优惠)
3、找到控制台,点击云应用SAE,创建应用
4、这里我是用php语言编写代码的,代码运行环境选择标准环境就好,一般不会超过额度,二级域名可自由编辑,但要记住后面有用到(这个应用每天10云豆租金=0.01元)
5、点击管理
6 、点击运行环境管理下的代码管理
7、点击创建新版本,可自由编辑
8、点击在线编辑或者上传代码包(以下操作为在线编辑)
9、创建index.php文件 (与微信公众号连接)(代码是在微信公众号开发文档的示例代码上改进的), 右击index.php,点通过URL访问(复制跳转的网址)
三、微信测试号连接新浪云服务器(因为测试号权限比较多方便测试)
1、微信测试号申请(微信扫码登录即可)
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2、接口配置信息
URL是上一步跳转的网址,Token是验证的令牌,可自己编写但是要与服务器的一致(第三行代码)。
define("TOKEN", "weixin");
3、如果提示“token验证失败”,可以先重次几次,微信服务器有时候不稳定。验证失败很大可能是新浪云服务器没有实名认证。
四、微信测试号与新浪云服务器的信息交互
信息交互的流程图可知,再参考微信文档,我们还要写一个函数来判断信息是否是微信服务器发送过来的信息
//验证签名
public function valid()
{
$echoStr = $_GET["echostr"];
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if($tmpStr == $signature){
echo $echoStr;
exit;
五、微信公众号关键字回复信息
1、需要解决的问题:
如何接收微信交互的xml
如何处理微信的各种消息
如何响应微信的各种消息
2、解决思路:
响应信息->进行消息分类->接收相对应的事件信息->发送事件信息
//消息类型分离
switch ($RX_TYPE)
{
case "event":
$result = $this->receiveEvent($postObj);
break;
case "text":
if (strstr($postObj->Content, "第三方")){
$result = $this->relayPart3("http://www.fangbei.org/test.php".'?'.$_SERVER['QUERY_STRING'], $postStr);
}else{
$result = $this->receiveText($postObj);
}
break;
case "image":
$result = $this->receiveImage($postObj);
break;
case "location":
$result = $this->receiveLocation($postObj);
break;
case "voice":
$result = $this->receiveVoice($postObj);
break;
case "video":
case "shortvideo":
$result = $this->receiveVideo($postObj);
break;
case "link":
$result = $this->receiveLink($postObj);
break;
default:
$result = "unknown msg type: ".$RX_TYPE;
break;
}
$this->logger("T \r\n".$result);
echo $result;
}else {
echo "";
exit;
}
3、关键字接收信息实现:
该项目主要查询浴室的温湿度情况,即微信客户端发送文本信息给微信公众号,从而代码编写在接收文本信息类型下。
private function receiveText($object)
{
$keyword = trim($object->Content);
//多客服人工回复模式
if (strstr($keyword, "请问在吗") || strstr($keyword, "在线客服")){
$result = $this->transmitService($object);
return $result;
}
//自动回复模式
if (strstr($keyword, "文本")){
$content = "这是个文本消息";
}else if (strstr($keyword, "表情")){
$content = "微笑:/::)\n乒乓:/:oo\n中国:".$this->bytes_to_emoji(0x1F1E8).$this->bytes_to_emoji(0x1F1F3)."\n仙人掌:".$this->bytes_to_emoji(0x1F335);
}else if(strstr($keyword, "温度")){
$header[]="Authorization:version=2018-10-31&res=products%2F372638&et=1800000000&method=md5&sign=8MEzCS8Zv3lhnBNjRCYPBA%3D%3D";//此处写成自己的API-KEY值 API-key可以通过token软件获取
$url="http://api.heclouds.com/devices/630610047/datapoints?datastream_id=temp";/*获取数据流为**的数据值,注意此处设备ID号以及申请获取的数据流ID号都应根据自己的OneNet平台设备ID号, 希望获取的数据流ID号进行更改*/
//用于获取从OneNet平台返还的数据
function get_one($url, $header)
{
//1.初始化,创建一个新cURL资源
$ch=curl_init();
//2.设置URL和相应的选项
curl_setopt($ch,CURLOPT_URL,$url);//需要获取的URL地址,也可以在curl_init()函数中设置
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);//启用时会将头文件的信息作为数据流输出
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//将curl_exec()获取的信息以字符串返回,而不是直接输出。
curl_setopt($ch,CURLOPT_HEADER,0);//启用时会将头文件的信息作为数据流输出。
if(curl_exec($ch)=== false) //curl_error()返回当前会话最后一次错误的字符串
{
die("Curlerror: ".curl_error($ch));
}
$response =curl_exec($ch);//获取返回的文件流
curl_close($ch);
return $response;
}
$output=get_one($url,$header);
$outputt = json_encode($output,true);
//$output_arr0 = $outputt [116];
//$output_arr1 = $outputt [117];
//$output_arr2 = $outputt [118];
//$output_arr3 = $outputt [119];
$temp = split(":", $outputt)[9];
$temp = split("}", $temp)[0];
$time = split("\"", $outputt)[14];
$time = split("\.", $time)[0];
//$time = split('"', $time)[0];
//$temp=$output_arr0.$output_arr1.$output_arr2.$output_arr3;
//$content =date("Y-m-d H:i:s",time())."\n"."你查询浴室的室温为".$temp."℃";
$content = $time."\n"."你查询浴室的室温为".$temp."℃";
}else if(strstr($keyword, "湿度")){
$header[]="Authorization:version=2018-10-31&res=products%2F372638&et=1800000000&method=md5&sign=8MEzCS8Zv3lhnBNjRCYPBA%3D%3D";//此处写成自己的API-KEY值
$url="http://api.heclouds.com/devices/630610047/datapoints?datastream_id=humi";/*获取数据流为**的数据值,注意此处设备ID号以及申请获取的数据流ID号都应根据自己的OneNet平台设备ID号,
希望获取的数据流ID号进行更改*/
//用于获取从OneNet平台返还的数据
function get_one($url, $header)
{
//1.初始化,创建一个新cURL资源
$ch=curl_init();
//2.设置URL和相应的选项
curl_setopt($ch,CURLOPT_URL,$url);//需要获取的URL地址,也可以在curl_init()函数中设置
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);//启用时会将头文件的信息作为数据流输出
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//将curl_exec()获取的信息以字符串返回,而不是直接输出。
curl_setopt($ch,CURLOPT_HEADER,0);//启用时会将头文件的信息作为数据流输出。
if(curl_exec($ch)=== false) //curl_error()返回当前会话最后一次错误的字符串
{
die("Curlerror: ".curl_error($ch));
}
$response =curl_exec($ch);//获取返回的文件流
curl_close($ch);
return $response;
}
$output=get_one($url,$header);
$outputt = json_encode($output,true);
//$output_arr0 = $outputt [116];
//$output_arr1 = $outputt [117];
$humi = split(":", $outputt)[9];
$humi = split("}", $humi)[0];
$time = split("\"", $outputt)[14];
$time = split("\.", $time)[0];
//$humi=$output_arr0.$output_arr1;
//$content =date("Y-m-d H:i:s",time())."\n"."你查询浴室的湿度为".$humi."%";
$content = $time."\n"."你查询浴室的湿度为".$humi."%";
}else if (strstr($keyword, "链接")){
$content = "电话号码:0755-83765566\n\n电子邮件:40012345@qq.com\n\n访问链接:<a href='http://www.qq.com/'>点此访问腾讯网</a>";
}else if (strstr($keyword, "图文")){
$content = array();
$content[] = array("Title"=>"图文标题", "Description"=>"图文内容", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
}else if (strstr($keyword, "多图文")){
$content = "微信官方已经禁用了多图文的这一消息格式。--2018年10月12日起,被动回复消息与客服消息接口的图文消息类型中图文数目只能为一条,请知悉。";
}else if (strstr($keyword, "音乐")){
$content = array();
$content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"http://mascot-music.stor.sinaapp.com/zxmzf.mp3", "HQMusicUrl"=>"http://mascot-music.stor.sinaapp.com/zxmzf.mp3");
}else{
$content = "请回复以下关键字:温度 湿度 文本 表情 链接 单图文 多图文 音乐\n请按住说话 或 点击 + 再分别发送以下内容:语音 图片 小视频 我的收藏 位置";
// $content = "";
}
if(is_array($content)){
if (isset($content[0])){
$result = $this->transmitNews($object, $content);
}else if (isset($content['MusicUrl'])){
$result = $this->transmitMusic($object, $content);
}
}else{
$result = $this->transmitText($object, $content);
}
return $result;
}
4、关键字回复信息实现:xml格式根据微信公众号文档获取
//回复文本消息
private function transmitText($object, $content)
{
if (!isset($content) || empty($content)){
return "";
}
$xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
}
六、微信公众号主动发送信息
1、获取access-key(令牌):
微信测试号的账号的appid和appsecret(登录测试号即看到)
Access-key的有效时间是2小时,测试号每日调用上限是200次。
2、 获取指定用户id,微信测试号的可以直接知道用户的openid。
3、编写模板信息的格式:确定以后,会生成一个模板ID,到时候填写模板ID即可。
4、写模板信息的json格式化:first 与remark 要与模板的相一致。
/**
* 将模板消息json格式化
*/
public function json_tempalte(){
//模板消息
$template=[
'touser' => 'oTG9I5v-s1dSaq3lgl1yZfVqgi3E', //用户openid
'template_id' => "A0uPru_lwLt1jUaOw92Qkg5iTkuqnH_d0pwrI8RCUiY", //在公众号下配置的模板id
'url' => "http://baidu.com", //点击模板消息会跳转的链接
'topcolor' => "#7B68EE",
'data'=>array(
'first' =>array('value'=>"浴室有人跌倒,请前往查看!!!!",
'color' =>"#173177"),
'remark' =>array('value'=>date("Y-m-d H:i:s",time()),
'color' =>"#173177")
)
];
$json_template=json_encode($template);
return $json_template;
}
5、实现发送:
1、服务器发送:通过php的curl实现post方法发送
/**
* 发送模板消息
*/
public function send_notice(){
$appid = 'wx2daf26657825f3cd';
$appsecret = '6f979bfc496e7f75560ab06b7b99cf00 ';
$access_token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret;
//获取access_token
$json_token=$this->curl_post($access_token_url);
$access_token1=json_decode($json_token,true);
$access_token2=$access_token1['access_token'];
//模板消息https://open.iot.10086.cn/
while(1){
$output=get("http://api.heclouds.com/devices/630610047/datapoints?datastream_id=warming","Authorization:version=2018-10-31&res=products%2F372638&et=1800000000&method=md5&sign=8MEzCS8Zv3lhnBNjRCYPBA%3D%3D");
$outputt = json_encode($output,true);
$arr = $outputt [116];
if($arr==0){
$json_template = $this->json_tempalte();
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token2;
$res = $this->curl_post($url,urldecode($json_template));
sleep(30);
}
else{
echo "";
exit;
}
}
/**
* @param $url
* @param array $data
* @return mixed
* curl请求
*/
function curl_post($url , $data=array()){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// POST数据
curl_setopt($ch, CURLOPT_POST, 1);
// 把post的变量加上
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
2、接口发送:
6、效果展示图。
七、新浪云服务器调用ONENET平台数据
1、获取ONENNET的API。这里我采用的是安全鉴权的方式,生成Authorization是利用token工具实现的
2、获取设备数据流。我们数据上传选择的是MQTT协议,所以查阅MQTT的相关文档即可知道如何获取
3、为确认Authorization和GET方法是否有效,这里我采用的是APIPOST(postman一样效果)接口软件进行测试
4、服务器与服务器之间的数据调用
php的curl函数就可以解决GET和POST方法的调用。
curl是PHP的一个扩展,利用该扩展可以实现服务器之间的数据或文件传输也就是说curl就是一个工具,用来做服务器之间数据、文件传输的工具。