$redis_conf['host'], 'port' => $redis_conf['port'], 'passwd' => $redis_conf['passwd'] )); return $r; } protected function getMysql($accountid) { $mysql_conf = getMysqlConfig(crc32($accountid)); $conn = new phpcommon\Mysql(array( 'host' => $mysql_conf['host'], 'port' => $mysql_conf['port'], 'user' => $mysql_conf['user'], 'passwd' => $mysql_conf['passwd'], 'dbname' => 'kefudb' )); return $conn; } private function getAppointMysql($mysql_conf) { $conn = new phpcommon\Mysql(array( 'host' => $mysql_conf['host'], 'port' => $mysql_conf['port'], 'user' => $mysql_conf['user'], 'passwd' => $mysql_conf['passwd'], 'dbname' => 'kefudb' )); return $conn; } private function getAllMysql() { return require('../config/kefu.mysql.cluster.php'); } private function getAwardDBMaxIdx($conn) { $select_tbl_name = 'accounts_kefu'; $row = $conn->execQueryOne('SELECT idx ' . "FROM $select_tbl_name GROUP BY idx DESC LIMIT 1;" ); if ($row) { return $row['idx']; } else { return ''; } } private function getAccountsKefuInfo($min_idx, $max_idx, $conn) { $select_tbl_name = 'accounts_kefu'; $row = $conn->execQuery("SELECT * FROM $select_tbl_name " . "WHERE idx >= :min_idx AND idx < :max_idx;", array( ':min_idx' => $min_idx, ':max_idx' => $max_idx )); #error_log('getAccountsKefuInfo:' . json_encode($row)); if ($row) { return $row; } else { return ''; } } private function getAwardConfig($gameid, $condition) { $url = ''; if (SERVER_ENV != _ONLINE) { $url = 'https://center-test.kingsome.cn/api/replays/'; } else { $url = 'https://center.kingsome.cn/api/replays/'; } $url .= $gameid . '/' . $condition; $response = ''; $params = array(); if (!phpcommon\HttpClient::get($url, $params ,$response)) { die(); return; } $ret = json_decode($response, true); if ($ret['errcode'] == 0) { return $ret['items']; } else { die(); return; } } private function sendAwardMail($accountid, $config) { if (SERVER_ENV != _ONLINE) { $url = 'https://gamemail-test.kingsome.cn/webapp/index.php?'; } else { $url = 'https://gamemail.kingsome.cn/webapp/index.php?'; } $attachments = ''; foreach ($config as $attachment) { $attachments .= $attachment['item_id'] . ':' . $attachment['count'] . ';'; } $response = ''; if (!phpcommon\HttpClient::get($url, array( 'c' => 'Mail', 'a' => 'sendMail', 'to' => $accountid, 'game_id' => phpcommon\extractGameId($accountid), 'from' => '客服', 'mail_type' => '1', 'mail_subtype' => '0', 'subject' => '领奖', 'content' => '领取奖励', 'sendtime' => time(), 'ext' => '', 'expire_time' => time() + 3600 * 24, 'attachments' => $this->translateAttachments($config) ), $response)) { return false; } $data = json_decode($response, true); return $data && $data['errcode'] == 0; } public function checkServer() // 校验服务器地址URL { $gameid = $_REQUEST['gameid']; $config_name = "../config/game$gameid/weixin/config.php"; require $config_name; if (isset($_REQUEST['echostr'])) { if ($this->checkSignature()) { echo $_REQUEST['echostr']; } else { echo 'signature error'; } die(); return; } $msg_str = ''; $pc = new WXBizMsgCrypt(WEIXIN_TOKEN, WEIXIN_MSG_KEY, WEIXIN_APP_ID); $errcode = $pc->decryptJsonMsg($_REQUEST['msg_signature'], $_REQUEST['timestamp'], $_REQUEST['nonce'], file_get_contents('php://input'), $msg_str); if ($errcode == 0) { $msg = json_decode($msg_str, true); $accountid = phpcommon\createAccountId(WEIXIN_CHANNEL, $_REQUEST['gameid'], $msg['FromUserName']); switch ($msg['MsgType']) { case 'text': { // 文本消息 $this->processText($msg, $accountid); break; } case 'image': { // 图文消息 $this->processImage($msg, $accountid); break; } case 'event': { // 进入客服动作 $this->processEvent($msg, $accountid); break; } } } else { #error_log($errcode . "\n"); } } public function sendMsgAllUser() { error_log('sendMsgAllUser:'); error_log('request:' . json_encode($_REQUEST)); if (phpcommon\md5Sign(array ( 'exclude_accountids' => $_REQUEST['key'] ), 'fc38349c5d084e920925e614c420be9f', $_REQUEST['timestamp'] ) != $_REQUEST['sign']) { echo json_encode(array( 'errcode' => 100, 'errmsg' => '签名错误', )); return; } $mysqls = $this->getAllMysql(); foreach($mysqls as $mysql_conf) { $conn = $this->getAppointMysql($mysql_conf); $minIdx = 10000; $maxIdx = $this->getAwardDBMaxIdx($conn); $this->sendOneDBInfo($minIdx, $maxIdx, $conn); } } private function checkSignature() { $signature = $_REQUEST["signature"]; $timestamp = $_REQUEST["timestamp"]; $nonce = $_REQUEST["nonce"]; $token = WEIXIN_TOKEN; $tmpArr = array ($token, $timestamp, $nonce); sort($tmpArr , SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr == $signature){ return true; } else { return false; } } private function encryptJson() { $pc = new WXBizMsgCrypt(WEIXIN_TOKEN, WEIXIN_MSG_KEY, WEIXIN_APP_ID); $encryptMsg = ''; $text = $postStr; $errcode = $pc->encryptJsonMsg($text, $timeStamp, $nonce, $encryptMsg_str); if ($errcode == 0) { $encryptMsg = json_decode($encryptMsg_str, true); $errcode = $pc->decryptJsonMsg($encryptMsg['MsgSignature'], $timeStamp, $nonce, $encryptMsg_str, $postStr2); } else { } } private function sendMsg($accountid, $data) { $postarray = json_encode($data, JSON_UNESCAPED_UNICODE); //POST发送https请求客服接口api $access_token = $this->getAccessToken($accountid); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=$access_token"; $response = ''; if (!phpcommon\HttpClient::post($url, $postarray, $response)) { phpcommon\sendError(ERR_RETRY, '系统繁忙'); return; } $ret_info = json_decode($response, true); #error_log('sendMsgRet:' . $response); if ($ret_info['errcode'] == 0) { } else { #error_log('sendMsg发送失败!'); echo(0); } } private function sendMsgSomeUser($arrayInfo) { foreach($arrayInfo as $userInfo) { $shareInfo = require('../config/kefu.share.config.php'); $miniprogrampateInfo = $shareInfo['1011']; $data = array ( "touser" => $userInfo['openid'], "msgtype" => "miniprogrampage", "miniprogrampage" => $miniprogrampateInfo ); $this->sendMsg($userInfo['accountid'], $data); } } private function sendOneDBInfo($minIdx, $maxIdx, $conn) { $selectOneCount = 20; $selectCount = $maxIdx - $minIdx; $selectTimes = ceil($selectCount / $selectOneCount); #error_log('selectCount:' . $selectCount); #error_log('selectTimes:' . $selectTimes); $selectMin = $minIdx; for ($i = 0; $i < $selectTimes; $i++ ) { #error_log('selectMin:' . $selectMin); $arrayInfo = $this->getAccountsKefuInfo($selectMin, $selectMin + $selectOneCount, $conn); $this->sendMsgSomeUser($arrayInfo); $selectMin = $selectMin + $selectOneCount; } } private function processText($msg, $accountid) { $openid = $msg['FromUserName']; $CreateTime = $msg['CreateTime']; $text = $msg['Content']; $gameid = phpcommon\extractGameId($accountid); $awardConfig = $this->getAwardConfig($gameid, $text); if (!isset($awardConfig)) { $this->sendMsg($accountid, array ( "touser" => $openid, "msgtype" => "text", "text" => array ("content" => '回复指定文字领取奖励!') )); return; } $conn = $this->getMysql($accountid); $row = $conn->execQueryOne('SELECT awardtime ' . "FROM accounts_kefu WHERE accountid = :accountid;", array( ':accountid' => $accountid, )); if ($row && time() - $row['awardtime'] < 3600 * 24) { $this->sendMsg($accountid, array ( "touser" => $openid, "msgtype" => "text", "text" => array ("content" => "一天内只能领取一次奖励!\n请明天再来!") )); return; } if ($this->sendAwardMail($accountid, $awardConfig)) { $ret = $conn->execScript("UPDATE accounts_kefu SET " . ' awardtime=:awardtime ' . 'WHERE accountid=:accountid; ', array( ':accountid' => $accountid, ':awardtime' => time() )); if ($ret) { $this->sendMsg($accountid, array ( "touser" => $openid, "msgtype" => "text", "text" => array ("content" => '奖励领取成功,请查收邮件!') )); } } } private function processImage($msg, $accountid) { die('not implement'); } private function processEvent($msg, $accountid) { if ($msg['Event'] == 'user_enter_tempsession') { $conn = $this->getMysql($accountid); $ret = $conn->execScript('INSERT INTO accounts_kefu(accountid, channel, gameid, openid, awardtime) ' . 'SELECT :accountid, :channel, :gameid, :openid, :awardtime ' . 'FROM accounts_kefu ' . 'WHERE NOT EXISTS(SELECT accountid FROM accounts_kefu WHERE accoutid=:accountid);', array( ':accountid' => $accountid, ':channel' => WEIXIN_CHANNEL, ':gameid' => phpcommon\extractGameId($accountid), ':openid' => $msg['FromUserName'], ':awardtime' => 0 )); if ($ret) { $this->sendMsg($accountid, array( "touser" => $msg['FromUserName'], "msgtype" => "text", "text" => array("content" => "您好,有什么能帮助你? \n回复指定文字领取奖励。 ") )); } } } private function getAccessToken($accountid) { $r = $this->getRedis($accountid); $access_token = $r->get('kf_token:' . $accountid . ':'); if (!empty($access_token)) { return $access_token; } else { $gameid = phpcommon\extractGameId($accountid); $config_name = "../config/game$gameid/weixin/config.php"; @require $config_name; $appid = WEIXIN_APP_ID; $appkey = WEIXIN_APP_SECRET; $url = "https://api.weixin.qq.com/cgi-bin/token?" . "grant_type=client_credential&appid=$appid&secret=$appkey"; $params = array(); $response = ''; if (!phpcommon\HttpClient::get($url, $params, $response)) { phpcommon\sendError(ERR_INTERNAL, '系统繁忙'); return; } #error_log('response_token:' . $response); $res = json_decode($response, true); if ( isset($res['access_token']) ) { //刚获取的token放到redis中 //微信限制过期时间为两小时 $r->set('kf_token:' . $accountid . ':', $res['access_token']); $r->pexpire('kf_token:' . $accountid . ':', 1000 * ($res['expires_in'] - 60 * 1)); return $res['access_token']; } else { die(); } } } }