年终了,各大公司都在准备着年终聚会,我所在公司今年打算潮一点,使用微信公众号来抽奖。由于手上的公众号属于订阅号,能使用的接口权限有限,时间紧(仅仅几个小时,来不及通过开发平台拓展微信相关接口)我又不想使用第三方的抽奖程序,因为第三方的没法控制中奖者(你懂的),然后就使用订阅号自动回复功能开发了一套文字抽奖程序,其中使用到了数据库,并对抽奖流程进行控制,可以添加必中名单。微信的回复功能可以用来做微信机器人,水煮鱼大神已经做过了,也可以用来做WordPress的验证码,已经有相关插件了,这里就不赘述。
实现过程
首先需要2张数据表,一张命名为options,为这次抽奖活动的配置表,它控制整个抽奖流程开关及参数(包括是否必中,必中名单等)。另一张表是抽奖活动的统计数据,所有参与抽奖的人都会自动分配一个幸运号,然后将用户的微信openID和幸运号插入这张数据表中,当然还需要一个是否中奖的默认字段,默认为0,没有中奖。
随机选择中奖数据mysql命令如下:
update choujiang set `staic_z` = '1' order by rand() limit n
这里的n就是随机多少条数据,上面的命令执行后,mysql会在该表中随机抽取n条数据,并且将中奖状态改为1,表示中奖。
假如我们需要内定中奖者,就需要修改上面的mysql:
UPDATE `choujiang` set `staic_z` = 1 WHERE `username` NOT IN ('XXXXXXXXXXXXXXXX') ORDER BY rand() limit n
解释下,这里先排除了username字段为XXXXXXXXX的用户数据,再对其它数据进行随机修改。这里被排除在外的数据就是必中名单,你可以先将自己的信息加进去设置为中奖状态即可。
可能有朋友会问,你怎么不用中间件操作随机,那样更灵活呀。我之所以不那么做是因为我懒呀!你不觉得这样会少些很多代码吗?不用去取数据,不用更新数据。一句mysql命令就解决了。
由于微信订阅号没有权限获取用户的信息,使用开放平台又来不及审核,所以我们采用了随机幸运号的形式,下面是PHP生成随机数字,字符的构造函数源码。
/** * 取得随机数 * * @param int $length 生成随机数的长度 * @param int $numeric 是否只产生数字随机数 1是0否 * @return string */ function random($length, $numeric = 1) { $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35); $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed)); $hash = ''; $max = strlen($seed) - 1; for ($i = 0; $i < $length; $i++) { $hash .= $seed{mt_rand(0, $max)}; } return $hash; }
这段代码经测试保证可用,是我在网上找的,自己写伤脑筋。
最重要的就是使用代码实现微信公众号的自动回复功能了,下面是源码,复制保存为utf-8编码的PHP文件如果出现token无法认证,请查看这篇文章:微信订阅号无法绑定token的解决办法,扔到你的服务器,然后去微信公众号后台设置下接口,回复内容试试效果吧。
<?php header('content-type:text/html;charset=utf-8'); define("TOKEN", "token值"); //你在后台设置的token $wx = new wechatCallbackapiTest(); if($_GET['echostr']){ $wx->valid(); //如果发来了echostr则进行验证 }else{ $wx->responseMsg(); //如果没有echostr,则返回消息 } class wechatCallbackapiTest{ public function valid(){ //valid signature , option $echoStr = $_GET["echostr"]; if($this->checkSignature()){ //调用验证字段 echo $echoStr; exit; } } public function responseMsg(){ //get post data, May be due to the different environments //$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //接收微信发来的XML数据 $postStr=file_get_contents("php://input"); //extract post data if(!empty($postStr)){ //解析post来的XML为一个对象$postObj $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; //请求消息的用户 $toUsername = $postObj->ToUserName; //"我"的公众号id $keyword = trim($postObj->Content); //消息内容 $time = time(); //时间戳 $msgtype = 'text'; //消息类型:文本 $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; if($postObj->MsgType == 'event'){ //如果XML信息里消息类型为event if($postObj->Event == 'subscribe'){ //如果是订阅事件 $contentStr = "欢迎订阅精密智造定制!"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgtype, $contentStr); echo $resultStr; exit(); } } if($keyword == 'haha'){ $contentStr = '哈哈'; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgtype, $contentStr); echo $resultStr; exit(); }else{ $contentStr = "我听不懂"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgtype, $contentStr); echo $resultStr; exit(); } }else { echo ""; 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; } } }
如果不出意外,你回复任意字符公众号会给你回复“我听不懂”四个字,具体的抽奖逻辑需要你自己写了,就是对用户发来的数据进行判断而已。
评论 (4)