kefu/webapp/controller/KefuController.class.php
2020-05-21 10:06:22 +08:00

474 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
include_once "endecrypt/wxBizMsgCrypt.php";
class KefuController {
protected function getRedis($accountid)
{
$redis_conf = getRedisConfig(crc32($accountid));
$r = new phpcommon\Redis(array(
'host' => $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' . $mysql_conf['instance_id']
));
return $conn;
}
private function translateAttachments($config)
{
$attachments = '';
foreach ($config as $attachment) {
$attachments .= $attachment['item_id'] . ':' . $attachment['count'] . ';';
}
return $attachments;
}
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;
}
error_log($response);
$ret = json_decode($response, true);
if ($ret['errcode'] == 0) {
if ($gameid >= 2001 && $gameid < 3000) {
if (count($ret['items']) > 0) {
$item = $ret['items'][rand() % count($ret['items'])];
error_log(json_encode($item));
return array($item);
} else {
return $ret['items'];
}
} else {
return $ret['items'];
}
} else {
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 = '';
error_log(time());
foreach ($config as $attachment) {
$attachments .= $attachment['item_id'] . ':' . $attachment['count'] . ';';
}
$params = array(
'to' => $accountid,
'gameid' => phpcommon\extractGameId($accountid),
'from' => '客服',
'mailtype' => 1,
'mailsubtype' => 0,
'subject' => '领奖',
'content' => '领取奖励',
'sendtime' => time(),
'ext' => '',
'expiretime' => time() + 3600 * 24,
'attachments' => $this->translateAttachments($config)
);
$params['c'] = 'MailMgr';
$params['a'] = 'sendMail';
$params['timestamp'] = time();
$params['sign'] = phpcommon\md5Sign($params, '14e1b600b1fd579f47433b88e8d85291', $params['timestamp']);
$response = '';
if (!phpcommon\HttpClient::get($url,
$params,
$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);
error_log(json_encode($msg));
$accountid = phpcommon\createAccountId(WEIXIN_CHANNEL, $_REQUEST['gameid'], $msg['FromUserName']);
switch ($msg['MsgType']) {
case 'event':
{
// 进入客服动作
$this->processEvent($msg, $accountid);
break;
}
case 'text':
{
// 文本消息
$this->processText($msg, $accountid);
break;
}
case 'image':
{
// 图文消息
die('not implement');
break;
}
case 'miniprogrampage':
{
// 小程序消息
$this->processText($msg, $accountid);
break;
}
}
} else {
#error_log($errcode . "\n");
}
}
public function notifyAllUser()
{
error_log('notifyAllUser');
set_time_limit(1800);
$media_conf = array();
$dbconfs = require('../config/kefu.mysql.cluster.php');;
foreach($dbconfs as $dbconf) {
$conn = new phpcommon\Mysql(array(
'host' => $dbconf['host'],
'port' => $dbconf['port'],
'user' => $dbconf['user'],
'passwd' => $dbconf['passwd'],
'dbname' => 'kefudb' . $dbconf['instance_id']
));
$this->sendOneDBInfo($conn, $media_conf);
}
echo json_encode(array(
'errcode' => 0,
'errmsg' => '',
));
}
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;
}
}
protected function delOvertimeOpenid($accountid)
{
$conn = $this->getMysql($accountid);
error_log('del:' . $accountid);
$ret = $conn->execScript('DELETE FROM accounts ' .
'WHERE accountid=:accountid;',
array(
':accountid' => $accountid,
));
}
private function sendKefuMsg($accountid, $data)
{
try {
$gameid = phpcommon\extractGameId($accountid);
$access_token = $this->getAccessToken($gameid);
error_log($access_token);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . urlencode($access_token);
$response = '';
error_log('kefu_openid');
error_log(json_encode($data, JSON_UNESCAPED_UNICODE));
if (!phpcommon\HttpClient::post($url,
json_encode($data, JSON_UNESCAPED_UNICODE),
$response)
) {
phpcommon\sendError(ERR_RETRY, '系统繁忙');
return;
}
$ret_info = json_decode($response, true);
error_log(json_encode($response));
if (isset($ret_info['errcode']) && ($ret_info['errcode'] == 40001 || $ret_info['errcode'] == 40003 || $ret_info['errcode'] == 41001)) {
if ($ret_info['errcode'] == 40003) {
//无效的openid更换appid appkey导致之前的openid失效
//从db里删除这种过期的openid
$this->delOvertimeOpenid($accountid);
return true;
}
error_log('重新获取access_token');
$r = $this->getRedis($gameid);
$r->del('kf_token:' . $gameid . ':');
$access_token = $this->getAccessToken($gameid);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=". urlencode($access_token);
$response = '';
error_log(json_encode($data, JSON_UNESCAPED_UNICODE));
if (!phpcommon\HttpClient::post($url,
json_encode($data, JSON_UNESCAPED_UNICODE),
$response)
) {
phpcommon\sendError(ERR_RETRY, '系统繁忙');
return;
}
error_log('retry:' . $response);
$ret_info = json_decode($response, true);
}
return !empty($ret_info) && $ret_info['errcode'] == 0;
} catch (Exception $e) {
error_log($e->getMessage());
return false;
}
}
private function sendOneDBInfo($conn, &$media_conf)
{
$last_idx = 0;
$share_conf = require('../config/kefu.share.config.php');
while (true) {
$rows = $conn->execQuery('SELECT idx, accountid, openid, awardtime, gameid, activetime ' .
' FROM accounts WHERE activetime > :time AND idx > :last_idx LIMIT 0, 1000;',
array(
':last_idx' => $last_idx,
':time' => time() - 3600 * 6
));
if (!$rows || count($rows) <= 0) {
break;
}
foreach ($rows as $row) {
if (isset($share_conf[$row['gameid']])) {
$game_conf = $share_conf[$row['gameid']];
if (!isset($media_conf[$row['gameid']])) {
$media_conf[$row['gameid']] = $this->getMediaId($row['gameid']);
}
$game_conf['thumb_media_id'] = $media_conf[$row['gameid']];
$this->sendKefuMsg($row['accountid'],
array (
"touser" => $row['openid'],
"msgtype" => "miniprogrampage",
"miniprogrampage" => $game_conf
));
}
if ($row['idx'] > $last_idx) {
$last_idx = $row['idx'];
}
}
}
}
private function processText($msg, $accountid)
{
$this->createUser($accountid);
$openid = $msg['FromUserName'];
$CreateTime = $msg['CreateTime'];
//$text = $msg['Content'];
$text = '';
$gameid = phpcommon\extractGameId($accountid);
if (strcmp($msg['MsgType'], 'miniprogrampage') == 0) {
$text = 1;
} else {
$text = $msg['Content'];
}
//error_log(json_encode($gameid));
$awardConfig = $this->getAwardConfig($gameid, $text);
if (!isset($awardConfig)) {
$this->sendKefuMsg($accountid, array (
"touser" => $openid,
"msgtype" => "text",
"text" => array ("content" => '回复指定文字领取奖励!')
));
return;
}
$conn = $this->getMysql($accountid);
$row = $conn->execQueryOne('SELECT awardtime, activetime ' .
' FROM accounts WHERE accountid = :accountid;',
array(
':accountid' => $accountid,
));
if (!$row) {
$this->sendKefuMsg($accountid, array (
"touser" => $openid,
"msgtype" => "text",
"text" => array ("content" => "请从游戏进入客服!")
));
return;
}
date_default_timezone_set('Asia/Shanghai');
if ($row && date("y-m-d", time()) == date("y-m-d", $row['awardtime'])) {
$this->sendKefuMsg($accountid, array (
"touser" => $openid,
"msgtype" => "text",
"text" => array ("content" => "一天内只能领取一次奖励!\n请明天再来!"),
));
return;
}
$this->updateActiveTime($conn, $accountid);
if ($this->sendAwardMail($accountid, $awardConfig)) {
$ret = $conn->execScript('UPDATE accounts SET ' .
' awardtime=:awardtime ' .
' WHERE accountid=:accountid; ',
array(
':accountid' => $accountid,
':awardtime' => time(),
));
if ($ret) {
$this->sendKefuMsg($accountid, array (
"touser" => $openid,
"msgtype" => "text",
"text" => array ("content" => '奖励已发放,请返回游戏领取!')
));
}
}
}
private function processEvent($msg, $accountid)
{
if ($msg['Event'] == 'user_enter_tempsession') {
$this->createUser($accountid);
}
}
private function createUser($accountid) {
$conn = $this->getMysql($accountid);
$ret = $conn->execScript('INSERT INTO accounts(accountid, channel, gameid, openid, awardtime, activetime) ' .
'SELECT :accountid, :channel, :gameid, :openid, :awardtime, :activetime ' .
'FROM DUAL ' .
'WHERE NOT EXISTS(SELECT accountid FROM accounts WHERE accountid=:accountid);',
array(
':accountid' => $accountid,
':channel' => WEIXIN_CHANNEL,
':gameid' => phpcommon\extractGameId($accountid),
':openid' => phpcommon\extractOpenId($accountid),
':awardtime' => 0,
':activetime' => 0
));
/*if ($ret) {
$this->sendKefuMsg($accountid, array(
"touser" => $msg['FromUserName'],
"msgtype" => "text",
//"text" => array("content" => "您好,有什么能帮助你? \n ")
));
}*/
}
private function getAccessToken($gameid)
{
$r = $this->getRedis($gameid);
$access_token = $r->get('kf_token:' . $gameid . ':');
if (!empty($access_token)) {
return $access_token;
}
$config_name = "../config/game$gameid/weixin/config.php";
require $config_name;
echo('zzz4');
$response = '';
if (!phpcommon\HttpClient::get('https://api.weixin.qq.com/cgi-bin/token',
array(
'grant_type' => 'client_credential',
'appid' => WEIXIN_APP_ID,
'secret' => WEIXIN_APP_SECRET
),
$response)) {
phpcommon\sendError(ERR_INTERNAL, '系统繁忙');
return;
}
$respobj = json_decode($response, true);
if (isset($respobj['access_token'])) {
$r->set('kf_token:' . $gameid . ':', $respobj['access_token']);
$r->pexpire('kf_token:' . $gameid . ':', 1000 * ($respobj['expires_in'] - 60 * 1));
return $respobj['access_token'];
} else {
error_log('getAccessToken:' . $response);
return '';
}
}
private function getMediaId($gameid)
{
error_log('getMediaId ' . $gameid);
$type = "image";
$filepath = "../config/game$gameid/share.png";
$filedata = array(
"media" => "@" . $filepath
);
$access_token = $this->getAccessToken($gameid);
$url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=$access_token&type=$type";
$response = '';
if (phpcommon\HttpClient::upload($url, $filedata, $response)) {
error_log('getMediaId ' . $response);
$jsonobj = json_decode($response, true);
if(isset($jsonobj['media_id'])) {
return $jsonobj['media_id'];
} else {
return '';
}
} else {
return '';
}
}
protected function updateActiveTime($conn, $accountid)
{
$ret = $conn->execScript('UPDATE accounts SET ' .
' activetime=:activetime ' .
' WHERE accountid=:accountid; ',
array(
':accountid' => $accountid,
':activetime' => time()
));
}
}