本博文就月初刚上线的微信服务号,图文进行总结分享给大家。
去年年底,我所在的团队讨论要开发微信号,话题由此拉开:
原来有一个3年前注册的微信号,但是后台操作无法从“订阅号”变更为“服务号”,随即找腾讯的客服沟通,客服还算是热情,mm耐心的告之系统已经更新,对于无法升级的微信号,只能重新注册----“*#*(*¥)¥K30#$e&#)”,一阵抓狂后,只能重新注册了,下面就开始从注册到内部需求讨论,到开发的图文总结。
在微信公众号官网: https://mp.weixin.qq.com ,点击注册
如上图所示,微信号由邮箱注册,每个邮箱仅能申请一种帐号:服务号、订阅号或企业号。
这里按照说明输入公司信息即可,本次我们选择的是 认证服务号 的选项:
为了认证服务号,需要支付300元/年,这个步骤稍微麻烦一些:财务打款、等待7个工作日、邮递发票等。
需要注意的是,微信的认证不是腾讯官方,是其委托方的第三方,这个刚开始的时候还比较差异。
在完成后的认证后,认证信息如下(略过中间扫描公司的营业执照、扫描盖公章的认证协议等细节):
微信开发和学习使用 ComponentOne控件 一样,需要做第一件事件是看微信官方的文档、API、demo样例代码,这样能极大减少走弯路的风险。
备注:原计划看几本热销的微信开发书籍,后来因为时间原因放弃了。
登陆微信后台,点击左侧的“开发者中心”,右侧出现的“ 开发者文档 ”、“ 在线接口调试工具 ”即是微信官方提供的文档和API利器,在开发过程中,会反复、多次使用,这2个是非常重要的资料。
在公众号“开发者中心”中,把AppID和AppSecret记下来,后面会多次用到。
微信的官方文档,首先从上往下通读一遍:
在文档的开始,微信官方就提供了PHP示例代码, 下载地址 。 且其明确的告之,微信公众号接口只支持80接口.
官方文档写的非常细,如获取 access token 是基于HTTP请求,用的是GET方式,其他的文档请直接参阅 文档 :
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
备注:access_token的有效时间是7200s,既需要自行做一个缓存,2小时刷新一次access_token; 我在这里用的是文件的缓存方式,添加了时间戳。
这节,我们着手搭建环境。
首先选择 http://git.oschina.net 搭建源码托管环境,OSC提供了免费的私有项目,配合使用TortoiseGit-1.8.11.0-64bit,使得搭建源码托管环境非常简单。另外,其在国内访问Git速度超快(赞一个!)
接着安装软件,配置电脑开发环境:
为了方便测试,和公司网管沟通,把微信的***. gcpowertools.com.cn / 80端口映射到我的局域网电脑。事后证明,这种本地调试方法非常高效,极大了提高了开发、调试效率。最后,为了方便调试微信数据,需要写log进行日志呈现,这里我使用的是读写文件的方式。
function writeLogBegin($msg = "begin log..............")
{
$logFile = date('Y-m-d') . '.txt';
$msg = date('Y-m-d H:i:s') . ' >>> ' . $msg . "/r/n";
file_put_contents("c://log.txt", $msg);
}
首先,结合业务特点,规划微信底部的自定义菜单。
小技巧:自定义菜单不用写代码,用微信官方自带的调试页面即可完成。
规划好自定义菜单后,POST JSON到微信服务器,可直接使用 微信公众平台接口调试工具 。
保存生成的access_token, 类似如下的文本:
vU2rq8nzdXZWmcS3jO1OAZzRL5dnm3OIlsPF8ZCKHkTGfrG8f87QpwYa4mBpkTvnuy0pQJsfyq_L5xLIqPSoIBIqdsVAaKOuEgBrPpQ4
接着选择“自定义菜单”,输入刚才保存的access_token,输入如下的JSON字符串:
{
"button":[
{
"name":"学习中心",
"sub_button":[
{
"type":"click",
"name":"联系葡萄城",
"key":"101"
}]
},
{
"name":"我的服务",
"sub_button":[
{
"type": "view",
"name": "最新动态",
"url": " https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9665cf3fcdaee2f1&redirect_uri=http://www.gcpowertools.com.cn&response_type=code&scope=snsapi_base&state=118#wechat_redirect"
},
{
"type": "view",
"name":"最新版本",
"url": " https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9665cf3fcdaee2f1&redirect_uri=http://www.gcpowertools.com.cn&response_type=code&scope=snsapi_base&state=118#wechat_redirect"
},
{
"type":"click",
"name":"金牌服务查询",
"key":"102"
},
{
"type":"click",
"name":"金牌服务条款",
"key":"103"
}
]
},
{
"name":"GCDN社区",
"sub_button":[
{
"type":"click",
"name":"每日签到",
"key":"104"
},
{
"type":"click",
"name":"信息查询",
"key":"105"
},
{
"type":"click",
"name":"我的帖子",
"key":"106"
},
{
"type":"click",
"name":"热门问答",
"key":"107"
},
{
"type":"view",
"name":"礼品兑换",
"url":" https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9665cf3fcdaee2f1&redirect_uri=http://www.gcpowertools.com.cn&response_type=code&scope=snsapi_base&state=118#wechat_redirect"
}]
}]
}
备注:创建 自定义菜单 后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
接着,我们进行核心的功能开发。
微信服务号的核心围绕GCDN社区,故“GCDN社区”子菜单有5个二级菜单,其中每日签到、信息查询、我的帖子、礼品兑换功能需要首先绑定自己的 GCDN账号 GCDN账号。
依据上面的逻辑,绑定GCDN账号是前提环节,故需要开发绑定功能。 绑定功能,做了一个页面,通过a标签跳转,用户在输入用户名、密码后进行GCDN鉴权验证,验证通过存储在表:包含GCDN ID、微信的OpenID,既完成账号绑定。
后面的多个功能,通过这个表,可从微信的OpenID获得GCDN ID,继而可以使用GCDN论坛中的个人信息。
打开论坛页面,在底部可看到目前GCDN使用的引擎较早,是 Discuz!NT 3.6.711 版本,故X3.1版本中时尚的签到功能是没有的。针对这个遗憾,本次微信开发做了弥补:用户可通过微信的签到完成这个功能。
这是另外一个特色功能:无需操作,只需要绑定GCDN账号,当你在GCDN的发帖有人回复时,会自动收到微信通知。
这个功能的开发,主要是为了还GCDNer的一个期待:在《 2013年葡萄城控件用户满意度调查 》,论坛用户对此类功能呼声很高,“谢谢你们的努力和尽职尽责,我希望GCDN回帖及时些,最好有及时的短信通知功能,省的我时不时的刷新GCDN页面,催促你们!”--某GCDN用户。
实现思路如下图所示:
微信通知用户,刚开始想的是文本通知,结果发现微信公众号的政策:如果用户未在24小时内主动和微信互动,则无法用文本通知用户。想到另外一个变通的办法,各大银行的余额动态通知功能。接着仔细找微信提供的功能,原来这种功能是“微信模板消息”。
这段文档关于微信的模板消息写的很详细:
为了保证用户不受到骚扰,在开发者出现需要主动提醒、通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板ID,再根据模板ID向用户主动推送提醒、通知消息。
约花了半天时间,开发出的功能效果看起来还不错(用户是否在24小时内主动联系,均可发送模板消息),截图如下:
如想配置这个功能,通过回复文字指令。
上面的开发过程,用到的PHP的 curl 实现HTTP GET、POST请求的源码:
/** * @param $url * @param null $data * @return mixed */ function https_request($url, $data = null) { // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer if (!empty($data)) { curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 } curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环 curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 $tmpInfo = curl_exec($curl); // 执行操作 if (curl_errno($curl)) { echo 'Errno' . curl_error($curl);//捕抓异常 } curl_close($curl); // 关闭CURL会话 return $tmpInfo; // 返回数据 }
//使用网络代理begin curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($curl, CURLOPT_PROXY, '192.168.0.1'); //替换代理地址 curl_setopt($curl, CURLOPT_PROXYPORT, '880'); //替换代理端口 curl_setopt($curl, CURLOPT_PROXYTYPE, 'HTTP'); curl_setopt($curl, CURLOPT_PROXYUSERPWD, 'grapecity/r:r'); //替换代理用户名 //使用网络代理end
坑的定义:有时候没有问题,有时候有问题。100%有问题的,不叫坑,叫bug。
小伙伴们,有微信的不妨扫一扫,看看大家还有啥需求,我们接着开发、写博客吧:
关注微信绑定 GCDN账号 ,有GCDN勋章哟!