年终了,各大公司都在准备着年终聚会,我所在公司今年打算潮一点,使用微信公众号来抽奖。由于手上的公众号属于订阅号,能使用的接口权限有限,时间紧(仅仅几个小时,来不及通过开发平台拓展微信相关接口)我又不想使用第三方的抽奖程序,因为第三方的没法控制中奖者(你懂的),然后就使用订阅号自动回复功能开发了一套文字抽奖程序,其中使用到了数据库,并对抽奖流程进行控制,可以添加必中名单。微信的回复功能可以用来做微信机器人,水煮鱼大神已经做过了,也可以用来做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的解决办法,扔到你的服务器,然后去微信公众号后台设置下接口,回复内容试试效果吧。
}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数据
//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 = ”
%s
“;
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;
}
}
}
如果不出意外,你回复任意字符公众号会给你回复“我听不懂”四个字,具体的抽奖逻辑需要你自己写了,就是对用户发来的数据进行判断而已。