企微短剧业务系统

WelcomeMsgSendService.php 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace App\Service;
  3. use App\Log;
  4. use App\Models\AuthorizeCorp;
  5. use App\Models\Customer;
  6. use App\Models\CustomerDetails;
  7. use App\Models\WelcomeMsg;
  8. use App\Models\WelcomeMsgRelation;
  9. use http\Env\Request;
  10. class WelcomeMsgSendService
  11. {
  12. /**
  13. * 发送新客户欢迎语
  14. * @param $corpid string 授权方企业微信id
  15. * @param $welcomeCode string 通过添加外部联系人事件推送给企业的发送欢迎语的凭证,有效期为20秒
  16. * @param $content string 消息文本内容
  17. * @param $attachments array 附件,最多支持添加9个附件
  18. * @param $retry integer 重试次数
  19. * */
  20. public static function sendMsg($corpid, $welcomeCode, $content, $attachments, $retry=0)
  21. {
  22. # 获取AccessToken
  23. $accessToken = AuthorizeCorp::getAccessToken($corpid, '发送客户欢迎语');
  24. if(empty($accessToken)) { // Todo::令牌获取失败,发送报警
  25. return false;
  26. }
  27. $postData = [
  28. 'welcome_code' => $welcomeCode,
  29. 'text' => [
  30. 'content' => $content
  31. ],
  32. 'attachments' => $attachments
  33. ];
  34. $requestUri = config('qyWechat.send_welcome_msg');
  35. $requestUri .= $accessToken;
  36. $response = HttpService::httpPost($requestUri, json_encode($postData));
  37. if($response===false && $retry<5) { // 发起重试
  38. $retry++;
  39. return WelcomeMsgSendService::sendMsg($corpid, $welcomeCode, $content, $attachments, $retry);
  40. }
  41. $responseData = json_decode($response, true);
  42. return $responseData;
  43. }
  44. /**
  45. * @param $corpid string 授权方企业微信id
  46. * @param $userId string 企业员工id
  47. * @param $createTime integer 外部联系人关注时间戳
  48. * */
  49. public static function getMatchMsg($corpid, $userId, $createTime)
  50. {
  51. $content = '';
  52. $attachments = array();
  53. # 获取专属员工的欢迎语配置
  54. $ruleInfo = WelcomeMsgRelation::select('id')->where('corpid', $corpid)
  55. ->whereRaw("FIND_IN_SET('".$userId."', users)")
  56. ->where('enable', 1)->where('is_for_all', 0)
  57. ->where('is_del', 0)
  58. ->orderBy('updated_at', 'desc')
  59. ->first();
  60. // Log::logInfo('专属欢迎语规则:', empty($ruleInfo) ? [] : $ruleInfo->toArray(), '0407');
  61. if(empty($ruleInfo)) { // 未查询到该员工的专属配置,则查询企业全体员工通用配置
  62. $ruleInfo = WelcomeMsgRelation::select('id')->where('corpid', $corpid)
  63. ->where('enable', 1)->where('is_del', 0)
  64. ->where('is_for_all', 1)->orderBy('updated_at', 'desc')
  65. ->first();
  66. // Log::logInfo('无专属,通用欢迎语规则:', empty($ruleInfo) ? [] : $ruleInfo->toArray(), '0407');
  67. }
  68. if(empty($ruleInfo)) {
  69. Log::logInfo('未获取到相关的欢迎语配置', [
  70. 'corpid' => $corpid,
  71. 'userId' => $userId
  72. ], 'WelcomeCodeSendTrace');
  73. return [$content, $attachments, 0];
  74. }
  75. # 获取用户关注时间对应的周
  76. $weekLabel = get_week($createTime);
  77. # 转化关注时间
  78. $addTime = date('H:i:s', $createTime);
  79. # 获取符合条件的消息内容
  80. # 获取分时段消息内容
  81. $msgInfo = WelcomeMsg::select(['content', 'attachments', 'id'])->where('relation_id', $ruleInfo->id)
  82. ->whereRaw("FIND_IN_SET('".$weekLabel."', weeks)")
  83. ->where('enable', 1)->where('start_time', '<=', $addTime)->where('end_time', '>=', $addTime)
  84. ->orderBy('updated_at', 'desc')
  85. ->first();
  86. // Log::logInfo('分时段欢迎语内容:', empty($msgInfo) ? [] : $msgInfo->toArray(), '0407');
  87. if(empty($msgInfo)) { // 获取通用消息内容
  88. $msgInfo = WelcomeMsg::select(['content', 'attachments', 'id'])->where('relation_id', $ruleInfo->id)
  89. ->where('enable', 1)
  90. ->orderBy('updated_at', 'desc')
  91. ->first();
  92. // Log::logInfo('通用时段欢迎语内容:', empty($msgInfo) ? [] : $msgInfo->toArray(), '0407');
  93. }
  94. $ruleId = isset($msgInfo->id) ? $msgInfo->id : '';
  95. $content = isset($msgInfo->content) ? $msgInfo->content : '';
  96. $attachments = isset($msgInfo->attachments) ? $msgInfo->attachments : '';
  97. return [$content, $attachments, $ruleId];
  98. }
  99. /**
  100. * 替换欢迎语中的客户昵称占位符
  101. * */
  102. public static function nicknameReplace($corpid, $externalUserId, $content)
  103. {
  104. # 查询用户昵称
  105. $nickname = Customer::suffix($corpid)->where('corpid', $corpid)->where('external_userid', $externalUserId)->value('name');
  106. Log::logInfo('本地查询到的用户昵称为:'. $nickname, [], 'NicknameReplace');
  107. if(empty($nickname)) { # 数据库中无查询结果,调用企微接口进行获取
  108. $externalUserInfo = ExternalContactService::getExternalContactDetail($corpid, $externalUserId, '');
  109. $externalContact = $externalUserInfo['external_contact'] ?? [];
  110. $nickname = $externalContact['name'] ?? '';
  111. Log::logInfo('通过企微API查询到的用户昵称为:'. $nickname, [], 'NicknameReplace');
  112. }
  113. $content = str_replace('%NICKNAME%', $nickname, $content);
  114. return $content;
  115. }
  116. /**
  117. * 小程序跳转链接处理
  118. * */
  119. public static function MiniProgramPathDeal($corpid, $userId, $attachments, $externalUserId)
  120. {
  121. if(empty($attachments)) return [];
  122. foreach ($attachments as $key=>&$attachment) {
  123. $msgType = $attachment['msgtype'] ?? '';
  124. if(empty($msgType)) {
  125. unset($attachments[$key]);
  126. continue;
  127. }
  128. if($msgType == 'miniprogram') {
  129. Log::logInfo('检测到待处理的小程序类附件', [
  130. 'user_id' => $externalUserId,
  131. 'attachment' => $attachment
  132. ], 'MiniProgramPathDeal');
  133. $path = $attachment['miniprogram']['page'] ?? '';
  134. if(!$path) {
  135. unset($attachments[$key]);
  136. continue;
  137. }
  138. $extra = $corpid . '|' . $userId . '|' . $externalUserId;
  139. $wxId = '';
  140. if(strpos($path, '?')) { // 已经携带了url参数
  141. $path .= '&userId=' . $extra . '&params=' . $extra . '&exparams=' . $corpid . '|'.$userId . '|' . $wxId . '|' . $externalUserId;
  142. } else {
  143. $path .= '?userId=' . $extra . '&params=' . $extra . '&exparams=' . $corpid . '|' . $userId . '|' . $wxId . '|' . $externalUserId;
  144. }
  145. # 容量平台
  146. $path .= '&qyOpenId='.$externalUserId.'&corpId='.$corpid.'&qyUserId='.$userId.'&qyUnionId=';
  147. # 九州平台 客户详情表中的数据ID
  148. $type = JiuZhouService::getMsgTypeByCorpid($corpid);
  149. $msgId = JiuZhouService::getMsgId($corpid, $externalUserId, $userId);
  150. $path .= '&msgType='.$type.'&msgId='.$msgId;
  151. # 触摸平台
  152. $path .= '&qw_params='.$msgId;
  153. # 掌阅平台
  154. $path .= '&attach='.$msgId;
  155. $attachment['miniprogram']['page'] = $path;
  156. Log::logInfo('本次处理后的小程序跳转信息为:', [
  157. 'attachment' => $attachment,
  158. 'user_id' => $externalUserId
  159. ], 'MiniProgramPathDeal');
  160. }
  161. }
  162. return $attachments;
  163. }
  164. }