如何使用开发者服务器运维微信公众号
2018-03-04 18:58
204 查看
很多人都有自己的服务器,特别是对于大学生而言,很多服务器公司都对学生有优惠,例如腾讯云只要1元每月:http://blog.csdn.net/tiandixuanwuliang/article/details/56494528 ,那么我们作为一名程序员,总想把一切掌控在自己手中,<哈哈>,那么如何使用我们开发者服务器去管理微信公众号呢?这就是本文介绍的内容。
本文介绍以下内容:
(1)如何把微信公众号授权给开发者服务器
(2)如何使用代码把开发者服务器与微信服务器进行关联
(3)实现接受和发送消息
(4)自定义菜单
注:这里也可以不取消第三方服务器的授权,不取消的话,公众号粉丝发送的数据会同时1发送到第三方服务器和开发者服务器,本人已经验证了,有兴趣可以自行研究
(2)回到微信公众号管理平台首页,页面往下拉,选择“基本配置”,如图:
(3)添加ip白名单
(4)选择修改配置
(5)下图中的url,指向你自己的服务器中正在运行的php地址,这是本文代码开发的重点,具体内容请看下一章。token可以随便写,但是需要与上述php文件中配置的一样,具体内容请看下一章
(1)该php文件内容如下,下面的代码实现了连接开发者服务器、关键字回复、图灵机器人功能,注:请把下面的token填写为第一章第5小节中截图中设置的token
(2)上面代码可以用下面的结构图进行分析:
(3)下面是自定义菜单的代码(不建议使用,原因请看下面的第5小节)
(4)下面是网页授权,授权后我们才可以在代码中调用(不建议使用,原因请看下面的第5小节)
(5)但是由于个人注册的订阅号没有自定义菜单的开发权限,所以我建议大家自定义菜单的功能交给第三方服务处理,这也是一个窍门,就是微信公众号同时授权给第三方服务器和开发者服务器,这是一个bug,哈哈。请注意,一定要先授权给开发者服务器,再授权给第三方服务器,否则将不成功。原理图如下:
上图中的第三方服务器具有关键字功能,我建议一些常用的关键字都交给第三方服务器做。一些具有逻辑性的关键字、需要存放到数据库的关键字、或者私密性的关键字可以由开发者服务器做。但是由于微信公众号粉丝发送的数据会同时发送到两个服务器,而且开发者服务器还具有图灵机器人功能,可以采取屏蔽的方法,在任意一方屏蔽一次,这样就避免了一条消息,回复了两次的问题。
(6)请把上述php文件,放到AppServ软件安装的根目录下的www文件夹下,然后重启AppServ中的服务,最后再把 http://服务器ip地址/index.php 填写到第一章第5节的url中即可。可以开始玩了
本文地址:http://blog.csdn.net/tiandixuanwuliang/article/details/79438662
欢迎大家看我的另一篇文章,这篇文章从需求分析、系统设计、代码实现等方面进行讲解,欢迎大家批评指正,http://blog.csdn.net/tiandixuanwuliang/article/details/79438738
欢迎大家关注,里面有很多资源分享:
本文介绍以下内容:
(1)如何把微信公众号授权给开发者服务器
(2)如何使用代码把开发者服务器与微信服务器进行关联
(3)实现接受和发送消息
(4)自定义菜单
1 如何把微信公众号授权给开发者服务器
(1)进入微信公众号平台,https://mp.weixin.qq.com/,首先请取消其他第三方服务器的授权,方法如下:注:这里也可以不取消第三方服务器的授权,不取消的话,公众号粉丝发送的数据会同时1发送到第三方服务器和开发者服务器,本人已经验证了,有兴趣可以自行研究
(2)回到微信公众号管理平台首页,页面往下拉,选择“基本配置”,如图:
(3)添加ip白名单
(4)选择修改配置
(5)下图中的url,指向你自己的服务器中正在运行的php地址,这是本文代码开发的重点,具体内容请看下一章。token可以随便写,但是需要与上述php文件中配置的一样,具体内容请看下一章
2 如何使用代码把开发者服务器与微信服务器进行关联
(0)这一章讲解代码的开发。第一章第5小节中的url指向自己的服务器中正在运行的php文件,本章将介绍这一个文件的内容。关于如何运行这个php文件,请看php教程http://blog.csdn.net/tiandixuanwuliang/article/category/7344088(1)该php文件内容如下,下面的代码实现了连接开发者服务器、关键字回复、图灵机器人功能,注:请把下面的token填写为第一章第5小节中截图中设置的token
<?php /** * 微信公众号开发-入门 * * api */ define("TOKEN",'we--xxxx'); //这里和你微信公众号开放平台上的tonken填写一样的即可 $weixinApi=new WeixinApi(); if(isset($_GET["echostr"])){ $weixinApi->valid(); }else{ $weixinApi->responseMsg(); } class WeixinApi{ //验证接口 public function valid(){ $echoStr = $_GET["echostr"];//从微信用户端获取一个随机字符赋予变量echostr if($this->checkSignature()){ echo $echoStr; exit; } } //检查签名 private function checkSignature(){ //1 接受微信服务器get请求发送过来的4个参数 $signature = $_GET["signature"];//从用户端获取签名赋予变量signature $timestamp = $_GET["timestamp"];//从用户端获取时间戳赋予变量timestamp $nonce = $_GET["nonce"]; //从用户端获取随机数赋予变量nonce //2 加密和校验请求 //2.1 将token、timestamp、nonce三个参数进行字典序排序 $tmpArr = array(TOKEN, $timestamp, $nonce);//简历数组变量tmpArr sort($tmpArr, SORT_STRING);//新建排序 //2.2 将三个参数字符串拼接成一个字符串进行sha1加密 $tmpStr = implode($tmpArr);//数组转字符串 $tmpStr = sha1($tmpStr);//shal加密 //2.3 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 if ($tmpStr == $signature) { return true; } else { return false; } } //回复消息 public function responseMsg(){ //3 以下代码接受消息 //3.1 接受微信服务器发送过来的原生的POST的数据包 // $postData = $GLOBALS["HTTP_RAW_POST_DATA"]; $postData = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] :file_get_contents("php://input"); //3.2 处理数据包 $xmlObj = simplexml_load_string($postData, "SimpleXMLElement", LIBXML_NOCDATA); $msgType = $xmlObj->MsgType; //4 根据消息类型进行业务处理 switch ($msgType) { //接受事件消息 case 'event': $this->disposeEvent($xmlObj); break; //接受文本消息 case 'text': $this->disposeText($xmlObj); break; //接受图片消息 case 'image': $this->disposeImage($xmlObj); break; } } //处理接收的事件消息 private function disposeEvent($xmlObj){ switch ($xmlObj->Event){ case 'subscribe'://订阅事件 $this->sendText('欢迎您的订阅'); break; case 'unsubscribe'://取消订阅事件 $this->sendText('good-bye');//该消息用户其实是看不到的,取消订阅事件一般用来清除数据库记录 break; } } //处理接收的文本消息 private function disposeText($xmlObj){ $text=trim($xmlObj->Content); //包含关键字都不做处理 if (!( strstr($text,'违规') //这里对违规的关键字做排除,不予理睬 )){ switch ($text){ case '你好': $this->sendText($xmlObj,'Hi 我是开发者服务器'); break; case 'new': $newsArr=array( array( "title"=>"看到这条消息,你可以买彩票了", "description"=>"本公众号有许多小彩蛋,欢迎您的探索。", "picUrl"=>"http://img.mp.itc.cn/upload/20170610/03d69e8df0524b8cb59fd16dc2fec989.jpg", "url"=>"http://www.baidu.com" ) ); $this->sendNews($xmlObj,$newsArr); break; default: $this->tuling123($xmlObj,trim($xmlObj->Content)); //图灵机器人 } } } //处理接收的图片消息 private function disposeImage($xmlObj){ //一般情况下,不会去处理用户发送的图片 $this->sendImage($xmlObj,$xmlObj->PicUrl,$xmlObj->MediaId); } //发送文本的方法 private function sendText($xmlObj,$content){ $replyTextMsg="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; echo sprintf($replyTextMsg,$xmlObj->FromUserName,$xmlObj->ToUserName,time(),$content); } //发送图片的方法 private function sendImage($xmlObj,$mediaId){ $replyImageMsg="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[image]]></MsgType> <Image> <MediaId><![CDATA[%s]]></MediaId> </Image> </xml>"; echo sprintf($replyImageMsg,$xmlObj->FromUserName,$xmlObj->ToUserName,time(),$mediaId); } //发送图文的方法 private function sendNews($xmlObj,$newsArr){ $newsTplHead = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>%s</ArticleCount> <Articles>"; $newsTplBody = "<item> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item>"; $newsTplFoot = "</Articles> <FuncFlag>%s</FuncFlag> </xml>"; $replyNewsMsg = sprintf($newsTplHead, $xmlObj->FromUserName, $xmlObj->ToUserName, time(),count($newsArr)); foreach($newsArr as $key => $value){ $replyNewsMsg .= sprintf($newsTplBody, $value['title'], $value['description'], $value['picUrl'], $value['url']); } $replyNewsMsg .= sprintf($newsTplFoot, 0); echo $replyNewsMsg; } public function tuling123($xmlObj,$message){//这是是使用图灵机器人 $tuTonken='2d8aaa17141c443----xxx---fsa'; //请去图灵网http://www.tuling123.com/自己申请一个tonken $tuUrl='http://www.tuling123.com/openapi/api?key='.$tuTonken.'&info='.$message.'&userid='.$xmlObj->FromUserName; $tuData='{ "key": "'.$tuTonken.'", "info": "'.$message.'", "userid": "'.$xmlObj->FromUserName.'" }'; $results = $this->htts_request($tuUrl,$tuData); // print_r($results); if ($results['code']==100000){ $text=$results['text']; $this->sendText($xmlObj,$text); }else{ $this->sendText($xmlObj,'有问题,请输入“帮助”'); } } //https请求(get和post) private function htts_request($url,$data=array()){ //1 初始化curl $ch=curl_init(); //2 设置传输选项 curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//把页面以文件流的形式返回 if (!empty($data)) { curl_setopt($ch, CURLOPT_POST, true); //设置为 POST 请求 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //设置POST的请求数据 } //3 执行curl请求 $outopt=curl_exec($ch); $outoptArr=json_decode($outopt,true); //4 关闭curl curl_close($ch); return $outoptArr; } } ?>
(2)上面代码可以用下面的结构图进行分析:
(3)下面是自定义菜单的代码(不建议使用,原因请看下面的第5小节)
//获取access_token private function getAccessToken(){ //获取微信接口凭证 $appid="wxb4----xxx";//请在第一章第5小节的图片中看 $appsecret="21d---xxx";//请在第一章第5小节的图片中看 $data=json_decode(file_get_contents('./access_token.json')); if ($data->expires_time <time()){ $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}"; $outoptArr=$this->htts_request($url,array(),false); $access_token=$outoptArr['access_token']; if (!empty($access_token)){ //把access_token写入文件 $data->access_token=$outoptArr['access_token']; $data->expires_time=time()+7000; $fp=fopen('access_token.json','w'); fwrite($fp,json_encode($data)); fclose($fp); }else{ echo '请求access_token错误'; } }else{ $access_token=$data->access_token; } // echo $access_token; return $access_token; } //实现自定义菜单 public function menu_create(){ $access_token=$this->getAccessToken(); $url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$access_token}"; $data='{ "button": [ { "type": "click", "name": "java", "key": "learn_java" }, { "name":"chengxu", "sub_button":[ { "type": "view", "name": "CSDN", "url": "http://blog.csdn.net/tiandixuanwuliang/" }, { "type": "view", "name": "Github", "url": "https://github.com/wllfengshu/" }, { "type": "view", "name": "jianshu", "url": "https://www.jianshu.com/users/4d12e03d0a5f/timeline/" }, { "type": "view", "name": "kaifazhe", "url": "https://toutiao.io/u/431066/" }, { "type": "view", "name": "yuyan", "url": "http://www.baidu.com" }] }, { "name":"jiaoliu", "sub_button":[ { "type": "view", "name": "shuji", "url": "http://blog.csdn.net/tiandixuanwuliang/" }, { "type": "view", "name": "ziyuan", "url": "https://github.com/wllfengshu/" }, { "type": "view", "name": "sucai", "url": "https://www.jianshu.com/users/4d12e03d0a5f/timeline/" }, { "type": "view", "name": "daxuesheng", "url": "https://toutiao.io/u/431066/" }, { "type": "click", "name": "zuozhe", "key": "about_author" }] } ] }'; echo $url." ///// ".$data; $outoptArr=$this->htts_request($url,json_decode($data,true),true); echo '***'; print_r($outoptArr); }
(4)下面是网页授权,授权后我们才可以在代码中调用(不建议使用,原因请看下面的第5小节)
//网页授权-base型 public function snsapi_base($redirect_uri){ //以下是测试账号 $appid="wxb4----xxx";//请在第一章第5小节的图片中看 $appsecret="21da56-----xxx";//请在第一章第5小节的图片中看 //准备scope $snsapi_base_url="https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope=SCOPE&state=123#wechat_redirect"; $code=$_GET['code']; //获取code if (!isset($code)){ header("Location:{$snsapi_base_url}"); } //获取access_token $url="https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code"; return $this->htts_request($url); }
(5)但是由于个人注册的订阅号没有自定义菜单的开发权限,所以我建议大家自定义菜单的功能交给第三方服务处理,这也是一个窍门,就是微信公众号同时授权给第三方服务器和开发者服务器,这是一个bug,哈哈。请注意,一定要先授权给开发者服务器,再授权给第三方服务器,否则将不成功。原理图如下:
上图中的第三方服务器具有关键字功能,我建议一些常用的关键字都交给第三方服务器做。一些具有逻辑性的关键字、需要存放到数据库的关键字、或者私密性的关键字可以由开发者服务器做。但是由于微信公众号粉丝发送的数据会同时发送到两个服务器,而且开发者服务器还具有图灵机器人功能,可以采取屏蔽的方法,在任意一方屏蔽一次,这样就避免了一条消息,回复了两次的问题。
(6)请把上述php文件,放到AppServ软件安装的根目录下的www文件夹下,然后重启AppServ中的服务,最后再把 http://服务器ip地址/index.php 填写到第一章第5节的url中即可。可以开始玩了
本文地址:http://blog.csdn.net/tiandixuanwuliang/article/details/79438662
欢迎大家看我的另一篇文章,这篇文章从需求分析、系统设计、代码实现等方面进行讲解,欢迎大家批评指正,http://blog.csdn.net/tiandixuanwuliang/article/details/79438738
欢迎大家关注,里面有很多资源分享:
相关文章推荐
- 微信公众号入门学习1_使用C#,ASP.NET APIController如何公众号接入服务器并启动开发者模式
- 如何在免费的第三方服务器上运维微信公众号
- 服务器运维学习——如何永久使用虚拟机VMware
- 如何在Suse_Linux9.0下使用Loadrunner监控服务器资源使用情况
- 如何通过 SQL Server 链接服务器和分布式查询使用 Excel
- 如何跨子网使用DHCP服务器
- 如何通过 SQL Server 链接服务器和分布式查询使用 Excel
- [C#]使用HttpWebRequest请求远端服务器时如何加载SSL证书
- 如何使用户能下载服务器中的文件
- 如何禁止普通用户使用企业管理器列出服务器上的数据库列表
- 如何:使用 AdRotator Web 服务器控件显示 XML 文件中的广告
- 如何使用Projecct 2003连接公司的Project 服务器
- Tomcat服务器下如何配置并使用可执行CGI,扩屏名是exe的。
- [dotNET]使用HttpWebRequest请求远端服务器时如何加载SSL证书
- 如何防止他人使用旧id和旧口令访问Domino服务器?
- 工具推荐:如何部署使用“远程桌面Web连接”,并且扩展它,可以连接非3389端口的远程桌面,(服务器管理员必备)
- 如何使用部署实用工具和配置来简化在服务器之间移动软件包的工作
- 如何使用HTTP压缩优化服务器 推荐
- 使用红帽企业版Linux如何配置一个点对点(PPP)拨号服务器?
- 使用Socket API如何与WEB服务器通信