企微短剧业务系统

WelcomeMsgSend.php 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Log;
  4. use App\Models\SourceQrcodes;
  5. use App\Models\SourceQrcodeWelcomeMsg;
  6. use App\Models\WelcomeMsg;
  7. use App\RedisModel;
  8. use App\Service\CustomerTagService;
  9. use App\Service\ExternalContactService;
  10. use App\Service\MaterialService;
  11. use App\Service\WelcomeMsgSendService;
  12. use App\Support\EmailQueue;
  13. use Illuminate\Console\Command;
  14. class WelcomeMsgSend extends Command
  15. {
  16. protected $signature = 'WelcomeMsgSend';
  17. protected $description = '发送新客户欢迎语';
  18. public function handle()
  19. {
  20. \DB::connection()->disableQueryLog();
  21. $beginTime = time();
  22. $this->info(date('m-d H:i:s') . ' 开始整理');
  23. while(true) {
  24. $result = $this->getMsg();
  25. if($result === false) {
  26. sleep(2);
  27. }
  28. $now = time();
  29. // 超过10分钟,主动停止循环
  30. if ($now - $beginTime > 600) {
  31. break;
  32. }
  33. }
  34. $this->info(date('Y-m-d H:i:s') . ' 整理结束');
  35. }
  36. private function getMsg()
  37. {
  38. try {
  39. # 取出新客户数据
  40. $dataJson = RedisModel::rPop(WelcomeMsg::WELCOME_USER_RDS);
  41. if(empty($dataJson))
  42. return false;
  43. $userInfo = json_decode($dataJson, true);
  44. Log::logInfo('此次取出的新客户数据', ['user_info' => $userInfo], 'WelcomeCodeSendTrace');
  45. $result = $this->send($userInfo);
  46. } catch (\Exception $e) {
  47. Log::logError('发送新客户欢迎语流程出现异常', [
  48. 'line' => $e->getLine(),
  49. 'msg' => $e->getMessage()
  50. ], 'WelcomeMsgSend');
  51. return false;
  52. }
  53. return $result;
  54. }
  55. private function send($userInfo)
  56. {
  57. $corpid = isset($userInfo['corpid']) ? $userInfo['corpid'] : '';
  58. $userId = isset($userInfo['user_id']) ? $userInfo['user_id'] : '';
  59. $externalUserId = isset($userInfo['external_userid']) ? $userInfo['external_userid'] : '';
  60. $welcomeCode = isset($userInfo['welcome_code']) ? $userInfo['welcome_code'] : '';
  61. $createTime = time();
  62. if(!$corpid || !$userId || !$welcomeCode) {
  63. Log::logError('待发送欢迎语客户信息缺失', ['user_info' => $userInfo], 'WelcomeMsgSend');
  64. return false;
  65. }
  66. $state = $userInfo['state'] ?? null;
  67. # 查询满足条件的消息体和附件
  68. $defMsgSend = true; // 是否使用默认
  69. if (!is_null($state)) {
  70. // 是否符合渠道
  71. $sqId = SourceQrcodes::query()
  72. ->where('corpid', $corpid)
  73. ->where('state', $state)
  74. ->where('enable', 1)
  75. ->value('id');
  76. if (!empty($sqId)) {
  77. list($content, $attachments, $ruleId) = SourceQrcodeWelcomeMsg::getMatchSqMsg($sqId, $createTime);
  78. if (!empty($content) || !empty($attachments)) {
  79. $defMsgSend = false;
  80. }
  81. }
  82. }
  83. if ($defMsgSend) {
  84. // 使用默认
  85. list($content, $attachments, $ruleId) = WelcomeMsgSendService::getMatchMsg($corpid, $userId, $createTime);
  86. if(empty($content) && empty($attachments)) {
  87. return false;
  88. }
  89. }
  90. # 替换文本消息中的用户昵称占位符
  91. if(!empty($content) && (strstr($content, '%NICKNAME%') !== false))
  92. $content = WelcomeMsgSendService::nicknameReplace($corpid, $externalUserId, $content);
  93. Log::logInfo('发送的消息体和附件的处理结果', [
  94. 'content' => $content,
  95. 'attachment' => $attachments,
  96. 'user_info' => $userInfo
  97. ], 'WelcomeCodeSendTrace');
  98. # 处理附件内容中的素材ID
  99. $attachments = json_decode($attachments, true);
  100. $attachments = MaterialService::mediaIdReplace($attachments, $corpid);
  101. Log::logInfo('附件内容:', ['attachment' => $attachments, 'user_info' => $userInfo], 'WelcomeCodeSendTrace');
  102. # 处理附件中的雷达信息
  103. $channel = $defMsgSend ? 3 : 4;
  104. $attachments = MaterialService::radarAttachment($attachments, $corpid, $userId, $channel, $ruleId, 2);
  105. Log::logInfo('【雷达信息处理后】附件内容:', ['attachment' => $attachments, 'user_info' => $userInfo], 'WelcomeCodeSendTrace');
  106. # 处理附件中的小程序链接
  107. $attachments = WelcomeMsgSendService::MiniProgramPathDeal($corpid, $userId, $attachments, $externalUserId);
  108. Log::logInfo('【小程序跳转链接处理后】附件内容:', ['attachment' => $attachments, 'user_info' => $userInfo], 'WelcomeCodeSendTrace');
  109. # 发送客户欢迎语
  110. $responseData = WelcomeMsgSendService::sendMsg($corpid, $welcomeCode, $content, $attachments);
  111. Log::logInfo('欢迎语发送响应结果:', ['response' => $responseData, 'user_info' => $userInfo], 'WelcomeCodeSendTrace');
  112. # 将数据放入队列,处理剧集标签信息
  113. # 2024-01-16日注释,因为仅可处理柚子嘉书迈步三个平台的推广链接
  114. // RedisModel::lPush(CustomerTagService::CUSTOMER_PLAYLET_TAG_LIST, json_encode([
  115. // 'corpid' => $corpid,
  116. // 'user_id' => $userId,
  117. // 'external_userid' => $externalUserId,
  118. // 'attachments' => $attachments,
  119. // ]));
  120. if(isset($responseData['errcode']) && $responseData['errcode']) {
  121. if(!in_array($responseData['errcode'], [41051, 41096])) {
  122. # 获取入队列时间
  123. $pushTime = $userInfo['push_time'] ?? null;
  124. if(!$pushTime || (time() - strtotime($pushTime)) > 20) {
  125. EmailQueue::rPush(date('H:i:s') . '新用户欢迎语发送失败', $pushTime . $welcomeCode . json_encode($responseData, JSON_UNESCAPED_UNICODE), ['xiaohua.hou@kuxuan-inc.com'], '新用户欢迎语发送失败');
  126. }
  127. }
  128. Log::logError('新用户欢迎语发送失败', [
  129. 'code' => $responseData['errcode'],
  130. 'msg' => $responseData['errmsg'],
  131. 'corpid' => $corpid,
  132. 'userId' => $userId,
  133. 'push_time' => $userInfo['push_time'] ?? null,
  134. 'welcome_code' => $welcomeCode
  135. ], 'WelcomeMsgSend');
  136. return false;
  137. }
  138. return true;
  139. }
  140. }