1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240 |
- <?php
- /**
- * Created by PhpStorm.
- * User: Bear
- * Date: 2018/11/29
- * Time: 上午10:20
- */
- namespace app\main\service;
- use app\api\library\ReplayTemplate;
- use app\common\library\Ip;
- use app\common\service\SendChannelMsgService;
- use app\common\service\ShareService;
- use app\common\library\Redis;
- use app\common\library\WeChatObject;
- use app\common\service\ActiveShareService;
- use app\common\service\UserVipExtendService;
- use app\common\service\WaterBookService;
- use app\main\constants\CacheConstants;
- use app\main\constants\ErrorCodeConstants;
- use app\main\constants\KafkaDotConstants;
- use app\main\constants\MarkConstants;
- use app\main\constants\MessageConstants;
- use app\main\constants\MqConstants;
- use app\main\constants\OpenPlatformConstants;
- use app\main\constants\UserConstants;
- use app\main\helper\StringHelper;
- use app\main\model\object\AdminConfigObject;
- use app\main\model\object\AnalysisObject;
- use app\main\model\object\DotObject;
- use app\main\model\object\EventObject;
- use app\main\model\object\ReplyMsgObject;
- use app\main\model\object\ReturnObject;
- use app\main\model\object\UserObject;
- use EasyWeChat\Kernel\Messages\Image;
- use EasyWeChat\Kernel\Messages\News;
- use EasyWeChat\Kernel\Messages\NewsItem;
- use EasyWeChat\Kernel\Messages\Text;
- use GuzzleHttp\Client;
- use think\Config;
- use think\Exception;
- use think\Log;
- use think\Model;
- use think\Request;
- use function GuzzleHttp\Psr7\parse_query;
- /**
- * 处理公众号事件信息
- * Class OfficialAccountsEventService
- * @package app\main\service
- */
- class OfficialAccountsEventService extends BaseService
- {
- /**
- * @var OfficialAccountsEventService
- */
- protected static $self = NULL;
- /**
- * @var EventObject
- */
- private $wechatMsg;
- /**
- * @return OfficialAccountsEventService
- */
- public static function instance()
- {
- if (self::$self == NULL) {
- self::$self = new self();
- }
- return self::$self;
- }
- /**
- * 订阅号事件管理
- * @param $appId
- * @return \app\main\model\object\ReturnObject
- */
- public function eventForSubscription($appId)
- {
- try {
- $subscription = OfficialAccountsService::instance()->getSubscriptionModel()->getSubscriptionByAppId($appId);
- if (!$subscription || empty($subscription['refresh_token'])) {
- $msg = '[ WeChat ] [ Subscription ] [ API ] error: AppId:' . $appId . ' refresh_token or subscription info get fail';
- return $this->setCode(ErrorCodeConstants::DB_ERROR_SELECT)->setMsg($msg)->getReturn();
- }
- $refresh_token = $subscription['refresh_token'];
- LogService::debug("Subscription Get OfficialAccount Appid:{$appId} RefreshToken:{$refresh_token}");
- $officialAccount = OpenPlatformService::instance()->getOfficialAccount($appId, $refresh_token);
- $officialAccount->server->push(function ($message) use ($officialAccount, $subscription) {
- $time = Request::instance()->server('REQUEST_TIME');
- LogService::info('[ WeChat ] [ MP ] [ API ] Message: ' . json_encode(var_export($message, true), JSON_UNESCAPED_UNICODE));
- //订阅号交互管理
- if (isset($message['Event']) && $message['Event'] == 'unsubscribe') {
- //取消关注
- OfficialAccountsService::instance()->getSubscriptionFansModel()->setConnect($subscription['id'], $message['FromUserName'])->unsubscribe($time);
- } else {
- //添加用户Fans
- OfficialAccountsService::instance()->getSubscriptionFansModel()->setConnect($subscription['id'], $message['FromUserName'])->createFans($officialAccount, $time);
- }
- //更新粉丝的交互时间
- OfficialAccountsService::instance()->getSubscriptionFansModel()->setConnect($subscription['id'], $message['FromUserName'])->updateOperateTime();
- //消息回复
- switch ($message['MsgType']) {
- case 'text':
- if ($message['Content'] == '$openid$') {
- return $message['FromUserName'];
- }
- if ($message['Content'] == '$userid$') {
- $userId = OfficialAccountsService::instance()->getSubscriptionFansModel()->setConnect($subscription['id'], $message['FromUserName'])->getFansId();
- return new Text($userId);
- }
- break;
- }
- return false;
- });
- $officialAccount->server->serve()->send();
- return $this->getReturn();
- } catch (\Exception $e) {
- return $this->getExceptionReturn($e);
- }
- }
- /**
- * 全网发布事件
- * @param $appId
- * @return \app\main\model\object\ReturnObject
- */
- public function eventForAllNet($appId)
- {
- try {
- $server = OpenPlatformService::instance()->getOfficialAccount($appId)->server;
- $server->push(function ($message) {
- $messageObject = (new EventObject())->bind($message);
- LogService::info('[ WeChat ] [ MP ] [ API ] Message: ' . $messageObject->toJson());
- switch ($messageObject->MsgType) {
- case MessageConstants::MESSAGE_TYPE_EVENT:
- if (in_array($messageObject->ToUserName, OpenPlatformConstants::$event_callback_user)) {
- return $messageObject->Event . 'from_callback';
- }
- break;
- case MessageConstants::MESSAGE_TYPE_TEXT: // 文本
- if ($messageObject->Content == 'TESTCOMPONENT_MSG_TYPE_TEXT') {
- return 'TESTCOMPONENT_MSG_TYPE_TEXT_callback';
- }
- if (strpos($messageObject->Content, 'QUERY_AUTH_CODE:') === 0) {
- $query_auth_code = str_replace('QUERY_AUTH_CODE:', '', $messageObject->Content);
- LogService::info('[ WeChat ] [ MP ] [ API ] QUERY_AUTH_CODE: ' . json_encode(var_export($query_auth_code,
- true), JSON_UNESCAPED_UNICODE));
- $auth = OpenPlatformService::instance()->openPlatform->handleAuthorize($query_auth_code); // 使用授权码换取接口调用凭据和授权信息
- LogService::info('[ WeChat ] [ MP ] [ API ] AUTH: ' . json_encode(var_export($auth, true),
- JSON_UNESCAPED_UNICODE));
- $app = OpenPlatformService::instance()->getOpenPlatform()->officialAccount($auth['authorization_info']['authorizer_appid'],
- $auth['authorization_info']['authorizer_refresh_token']);
- $app->customer_service
- ->message(new Text($query_auth_code . '_from_api'))
- ->to($messageObject->FromUserName)
- ->send();
- }
- break;
- default:
- break;
- }
- return true;
- });
- $server->serve()->send();
- return $this->getReturn();
- } catch (\Exception $e) {
- return $this->getExceptionReturn($e);
- }
- }
- /**
- * 检查平台id有效性
- * @param $platform_id
- * @return ReturnObject
- */
- public function checkOphostLegal($platform_id)
- {
- $sourceDomain = UrlService::instance()->getSourceDomain();
- //检测是否是用户默认平台
- $ophost = OfficialAccountsService::instance()->getOphostModel()->getInfoByHost($sourceDomain);
- if ($ophost) {
- //非法用户判断
- if (isset($ophost['platform_id']) && $platform_id != $ophost['platform_id']) {
- return $this->setData(false)->getReturn();
- }
- } else {
- return $this->setData(false)->getReturn();
- }
- return $this->setData(true)->getReturn();
- }
- /**
- * @param $appId
- * @return \app\main\model\object\ReturnObject
- */
- public function eventForNormal($appId)
- {
- try {
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($appId);
- if (!$adminConfig) {
- $this->setLimitCache($appId);
- return $this->setMsg('渠道信息无效!' . $appId)->getReturn();
- }
- $adminConfigObject = (new AdminConfigObject())->bind($adminConfig);
- //检测平台有效性
- if (!$this->checkOphostLegal($adminConfigObject->platform_id)->data) {
- return $this->setMsg('平台无效!' . $adminConfigObject->platform_id)->getReturn();
- }
- $refreshToken = OpenPlatformService::instance()->getRefreshToken($adminConfigObject->admin_id);
- $server = OpenPlatformService::instance()->getOfficialAccount($appId, $refreshToken)->server;
- $server->push(function ($message) use ($adminConfigObject) {
- $messageObject = (new EventObject())->bind($message);
- $this->wechatMsg = $messageObject;
- return $this->eventCallBack($messageObject, $adminConfigObject)->data;
- });
- $server->serve()->send();
- if ($this->wechatMsg->MsgType == MessageConstants::MESSAGE_TYPE_EVENT) {
- Log::info("EVENT_ANALYSIS:" . $this->wechatMsg->Event . "-" . $adminConfigObject->admin_id . ",time:" . (microtime(true) - THINK_START_TIME));
- }
- return $this->getReturn();
- } catch (\Exception $e) {
- return $this->getExceptionReturn($e);
- }
- }
- /**
- * 用户注册回调
- */
- public function processCallbackUserInfo($appId)
- {
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($appId);
- if ($adminConfig) {
- $list = Redis::instance()->hGet("callback_user", $adminConfig['admin_id']);
- Redis::instance()->hDel('callback_user', $adminConfig['admin_id']);
- if ($list) {
- $list = json_decode($list, true);
- foreach ($list as $message) {
- $channel_id = $adminConfig['admin_id'];
- $messageObj = (new EventObject())->bind($message);
- $userId = UserService::instance()->weChatInsertUser($channel_id, $messageObj->FromUserName)->data;
- if ($userId) {
- $cacheKey = CacheConstants::getQrcodeVisitCache($messageObj->FromUserName);
- if ($id = Redis::instance()->get($cacheKey)) {
- $oAna = new AnalysisObject();
- $oAna->type = KafkaDotConstants::TYPE_VISIT;
- $oAna->event_time = Request::instance()->server('REQUEST_TIME');
- $oAna->user_from = [
- 'qrcode_id' => $id
- ];
- KafkaDotService::instance()->sendMsg($userId, $oAna);
- }
- switch ($messageObj->Event) {
- case MessageConstants::MESSAGE_EVENT_SUBSCRIBE:
- $this->callbackSubscribe($channel_id, $messageObj);
- break;
- case MessageConstants::MESSAGE_EVENT_CLICK:
- if ($messageObj->EventKey == '签到') {
- $this->sendShareText($appId, $channel_id, $messageObj->FromUserName);
- } else{
- $this->sendText($appId, $channel_id, $messageObj->FromUserName);
- }
- break;
- }
- //更新用户交互时间
- UserService::instance()->updateUserOperateTime($userId, $messageObj->Event);
- }
- }
- }
- }
- }
- public function sendText($appId, $channel_id, $openid)
- {
- //如果Channel_id 是二维码图片菜单,则,查询回复的内容文字
- $adminInfo = AdminService::instance()->getAdminConfigModel()->getAdminInfoAll($channel_id);
- if($adminInfo['is_qrcode_menu'] == '1'){
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($appId);
- $wechat = new WeChatObject($adminConfig);
- $officialAccount = $wechat->getOfficialAccount();
- $event_key = $this->wechatMsg->EventKey;
- $result = OfficialAccountsService::instance()->getWechatResponseModel()->where([
- 'admin_id' => $channel_id,
- 'eventkey' => $event_key,
- 'status' => 'normal',
- ])->find();
- // 点击菜单'联系客服'时,event_key='manager_contact',此时$result=null
- if ($result) {
- $text = '请点击图片,长按识别二维码,进入[' . $result->title . ']';
- //调用客服消息
- $news = new Text($text);
- $officialAccount->customer_service
- ->message($news)
- ->to($openid)
- ->send();
- }
- }
- }
- /**
- * 关注事件的异步处理
- * @param $channel_id
- * @param EventObject $eventObject
- * @return bool
- */
- public function callbackSubscribe($channel_id, EventObject $eventObject)
- {
- $userId = OfficialAccountsService::instance()->getOpenidModel()->getUserId($channel_id, $eventObject->FromUserName);
- $userKey = CacheConstants::getUserCacheKey($userId);
- $redis = Redis::instance();
- $request_time = Request::instance()->server('REQUEST_TIME');
- try {
- /*
- * php打点,关注
- */
- $wechat = OpenPlatformService::instance()->officialAccount;
- $wechat->http_client = new Client(Config::get('wechat.http'));
- $wechatUser = $wechat->user->get($eventObject->FromUserName); //获取微信用户
- if (array_key_exists('errcode', $wechatUser)) {
- LogService::notice("获取微信用户失败:" . json_encode($wechatUser));
- return false;
- }
- $updateData = new UserObject();
- $updateData->is_subscribe = UserConstants::USER_IS_SUBSCRIBE_YES;
- $updateData->avatar = $wechatUser['headimgurl'];
- $updateData->nickname = $wechatUser['nickname'];
- $updateData->sex = $wechatUser['sex'];
- $updateData->subscribe_time = $request_time;
- if ($userId) { //判断是否有此用户
- $oldUser = UserService::instance()->getUserModel()->getUserInfo($userId);
- //用户关注推广链接为空时,更新用户关注推广链接
- $user_follow_referral_id = $oldUser['follow_referral_id'] ?? null;
- $referral_id = $oldUser['referral_id'];
- if(!$user_follow_referral_id && $referral_id){
- $updateData->follow_referral_id = $referral_id;
- $user_follow_referral_id = $referral_id;
- }
- $oldFollowTime = $oldUser['subscribe_time'];
- $res = UserService::instance()->update($updateData->toArray(), ['id' => $userId]); //更新关注状态 关注时间 昵称 头像等
- if ($redis->exists($userKey)) {
- $redis->hmset($userKey, $updateData->toArray());
- $redis->expire($userKey, 86400);
- }
- $dotData = new DotObject();
- //打点信息初始化
- $dotData->channel_id = $channel_id;
- $dotData->user_id = $userId;
- $dotData->event_time = $request_time;;
- $dotData->is_first_follow = UserConstants::USER_IS_FIRST_FOLLOW_YES;
- //新增关注用户统计
- if ($oldUser && $res) {
- if ($oldUser['is_first_unfollow'] != UserConstants::USER_IS_FIRST_UNFOLLOW_NEVER) {
- $dotData->is_first_follow = UserConstants::USER_IS_FIRST_FOLLOW_NO;
- }
- //新增性别打点
- if ($oldUser['sex'] == UserConstants::USER_SEX_UNKNOWN && $updateData->sex) {
- //性别变更多打一次点
- $oSexAna = new AnalysisObject();
- $oSexAna->event_time = $request_time;
- $oSexAna->data['sex'] = $updateData->sex;
- $oSexAna->data['user_collect'] = 1;
- $oSexAna->type = KafkaDotConstants::TYPE_SEX;
- KafkaDotService::instance()->sendMsg($userId, $oSexAna);
- $newDotData = $dotData;
- $newDotData->sex = $updateData->sex;
- $newDotData->action_type = MqConstants::ROUTING_KEY_SUBSCRIBE;
- $newDotData->type = MqConstants::MSG_TYPE_SEX;
- MqService::instance()->sendMessage($dotData);
- }
- }
- $dotData->action_type = MqConstants::ROUTING_KEY_SUBSCRIBE;
- $dotData->type = MqConstants::MSG_TYPE_FOLLOW;
- MqService::instance()->sendMessage($dotData);
- $oAna = new AnalysisObject();
- $oAna->event_time = $request_time;
- $oAna->type = [KafkaDotConstants::TYPE_SUBSCRIBE];
- //php打点推广链接关注,以第一次关注推广链接为准
- if ($user_follow_referral_id) {
- $oAna->user_from = [
- 'referral_id' => $user_follow_referral_id
- ];
- $dotData->action_type = MqConstants::ROUTING_KEY_SUBSCRIBE_REFERER;
- $dotData->referral_id = $user_follow_referral_id;
- MqService::instance()->sendMessage($dotData);
- }
- $oAna->data['user_collect'] = 1;
- KafkaDotService::instance()->sendMsg($userId, $oAna);
- if ($oldUser['is_first_unfollow'] == 2 && Config::get('site.is_open_share') == "1"){//判断是不是分享链接的用户 && 分享活动开关配置为开
- ShareService::instance()->attentionUser($userId,$wechatUser);
- }
- if ($oldFollowTime == 0 && $referral_id) {
- //首次关注回源
- $url = getCurrentDomain($channel_id,"/t/{$referral_id}");
- ReferralService::instance()->sendReferralAdData($referral_id, ['admin_id' => $channel_id, 'url' => $url, 'sub' => ['productName' => "关注"], 'openid' => $oldUser['openid']]);
- }
- }
- } catch (\Exception $exception) {
- LogService::exception($exception);
- if ($userId) {
- $upUserData = ['is_subscribe' => UserConstants::USER_IS_SUBSCRIBE_YES, 'subscribe_time' => $request_time];
- UserService::instance()->update($upUserData, ['id' => $userId]);
- if ($redis->exists($userKey)) {
- $redis->hmset($userKey, $upUserData);
- $redis->expire($userKey, 86400);
- }
- }
- }
- }
- /**
- * 更新模板回调缓存
- * @param $appid
- */
- public function updateTplCallback($appid)
- {
- $cacheKey = "TPL_CALLBACK_" . $appid;
- Redis::instance()->incr($cacheKey);
- Redis::instance()->expire($cacheKey, Config::get("app_callback_tpl_cache"));
- if (Redis::instance()->get($cacheKey) >= Config::get("app_callback_tpl_threshold")) {
- $this->setLimitCache($appid);
- }
- }
- /**
- * 添加限制缓存
- * @param $appid
- */
- public function setLimitCache($appid)
- {
- LogService::info('appid limited:' . $appid);
- file_put_contents(sys_get_temp_dir() . '/TPL_CALLBACK_' . $appid, time());
- }
- /**
- * @param $messageObject EventObject
- * @param $adminConfigObject AdminConfigObject
- * @return \app\main\model\object\ReturnObject
- */
- public function eventCallBack($messageObject, $adminConfigObject)
- {
- try {
- LogService::info('[ WeChat ] [ MP ] [ API ] Message: ' . $messageObject->toJson());
- if ($messageObject->Event == 'MASSSENDJOBFINISH') {
- // 高级群发JOB推送
- SendChannelMsgService::instance()->saveSuccessCount($messageObject->MsgID, $messageObject->SentCount, $adminConfigObject->admin_id);
- }
- if ($messageObject->Event == 'TEMPLATESENDJOBFINISH') {
- $this->updateTplCallback($adminConfigObject->appid);
- return $this->setData('')->getReturn();
- }
- if (!$messageObject->FromUserName) {
- LogService::error("用户信息为空");
- return $this->setData('')->getReturn();
- }
- //将非取消关注的事件存入缓存
- if ($messageObject->Event != MessageConstants::MESSAGE_EVENT_UNSUBSCRIBE) {
- $data = $messageObject->toArray();
- $cache = Redis::instance()->hGet('callback_user', $adminConfigObject->admin_id);
- if ($cache) {
- $cache = json_decode($cache, true);
- $cache[] = $data;
- }else{
- $cache = [$data];
- }
- Redis::instance()->hSet("callback_user", $adminConfigObject->admin_id, json_encode($cache));
- }
- $replayData = false;
- switch ($messageObject->MsgType) {
- case MessageConstants::MESSAGE_TYPE_EVENT:
- switch ($messageObject->Event) {
- case MessageConstants::MESSAGE_EVENT_SCAN: //永久二维码已关注
- $replayData = $this->weChatPermanentQRCodeFollow($adminConfigObject, $messageObject, true);
- if (!$replayData) {
- $replayData = $this->getSubscribe($adminConfigObject->admin_id, $messageObject->FromUserName);
- }
- break;
- case MessageConstants::MESSAGE_EVENT_SUBSCRIBE: // 关注
- $replayData = $this->eventSubscribe($adminConfigObject, $messageObject);
- break;
- case MessageConstants::MESSAGE_EVENT_UNSUBSCRIBE: // 取消关注
- //取消订阅不需要回复
- $this->eventUnsubscribe($adminConfigObject->admin_id, $messageObject->FromUserName);
- break;
- case MessageConstants::MESSAGE_EVENT_CLICK: //点击
- $replayData = $this->autoReply($messageObject->ToUserName, $messageObject->FromUserName, $messageObject->EventKey, MessageConstants::MESSAGE_TYPE_EVENT_YES);
- if ($replayData instanceof ReplyMsgObject && $replayData->msg_mark != MarkConstants::MARK_CLICK_INNER_KEYWORDS) {
- $replayData->msg_mark = MarkConstants::MARK_CLICK_PRE_RESOURCE;
- }
- break;
- }
- break;
- case MessageConstants::MESSAGE_TYPE_TEXT: // 文本
- $replayData = $this->eventText($messageObject, $adminConfigObject);
- break;
- }
- $replayData = $this->setMarkForReplyData($replayData, $messageObject)->data;
- return $this->setData($replayData)->getReturn();
- } catch (\Exception $e) {
- LogService::exception($e);
- return $this->setData('')->getReturn();
- }
- }
- /**
- * 添加打点内容
- * @param $data
- * @param EventObject $eventObject
- * @return ReturnObject|News|Text
- */
- public function setMarkForReplyData($data, EventObject $eventObject)
- {
- $appid = Request::instance()->param('appid');
- if (!($data instanceof ReplyMsgObject)) {
- return $this->setData($data)->getReturn();
- }else{
- LogService::debug("RESOURCE:".$data->toJson());
- }
- $push_id = '';
- if ($data->msg_mark == MarkConstants::MARK_QR_RESOURCE) {
- $push_id = (string)$eventObject->EventKey;
- }
- if ($data->push_id) {
- $push_id = (string)$data->push_id;
- }
- $push_time = time();
- $mark = $data->msg_mark;
- if ($data->msg_type == MarkConstants::MSG_TYPE_TEXT) {
- preg_match_all("<a href=['\"](.*?)['\"]>", $data->msg_content, $match);
- if ($match) {
- $replace = [];
- foreach ($match[1] as $index => $item) {
- $push_idx = $index + 1;
- $parse = parse_url($item);
- if (array_key_exists('host', $parse)) {
- if (preg_match('/^' . $appid . '/', $parse['host'])) {
- if (array_key_exists('query', $parse)) {
- $query = parse_query($parse['query']);
- if (array_key_exists('book_id', $query) && !$push_id) {
- $push_id = (string)$query['book_id'];
- }
- $item .= '&' . $this->processExt($mark, $push_id, $push_idx, $push_time);
- } else {
- $item .= '?' . $this->processExt($mark, $push_id, $push_idx, $push_time);
- }
- }
- }
- $replace[] = $item;
- }
- $data->msg_content = StringHelper::replaceOneByOne($data->msg_content, $match[1], $replace);
- //替换占位符
- if (strrpos($data->msg_content, '{ZHIDING}')) {
- $top = model('ManageKey')->getOneByKey('top');
- $data->msg_content = str_replace('{ZHIDING}', cdnurl($top['image']), $data->msg_content);
- }
- if (strrpos($data->msg_content, '{KANDIAN}')) {
- $kandian = Config::get('site.kandian_sign');
- $data->msg_content = str_replace('{KANDIAN}', $kandian, $data->msg_content);
- }
- }
- LogService::debug($data->msg_content);
- return $this->setData(new Text($data->msg_content))->getReturn();
- }
- if ($data->msg_type == MarkConstants::MSG_TYPE_NEWS) {
- $news = [];
- foreach ($data->msg_content as $index => $item) {
- $push_idx = $index + 1;
- $parse = parse_url($item['url']);
- if (array_key_exists('query', $parse)) {
- $query = parse_query($parse['query']);
- if (array_key_exists('book_id', $query) && !$push_id) {
- $push_id = (string)$query['book_id'];
- }
- $item['url'] .= '&' . $this->processExt($mark, $push_id, $push_idx, $push_time);
- } else {
- $item['url'] .= '?' . $this->processExt($mark, $push_id, $push_idx, $push_time);
- }
- $news[] = new NewsItem($item);
- }
- return $this->setData(new News($news))->getReturn();
- }
- return $this->setData($data)->getReturn();
- }
- public function processExt($mark, $push_id, $push_idx, $push_time)
- {
- $data = json_encode([
- 'mark' => $mark,
- 'push_id' => $push_id,
- 'push_idx' => $push_idx,
- 'push_time' => $push_time,
- ]);
- return 'ext=' . urlencode($data);
- }
- /**
- * @param EventObject $message
- * @param AdminConfigObject $adminConfig
- * @return bool|News|Text|string
- * @throws \Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function eventText(EventObject $message, AdminConfigObject $adminConfig)
- {
- $object = new ReplyMsgObject();
- /**
- * 自动回复处理
- */
- $autoReply = $this->autoReply($message->ToUserName, $message->FromUserName, $message->Content);
- if ($autoReply) {
- if ($autoReply instanceof ReplyMsgObject && $autoReply->msg_mark == MarkConstants::MARK_RESOURCE){
- $autoReply->msg_mark = MarkConstants::MARK_REPLY_PRE_RESOURCE;
- }
- return $autoReply;
- }
- if ($adminConfig->search_tip) {
- $uid = OfficialAccountsService::instance()->getOpenidModel()->getUserId($adminConfig->admin_id, $message->FromUserName);
- $channel_id = AdminService::instance()->getAdminExtendModel()->getChannelId($adminConfig->admin_id);
- $is_water = WaterBookService::instance()->showBook($channel_id, $uid);
- [$type, $books] = BookService::instance()->getWeinxinSearchBooks($message, $is_water,$adminConfig->admin_id);
- //查询到图书
- if ($books) {
- if ($type == 1) {
- //推荐 多本书 文字
- $content = "未找到您要查询的书籍,为您推荐:\r\n\r\n";
- foreach($books as $book){
- $url = getCurrentDomain($adminConfig->admin_id,'/index/book/chapter', ['book_id' => $book['id']]);
- $content .= "<a href='{$url}'>{$book['name']}</a>\r\n\r\n";
- }
- //新增一个最近阅读
- //$uid = OfficialAccountsService::instance()->getOpenidModel()->getUserId($adminConfig->admin_id, $message->FromUserName);
- if ($uid) {
- $soruceReadLog = BookService::instance()->getUserRecentlyRead()->setConnect($uid)->getRecentlyRead(0, 3, $uid, true);
- if ($soruceReadLog['totalNum'] > 0) {
- $book_info = current($soruceReadLog['data']);
- $cacheKey = CacheConstants::getBookSubCache($uid);
- //如果点下一章关注,阅读记录加一章
- if (Redis::instance()->get($cacheKey) == $book_info['book_id']) {
- $chapterInfo = BookService::instance()->getChapterInfo($book_info['book_id'], $book_info['chapter_id'] + 1)->data;
- BookService::instance()->setRecentlyRead($chapterInfo['name'], $chapterInfo['id'], $book_info['book_id'], $chapterInfo['idx'], $uid);
- $book_info['chapter_name'] = $chapterInfo['name'];
- }
- $recentBookUrl = getCurrentDomain($adminConfig->admin_id,'/index/book/chapter', ['book_id' => $book_info['book_id']]);
- $title = "阅读记录,你上次看到了\r\n《%s》 %s \r\n\r\n";
- $title = sprintf($title, $book_info['book_name'], $book_info['chapter_name']);
- $content.=$title;
- $content .= "<a href='{$recentBookUrl}'>".("【点此继续阅读】")."</a>";
- }
- }
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_SEARCH_BOOKS;
- $object->msg_content = $content;
- return $object;
- // return new Text($content);
- } else {
- //单本书图文
- $book = $books[0];
- $items = [];
- array_push($items,
- [
- 'title' => $book['name'],
- 'url' => getCurrentDomain($adminConfig->admin_id,'/index/book/chapter', ['book_id' => $book['id']]),
- 'image' => $book['image'],
- 'description' => $book['description'] ?? ''
- ]);
- $object->msg_type = MarkConstants::MSG_TYPE_NEWS;
- $object->msg_mark = MarkConstants::MARK_SEARCH_BOOKS;
- $object->msg_content = $items;
- return $object;
- // return new News($items);
- }
- }
- //未查询到结果的情况
- $content = BookService::instance()->getEventTextNoResult($adminConfig->admin_id);
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_SEARCH_NO_BOOKS;
- $object->msg_content = $content;
- return $object;
- // return $content;
- }
- return '';
- }
- /**
- * @param AdminConfigObject $adminConfig
- * @param EventObject $message
- * @param $userId
- * @return bool|Text
- * @throws \Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function eventSubscribe(AdminConfigObject $adminConfig, EventObject $message)
- {
- $countKey = 'SC:' . $adminConfig->admin_id . ':' . date('Ymd', time()); //记录当天该渠道商的导粉数量
- $resdata = Redis::instance()->incr($countKey);
- if ($resdata == 1) {
- Redis::instance()->expire($countKey, 86400); //设置失效时间为一天
- }
- $eventKey = explode('_', $message->EventKey);
- //检查是否是永久二维码关注
- if ($eventKey && $eventKey[0] == 'qrscene' && count($eventKey) == 2) {
- $message->EventKey = $eventKey[1];
- $replayData = $this->weChatPermanentQRCodeFollow($adminConfig, $message);
- if ($replayData) {
- return $replayData;
- }
- }
- //判断公众号是否关闭了自动回复
- $switch = AdminService::instance()->getSubscribeSwitchCache($adminConfig->admin_id);
- if (empty($switch) || $switch['status'] == 2) {
- return '';
- }
- return $this->autoReply($message->ToUserName, $message->FromUserName, $message->Event);
- }
- /**
- * 用户取消订阅
- * @param $channelId
- * @param $openid
- * @throws \Exception
- */
- public function eventUnsubscribe($channelId, $openid)
- {
- $userId = OfficialAccountsService::instance()->getOpenidModel()->getUserId($channelId, $openid);
- $userKey = CacheConstants::getUserCacheKey($userId);
- if ($userId) {
- $oldUser = UserService::instance()->getUserModel()->getUserInfo($userId);
- if (!$oldUser) {
- LogService::info('用户不存在');
- return;
- }
- $upUserData = [];
- if ($oldUser['is_first_unfollow']) {
- if ($oldUser['is_first_unfollow'] == UserConstants::USER_IS_FIRST_UNFOLLOW_NEVER) {
- $upUserData['is_first_unfollow'] = UserConstants::USER_IS_FIRST_UNFOLLOW_YES;
- } elseif ($oldUser['is_first_unfollow'] == UserConstants::USER_IS_FIRST_UNFOLLOW_YES) {
- $upUserData['is_first_unfollow'] = UserConstants::USER_IS_FIRST_UNFOLLOW_NO;
- }
- } else {
- $upUserData['is_first_unfollow'] = UserConstants::USER_IS_FIRST_UNFOLLOW_NO;
- }
- //取消关注时,清空关注时的推广链接
- $upUserData['follow_referral_id'] = 0;
- $oAna = new AnalysisObject();
- $oAna->type = KafkaDotConstants::TYPE_UNSUBSCRIBE;
- $oAna->event_time = Request::instance()->server('REQUEST_TIME');
- //发送打点数据
- $dotData = new DotObject();
- $dotData->bind($upUserData);
- $dotData->channel_id = $channelId;
- $dotData->user_id = $userId;
- $dotData->is_first_unfollow = $upUserData['is_first_unfollow'];
- $dotData->event_time = Request::instance()->server('REQUEST_TIME');
- $dotData->action_type = MqConstants::ROUTING_KEY_UNSUBSCRIBE;
- $dotData->type = MqConstants::MSG_TYPE_UNFOLLOW;
- MqService::instance()->sendMessage($dotData);
- //取消关注推广链接打点,推广链接净关注使用,使用用户关注时的推广链接进行打点
- if ($user_follow_referral_id = $oldUser['follow_referral_id'] ?? null) {
- $oAna->user_from = [
- 'referral_id' => $user_follow_referral_id
- ];
- $dotData->action_type = MqConstants::ROUTING_KEY_UNSUBSCRIBE_REFERRAL;
- $dotData->referral_id = $user_follow_referral_id;
- MqService::instance()->sendMessage($dotData);
- }
- $oAna->data['user_collect'] = 1;
- KafkaDotService::instance()->sendMsg($userId, $oAna);
- //取消关注打点
- $upUserData['is_subscribe'] = UserConstants::USER_IS_SUBSCRIBE_NO;
- UserService::instance()->update($upUserData, ['id' => $userId]); //更新关注状态
- if (Redis::instance()->exists($userKey)) {
- Redis::instance()->hmset($userKey, $upUserData);
- Redis::instance()->expire($userKey, 86400);
- }
- }
- }
- /**
- * 微信永久二维码关注回复
- * @param AdminConfigObject $adminConfig 渠道商信息
- * @param EventObject $message 微信信息
- * @param bool $is_scan 是不是已关注扫码
- * @return Text|mixed
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- * @throws \think\Exception
- */
- protected function weChatPermanentQRCodeFollow(AdminConfigObject $adminConfig, EventObject $message,$is_scan = false)
- {
- $object = new ReplyMsgObject();
- $index = $message->EventKey;
- $qrcode = CustomService::instance()->getCustomQrcodeModel()->field('id,type,eventkey,book_name,book_id,chapter_id,referral_id')->where(['admin_id' => $adminConfig->admin_id, 'index' => $index])->find();
- if ($qrcode) {
- $cacheKey = CacheConstants::getQrcodeVisitCache($message->FromUserName);
- Redis::instance()->set($cacheKey, $qrcode['id'], 10);
- if(!$is_scan){
- //UV统计
- $redis = Redis::instance();
- $pre_num = $redis->pfCount("QR_UV:{$adminConfig->admin_id}:{$index}");
- $redis->pfAdd("QR_UV:{$adminConfig->admin_id}:{$index}",$message->FromUserName);
- $after_num = $redis->pfCount("QR_UV:{$adminConfig->admin_id}:{$index}");
- //UV每日统计
- if($after_num>$pre_num){
- $redis->pfAdd("QR_UV:".date('Ymd').":{$adminConfig->admin_id}:{$index}",$message->FromUserName);
- $redis->expire("QR_UV:".date('Ymd').":{$adminConfig->admin_id}:{$index}",60*60*24);
- }
- }
- //资源回复
- if (intval($qrcode['type']) == MessageConstants::QRCODE_EVENT_TYPE_RESOURCE) {
- if ($autoReply = $this->autoReply($message->ToUserName, $message->FromUserName, $qrcode['eventkey'], MessageConstants::MESSAGE_TYPE_EVENT_YES)) {
- if ($autoReply instanceof ReplyMsgObject && $autoReply->msg_mark == MarkConstants::MARK_RESOURCE) {
- $autoReply->msg_mark = MarkConstants::MARK_QR_RESOURCE;
- }
- return $autoReply;
- }
- }
- //书籍回复
- if (intval($qrcode['type']) == MessageConstants::QRCODE_EVNET_TYPE_BOOK) {
- $replay = new ReplayTemplate($adminConfig->admin_id);
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_QR_RESOURCE;
- $object->msg_content = $replay->getQRCodeReplayTemplate('欢迎关注', $qrcode->toArray());
- return $object;
- // return new Text($replay->getQRCodeReplayTemplate('欢迎关注', $qrcode->toArray()));
- }
- //推广链接回复
- if (intval($qrcode['type']) == MessageConstants::QRCODE_EVENT_TYPE_REFERRAL) {
- $ref = model('Referral')->getone($qrcode['referral_id'],false);
- $replay = new ReplayTemplate($adminConfig->admin_id);
- $html = $replay->getQRCodeRefReplayTemplate('欢迎关注', getCurrentDomain($adminConfig->admin_id,"/t/{$ref['id']}"));
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_QR_RESOURCE;
- $object->msg_content = $html;
- return $object;
- // return new Text($html);
- }
- }
- return '';
- }
- /**
- * 获取最近阅读
- * @param $admin_id
- * @param $user
- * @return ReturnObject
- */
- public function getLocalReading($admin_id, $user)
- {
- $object = new ReplyMsgObject();
- //用户信息
- if ($user) {
- //获取阅读历史 OR 推荐书籍
- try {
- $soruceReadLog = BookService::instance()->getUserRecentlyRead()->setConnect($user['id'])->getRecentlyRead(0,
- 3, $user['id'], true);
- if ($soruceReadLog['totalNum'] > 0) {
- $book_info = current($soruceReadLog['data']);
- $cacheKey = CacheConstants::getBookSubCache($user['id']);
- //如果点下一章关注,阅读记录加一章
- if (Redis::instance()->get($cacheKey) == $book_info['book_id']) {
- $chapterInfo = BookService::instance()->getChapterInfo($book_info['book_id'], $book_info['chapter_id'] + 1, $user['id']);
- if ($chapterInfo->code == ErrorCodeConstants::SUCCESS) {
- $chapterInfo = $chapterInfo->data;
- BookService::instance()->setRecentlyRead($chapterInfo['name'], $chapterInfo['id'], $book_info['book_id'], $chapterInfo['idx'], $user['id']);
- $book_info['chapter_name'] = $chapterInfo['name'];
- }
- }
- $title = "欢迎关注,你上次看到了\r\n 《%s》 %s";
- $title = sprintf($title, $book_info['book_name'], $book_info['chapter_name']);
- $readlog = current($soruceReadLog['data']);
- //发送消息
- $replay = new ReplayTemplate($admin_id);
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_LAST_BOOK;
- $object->msg_content = $replay->getFollowReplayTemplate($title, $readlog, []);
- return $this->setData($object)->getReturn();
- }
- } catch (\Exception $e) {
- LogService::exception($e);
- }
- }
- return $this->setData(false)->getReturn();
- }
- /**
- * 获取自动回复
- * @param int $admin_id 渠道ID
- * @param int $openid 用户OPENID
- * @param string $content 渠道自定义关注回复
- * @return string 推送Text
- * @throws
- */
- private function getSubscribe($admin_id, $openid, $content = null)
- {
- try{
- $sex = UserConstants::USER_SEX_MAN;
- $uid = OfficialAccountsService::instance()->getOpenidModel()->getUserId($admin_id, $openid);
- $user = UserService::instance()->getUserModel()->getUserInfo($uid);
- $readlog = [];
- if ($user) {
- if ($user['sex'] != UserConstants::USER_SEX_UNKNOWN) {
- $sex = $user['sex'];
- }
- $result = $this->getLocalReading($admin_id, $user)->data;
- if ($result) {
- return $result;
- }
- }
- $object = new ReplyMsgObject();
- //关注回复
- if ($content) {
- $book_name = null;
- $book_id = null;
- try {
- $rankList = controller('index/index')->ranklist($sex);
- $book_name = $rankList['idx'][0]['name'];
- $book_id = $rankList['idx'][0]['id'];
- if ($book_name && $book_id) {
- $book_url = getCurrentDomain($admin_id, '/index/book/chapter', ['book_id' => $book_id]);
- $keys = ['{$book_name}', '{$book_url}'];
- $book = [$book_name, $book_url];
- $content = str_replace($keys, $book, $content);
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_RESOURCE;
- $object->msg_content = $content;
- return $object;
- // return new Text($content);
- }
- } catch (\Exception $e) {
- LogService::error("获取推荐书籍错误");
- }
- }
- $channelId = AdminService::instance()->getAdminExtendModel()->getChannelId($user['channel_id']);
- $isWater = WaterBookService::instance()->showBook($channelId,$uid);//清水逻辑
- $recommandBook = BookService::instance()->getFollowRecommandModel()->getBooksBySex($sex,$isWater);
- //推荐书籍
- if ($recommandBook) {
- $title = '亲,终于等到你了!';
- //发送消息
- $replay = new ReplayTemplate($admin_id);
- // return $replay->getFollowReplayTemplate($title, $readlog, $recommandBook);
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_RECOMMEND_BOOKS;
- $object->msg_content = $replay->getFollowReplayTemplate($title, $readlog, $recommandBook);
- return $object;
- }
- //欢迎关注
- return new Text('感谢关注!');
- }catch (Exception $e){
- LogService::error($e->getMessage().$e->getFile().$e->getLine());
- //欢迎关注
- return new Text('感谢关注!');
- }
- }
- /**
- * 自动回复匹配(自带占位符替换逻辑)
- * @param string $user_name 公众号user_name gh_c15958c0fa33
- * @param string $openid 发送人openid
- * @param string $msg 用户发送原始内容
- * @param int $type 消息类型 默认0消息 1事件client event
- * @return mixed
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- protected function autoReply($user_name, $openid, $msg, $type = MessageConstants::MESSAGE_TYPE_EVENT_NO)
- {
- $object = new ReplyMsgObject();
- LogService::info('查询自动回复 公众号:' . $user_name . ' openid:' . $openid . ' msg:' . $msg);
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getInfoByOfficialUserName($user_name);
- //解绑处理
- if (!$adminConfig) {
- return false;
- }
- $uid = OfficialAccountsService::instance()->getOpenidModel()->getUserId($adminConfig['admin_id'], $openid);
- $autoReply = false;
- if ($type == MessageConstants::MESSAGE_TYPE_EVENT_NO) { // 自动回复消息设置
- if ($msg == '$openid$') { //内置规则 查看当前访问用户openid
- return new Text($openid);
- }
- if ($msg == '$userid$') {
- $userId = OfficialAccountsService::instance()->getOpenidModel()->getUserId($adminConfig['admin_id'], $openid);
- return new Text($userId);
- }
- if ($msg == '签到') { //内置规则 签到推送消息
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_REPLY_INNER_KEYWORDS;
- $object->msg_content = $this->sign($adminConfig['admin_id'], $openid);
- return $object;
- // return new Text($this->sign($adminConfig['admin_id'], $openid));
- }
- if ($msg == 'subscribe') {
- $itkey = '';
- $switch = AdminService::instance()->getSubscribeSwitchCache($adminConfig['admin_id']);
- if (!empty($switch) && $switch['status'] == 1) {
- if ($switch['type'] == 2) {
- $subcontent = AdminService::instance()->getSubscribeConfigCache($adminConfig['admin_id']);
- if (!empty($subcontent) && !empty($subcontent['event_keys'])) {
- $eventKey = json_decode($subcontent['event_keys'],true);
- if ($subcontent['type'] == 'news') {
- $itkey = $eventKey['news'];
- } elseif ($subcontent['type'] == 'text') {
- $itkey = $eventKey['text'];
- }
- }
- }
- }
- if (!empty($itkey)) {
- $result = OfficialAccountsService::instance()->getWechatResponseModel()->where([
- 'admin_id' => $adminConfig['admin_id'],
- 'status' => 'normal',
- 'eventkey' => $itkey
- ])->find();
- }
- }
- else{
- $where = [];
- $where['admin_id'] = $adminConfig['admin_id'];
- // $where['text'] = $msg;
- $where['status'] = 'normal';
- $msg = str_replace(['\'', '"', ',', ';', '.'], ['', '', '', '', ''], $msg);
- if ($msg) {
- $autoReply = OfficialAccountsService::instance()->getWechatAutoreplyModel()->where("find_in_set('{$msg}',text)")->where($where)->find();
- }
- if($autoReply['type'] == 'text'){
- $tmpContent = json_encode($autoReply['text_content']);
- }else{
- $tmpContent = json_encode($autoReply['news_content']);
- }
- $tmpContent = str_replace("\\","",$tmpContent);
- $isBlockIosUser = UserVipExtendService::instance()->isBlockIosUser($adminConfig, $uid, $tmpContent);
- if($isBlockIosUser){
- $autoReply = [];
- }
- if ($autoReply) { //具有自动回复
- $object->push_id = $autoReply['id'];
- if ($autoReply['eventkey']) {
- $event_key = $autoReply['eventkey'];
- } else {
- $event_keys = json_decode($autoReply['event_keys'], true);
- $event_key = $event_keys[$autoReply['type']];
- }
- $result = OfficialAccountsService::instance()->getWechatResponseModel()->where([
- 'admin_id' => $adminConfig['admin_id'],
- 'eventkey' => $event_key,
- 'status' => 'normal',
- ])->find();
- }
- }
- }
- else { // client event事件触发资源回复
- if ($msg == '签到') { //内置规则 签到推送消息
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_CLICK_INNER_KEYWORDS;
- $object->msg_content = $this->sign($adminConfig['admin_id'], $openid);
- return $object;
- // return new Text($this->sign($adminConfig['admin_id'], $openid));
- }
- $result = OfficialAccountsService::instance()->getWechatResponseModel()->get([
- 'admin_id' => $adminConfig['admin_id'],
- 'eventkey' => $msg,
- 'status' => 'normal',
- ]);
- }
- /**
- * 返回内容处理
- */
- if (isset($result) && $result) {
- $result['content'] = UrlService::instance()->replaceReferralHost($adminConfig['admin_id'], $result['content'], false)->data;
- $user = UserService::instance()->getUserModel()->getUserInfo($uid);
- if ($user) {
- $result['content'] = str_replace('$user_nickname',$user['nickname'], $result['content']);
- }
- switch ($result['type']) {
- case 'text':
- if ($msg == 'subscribe') { //关注
- $object = $this->getSubscribe($adminConfig['admin_id'], $openid, $result['content']);
- if ($object instanceof ReplyMsgObject && $autoReply) {
- $object->push_id = $autoReply['id'];
- }
- return $object;
- } else {
- $object->msg_type = MarkConstants::MSG_TYPE_TEXT;
- $object->msg_mark = MarkConstants::MARK_REPLY_PRE_RESOURCE;
- $object->msg_content = $result['content'];
- return $object;
- // return new Text($result['content']);
- }
- break;
- case 'image':
- if ($msg == 'subscribe') {
- $data = $this->getLocalReading($adminConfig['admin_id'], $user)->data;
- if ($data) {
- return $data;
- }
- }
- $content = json_decode($result['content'], true);
- return new Image($content['media_id']);
- break;
- case 'news':
- if ($msg == 'subscribe') {
- $data = $this->getLocalReading($adminConfig['admin_id'], $user)->data;
- if ($data) {
- return $data;
- }
- }
- $content = json_decode($result['content'], true);
- $news = [];
- foreach ($content as $key => $value) {
- //if ($key == 0) {
- $value['image'] = cdnurl($value['image']);
- $content[$key] = $value;
- // $news[] = new NewsItem($value);
- $news[] = $value;
- //}
- }
- $object->msg_type = MarkConstants::MSG_TYPE_NEWS;
- $object->msg_mark = MarkConstants::MARK_RESOURCE;
- $object->msg_content = $news;
- return $object;
- // return new News($news);
- break;
- }
- }
- /**
- * 内置自动回复规则
- */
- switch ($msg) {
- case 'subscribe': // 关注
- return $this->getSubscribe($adminConfig['admin_id'], $openid);
- break;
- case 'ContactManager': //联系客服
- case 'manager_contact': //联系客服
- if ($adminConfig && isset($adminConfig['manager_contact']) && !empty($adminConfig['manager_contact'])) {
- $contact = $adminConfig['manager_contact'];
- if (!empty($contact)) {
- $contact = strip_tags($contact, '<p><br>');
- $contact = preg_replace("/<p.*?>/is", "", $contact);
- $contact = preg_replace("/<\/p>/is", "\n", $contact);
- $contact = preg_replace("/<\/br>|<br>/is", "\n", $contact);
- }
- }
- if (!isset($contact) || strlen($contact) < 7) {
- $contact = Config::get('site.wx_contact');
- $contact = strip_tags($contact, '<p><br>');
- $contact = preg_replace("/<p.*?>/is", "", $contact);
- $contact = preg_replace("/<\/p>/is", "\n", $contact);
- $contact = preg_replace("/<\/br>|<br>/is", "\n", $contact);
- }
- return new Text($contact);
- break;
- }
- return false;
- }
- /**
- * 微信签到
- * @param $admin_id
- * @param $openid
- * @return string
- */
- private function sign($admin_id, $openid)
- {
- if ($uid = OfficialAccountsService::instance()->getOpenidModel()->getUserId($admin_id, $openid)) {
- [$status, $message] = OfficialAccountsService::instance()->getSignModel()->setConnect($uid)->UserSign();
- if (!$status) {
- LogService::info('Sign: UserID:' . $uid . ' Error:' . $message);
- }
- return $message;
- } else {
- return '签到失败,用户信息为空';
- }
- }
- /**
- * 分享活动 签到回复
- * @param $appId
- * @param $channel_id
- * @param $openid
- * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
- * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
- */
- private function sendShareText($appId, $channel_id, $openid)
- {
- if(ActiveShareService::instance()->checkChannel($channel_id)){
- $content = ActiveShareService::instance()->getSignReplyContent($channel_id);
- $adminConfig = AdminService::instance()->getAdminConfigModel()->getAdminInfoByAppId($appId);
- $wechat = new WeChatObject($adminConfig);
- $officialAccount = $wechat->getOfficialAccount();
- //调用客服消息
- $news = new Text($content);
- $officialAccount->customer_service
- ->message($news)
- ->to($openid)
- ->send();
- }
- }
- }
|