123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- <?php
- /**
- * 批量发送微信素材
- */
- namespace App\Modules\WechatMaterial\Services;
- use App\Modules\WechatMaterial\Models\WechatMaterial;
- use App\Modules\WechatMaterial\Models\WechatMaterialSendMsg;
- use App\Modules\WechatMaterial\Models\BatchWechatMaterial;
- use App\Modules\OfficialAccount\Services\ForceSubscribeService;
- use App\Modules\OfficialAccount\Models\ForceSubscribeUsers;
- use App\Modules\OfficialAccount\Models\OfficialAccount;
- use App\Modules\OfficialAccount\Models\OfficialCustomMsg;
- use App\Modules\OfficialAccount\Models\CustomSendMsgs;
- use App\Modules\User\Services\ReadRecordService;
- use App\Modules\User\Services\UserService;
- use App\Modules\Book\Services\BookConfigService;
- use App\Modules\OfficialAccount\Services\OfficialAccountService;
- use App\Modules\Channel\Services\ChannelService;
- use GuzzleHttp\Client;
- use Redis;
- use App\Jobs\SendBatchWechatMaterial;
- class BatchWechatCustomSendService
- {
- /**
- * @return int|void toCheckAndSendCustomMsg
- * 查找并发送客服消息
- */
- static function toCheckAndSendBatchCustomMsg()
- {
- //
- try {
- //查找模板消息并发送
- $statusPram = 'to_send';
- $allStandByWechatCustomMsgs = WechatMaterialSendMsg::wechatCustomMsgsByStatus($statusPram);
- \Log::info($allStandByWechatCustomMsgs);
- $allStandByWechatCustomMsgsArray = [];
- if ($allStandByWechatCustomMsgs) {
- //先单独更新数据库 把要发送的状态改为sending 以免发送期间超时,导致重复发送
- for ($x = 0; $x < count($allStandByWechatCustomMsgs); $x++) {
- $customSendMsgsPrams = $allStandByWechatCustomMsgs[$x];
- $send_time = $customSendMsgsPrams['send_time'];
- if (strtotime($send_time) - time() > 60*15) { //发送时间大于当前时间15分钟
- continue;
- } else {
- \Log::info('========现将客服消息设置成发送状态 "sending" 用户不能操作(删除,编辑,停止) = ' . $customSendMsgsPrams['id']);
- $customSendMsgsPrams['status'] = 'sending';
- $customSendMsgsPrams->save();
- $officialAccountArray = $customSendMsgsPrams->toArray();
- Redis::hset('send_batch_wechat_msg:task_id:' . $customSendMsgsPrams['id'], 'wechat_msg', json_encode($officialAccountArray));
- $allStandByWechatCustomMsgsArray[] = $customSendMsgsPrams;
- }
- }
- for ($x = 0; $x < count($allStandByWechatCustomMsgsArray); $x++) {
- $customSendMsgsPrams = $allStandByWechatCustomMsgsArray[$x];
-
- // 转化图文的链接url
- // $customSendMsgsPrams['content'] = self::convert_custom_content($customSendMsgsPrams['content'],$customSendMsgsPrams['id'],$customSendMsgsPrams['distribution_channel_id']);
- $media_id = $customSendMsgsPrams['wechat_media_id'];
- $appids = $customSendMsgsPrams['appid'];
- $batch_id = $customSendMsgsPrams['batch_id'];
- $task_id = $customSendMsgsPrams['id'];
-
- // 获取发送的批次信息
- $batchWechatMaterial = BatchWechatMaterial::find($batch_id);
- $send_time= isset($batchWechatMaterial['send_time'])?$batchWechatMaterial['send_time']:date('Y-m-d H:i:s');
- $is_full_send= isset($batchWechatMaterial['is_all_user'])?$batchWechatMaterial['is_all_user']:0;
-
- \Log::info('batch_wechat_msg,appids:'.$appids.' is_full_send:'.$is_full_send.' media_id:'.$media_id);
- $appidArray = explode(',', $appids);
- $usercountnum = 0;
- for ($j=0; $j < count($appidArray); $j++) {
- $skip = 0;
- $next_openid = '';
- $loop = 0;
- while ( $skip <= 2500000) {
- $loop++;
- \Log::info('toCheckAndSendBatchCustomMsg_loop:'.$skip.' loop:'.$loop.' next_openid:'.$next_openid);
- $users = array();
- // 全服务号粉丝发,要记录next_openid
- if($is_full_send){
- // 防止异常
- if($loop > 1 && empty($next_openid)){
- \Log::info('send_template_appid:'.$appidArray[$j].' break,skip:'.$skip);
- break;
- }
- try{
- $user_res = ForceSubscribeService::getFullOfficialAccountUsers($appidArray[$j],$next_openid);
- $users = $user_res['openids'];// TODO格式化成一样的格式
- $next_openid = $user_res['next_openid'];
- } catch (\Exception $e) {
- \Log::info($e);
- }
- }else{
- //5,获取所选条件下筛选出的用户
- $sign_time = 'z';
- $subscribe_time = isset($batchWechatMaterial['subscribe_time'])?$batchWechatMaterial['subscribe_time']:'';
- $sex= isset($batchWechatMaterial['sex'])?$batchWechatMaterial['sex']:'';
- $balance= isset($batchWechatMaterial['balance'])?$batchWechatMaterial['balance']:'';
- $category_id= isset($batchWechatMaterial['category_id'])?$batchWechatMaterial['category_id']:'';
- $order_type= isset($batchWechatMaterial['pay_type'])?$batchWechatMaterial['pay_type']:'';
- $sign_time= isset($batchWechatMaterial['sign_time'])?$batchWechatMaterial['sign_time']:'';
- $interaction_time= isset($batchWechatMaterial['interaction_time'])?$batchWechatMaterial['interaction_time']:'';
-
- $users = ForceSubscribeService::forceUserCountByBatchWechatCustomPrams($appidArray[$j],$customSendMsgsPrams['distribution_channel_id'],$subscribe_time,$sex,$balance,$category_id,$order_type,$sign_time,$interaction_time,$skip);
- }
- \Log::info('toCheckAndSendBatchCustomMsg_users_num:'.count($users));
- // continue;
- $queue_user_one_num = 10000;
- $user_loop = 1;
- $last_openids = $openids = [];
- if (count($users)>0) {
- $usercountnum += count($users);
- for ($i=0; $i < count($users); $i++) {
-
- // 循环用户发送客服消息
- $data = array();
- if ($i == count($users)-1) {
- $data['type'] = 'last_task';
- }else{
- $data['type'] = 'one_task';
- }
-
- \Log::info('i:'.$i.' $user_loop:'.$user_loop.' openid:'.$users[$i]['openid'].' type:'.$data['type']);
-
- // 一次组装10000个用户 (接口1次最多10000个,1天最多发100次)
- if($user_loop <= $queue_user_one_num){
- $openids[] = $users[$i]['openid'];
- $user_loop++;
-
- // 最后1组直接执行
- if($data['type'] == 'one_task'){
- continue;
- }else{
- $last_openids = $openids;
- }
-
- }else{
- $user_loop = 1;
- $last_openids = $openids;
- }
-
- // $data['content'] = $customSendMsgsPrams['content'];
- $data['openids'] = $last_openids;
- $data['appid'] = $appidArray[$j];
- $data['media_id'] = $media_id;
- $data['type'] = 'last_task'; // 默认发1个直接更新,防止更新失败情况
- $data['task_id'] = $task_id;
- $data['batch_id'] = $batch_id;
- $data['send_time'] = $send_time;
- $send_data=array(
- 'send_time'=>$send_time,
- 'data' => $data
- );
- $now_time = strtotime($send_time)-time();
- $delay = $now_time < 0 ? 0:$now_time;
-
- \Log::info('SendBatchWechatMaterial:'.json_encode($last_openids).' task_id:'.$task_id);
- \Log::info($send_data);
- $job = (new SendBatchWechatMaterial($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('{send_batch_wechat_material}');
-
- dispatch($job);
-
- $last_openids = $openids = [];
- }
- }else{
- \Log::info('toCheckAndSendBatchCustomMsg_no_user:'.$customSendMsgsPrams['task_id']);
- break;
- }
- $skip += count($users);
- }
- }
- $customSendMsgsPrams['send_user_num'] = $usercountnum;
- // 若没有用户,则直接更新为已发送
- if($usercountnum == 0){
- \Log::info('has_no_batch_custom_users:'.$customSendMsgsPrams['id']);
- $customSendMsgsPrams['status'] = 'has_send';
- }
- \Log::info('toCheckAndSendBatchCustomMsg_update_user_num:'.$customSendMsgsPrams['id'].' usercountnum:'.$usercountnum);
- $customSendMsgsPrams->save();
- }
- }else{
- \Log::info('toCheckAndSendBatchCustomMsg_no_msgs');
- }
- } catch (\Exception $e) {
- \Log::info('toCheckAndSendBatchCustomMsg_ept:'.$e->getMessage());
- }
- }
-
- /**
- * 转换客服消息内容
- */
- public static function convert_custom_content($content,$mark_str,$distribution_channel_id){
- \Log::info('convert_custom_content_start:');
- $_contents = json_decode($content);
- \Log::info('convert_custom_content_before:');
- \Log::info($_contents);
- $new_contents = null;
- $origin_mark_str = $mark_str;
- $send_type = 'batch_custom';
- // 智能推送不加前缀
- if(strpos($origin_mark_str,'smart_push_') > -1){
- $send_type = 'smart_push';
- $origin_mark_str = str_replace('smart_push_','',$origin_mark_str);
- }
- \Log::info('origin_mark_str:'.$origin_mark_str);
- foreach($_contents as $key=>$_content){
- // 新版要自动添加域名
- $_content[2]->url = self::checkAddDomain($distribution_channel_id,$_content[2]->url);
-
- $mark_str = $origin_mark_str.'&source=wechatmsg';// source能让用户继续阅读
- $_contents[$key][2]->url = self::redirect_url_add_param($_content[2]->url,$mark_str,$send_type,false);
- $new_contents[] = $_contents[$key];
- }
- \Log::info('convert_custom_content_after:');
- \Log::info($new_contents);
- $_convert_contents = json_encode($new_contents);
-
- return $_convert_contents;
- }
-
- /**
- * 跳转地址加参
- * @param unknown_type $redirect_url
- * @param unknown_type $type
- * @return string
- */
- public static function redirect_url_add_param($redirect_url,$mark_str,$type='custom',$trusteeship=false){
- $pre_str = '';
- if($type == 'batch_custom'){
- $pre_str = 'batch_custom_';
- }
-
- // 模板客服消息,单独加参
- $inner_order_id = '';
- if(!$trusteeship){
- $inner_order_id = '&inner_order_id='.$pre_str.$mark_str;
- }
-
- $send_time_str = '';
-
- // 跳转链接加参
- if(strpos($redirect_url,'?') > -1){
- $redirect_url .= '&fromtype='.$pre_str.$mark_str.$inner_order_id.$send_time_str;
- }else{
- $redirect_url .= '?fromtype='.$pre_str.$mark_str.$inner_order_id.$send_time_str;
- }
- return $redirect_url;
- }
-
- // 新版要自动添加域名
- public static function checkAddDomain($distribution_channel_id,$redirect_url){
- // 非托管,如果url没有域名,则加上
- if(strpos($redirect_url, 'http') !== false){
- \Log::info('not_need_add_domain:'.$distribution_channel_id.' url:'.$redirect_url);
- }else{
- \Log::info('need_add_domain_before:'.$distribution_channel_id.' url:'.$redirect_url);
- $redirect_url = env('PROTOCOL').'://site'.encodeDistributionChannelId($distribution_channel_id).'.'.env('CUSTOM_HOST').'.com'.$redirect_url;
- \Log::info('need_add_domain_after:'.$distribution_channel_id.' url:'.$redirect_url);
- }
- return $redirect_url;
- }
-
- }
|