ForceSubscribeDelayMsgService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: z-yang
  5. * Date: 2020/2/6
  6. * Time: 22:09
  7. */
  8. namespace App\Modules\OfficialAccount\Services;
  9. use App\Jobs\ForceSubscribeDelayMsgJob;
  10. use App\Jobs\SendNews;
  11. use App\Jobs\SendTexts;
  12. use App\Modules\OfficialAccount\Models\ForceSubscribeDelayMsg;
  13. use App\Http\Controllers\WechatController;
  14. use GuzzleHttp\Client;
  15. use GuzzleHttp\Psr7\Request as GuzzleRequest;
  16. use DB;
  17. class ForceSubscribeDelayMsgService
  18. {
  19. public static function getList($distribution_channel_id){
  20. return ForceSubscribeDelayMsg::where('distribution_channel_id',$distribution_channel_id)
  21. ->where('is_show',1)
  22. ->where('is_enable',1)
  23. ->select('id',
  24. 'distribution_channel_id',
  25. 'title',
  26. 'link',
  27. 'icon',
  28. 'desc',
  29. 'time_delay',
  30. 'mode',
  31. 'content',
  32. 'is_enable')
  33. ->get();
  34. }
  35. public static function queue($distribution_channel_id,$appid,$openid){
  36. $list = self::getList($distribution_channel_id);
  37. if($list->isEmpty())return ;
  38. foreach ($list as $item){
  39. try{
  40. if ($item->mode == 1) {
  41. $inset_data = [
  42. 'openid'=>$openid,
  43. 'title'=>$item->title,
  44. 'link'=>$item->link,
  45. 'icon'=>$item->icon,
  46. 'desc'=>$item->desc,
  47. 'mode'=>1,
  48. 'appid'=>$appid,
  49. 'time_delay'=>$item->time_delay,
  50. 'distribution_channel_id'=>$distribution_channel_id
  51. ];
  52. }elseif ($item->mode == 2) {
  53. $inset_data = [
  54. 'openid'=>$openid,
  55. 'mode'=>2,
  56. 'content'=>$item->content,
  57. 'appid'=>$appid,
  58. 'time_delay'=>$item->time_delay,
  59. 'distribution_channel_id'=>$distribution_channel_id
  60. ];
  61. }
  62. $inset_data['created_at'] = date('Y-m-d H:i:s');
  63. $inset_data['updated_at'] = date('Y-m-d H:i:s');
  64. $inset_data['predict_send_time'] = date('Y-m-d H:i:s',time()+$item->time_delay);
  65. $inset_data['send_status'] = 'ready';
  66. //$id = DB::table('force_subscribe_delay_msg_send_record')->insertGetId($inset_data);
  67. if ($item->time_delay > 60) {
  68. DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->insertGetId($inset_data);
  69. }else {
  70. $inset_data['send_status'] = 'send_success';
  71. $id = DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->insertGetId($inset_data);
  72. // 加入队列
  73. $send_data = [
  74. 'id'=>$id,
  75. 'openid'=>$openid,
  76. 'title'=>$item->title,
  77. 'link'=>$item->link,
  78. 'icon'=>$item->icon,
  79. 'desc'=>$item->desc,
  80. 'mode'=>$item->mode,
  81. 'appid'=>$appid,
  82. 'time_delay'=>$item->time_delay,
  83. 'distribution_channel_id'=>$distribution_channel_id,
  84. 'content'=>$item->content,
  85. ];
  86. $job = (new ForceSubscribeDelayMsgJob($send_data))->onConnection('rabbitmq')->delay($item->time_delay)->onQueue('force_subscribe_delay_msg');
  87. dispatch($job);
  88. }
  89. if(stripos($item->link,'?') !== false){
  90. $link = $item->link.'&fromtype=subscribe_delay&send_time='.(time()+$item->time_delay);
  91. }else{
  92. $link = $item->link.'?fromtype=subscribe_delay&send_time='.(time()+$item->time_delay);
  93. }
  94. // 原代码
  95. $send_content = [];
  96. $send_content[] = [
  97. ['title'=>textDecode($item->title)],
  98. ['description'=>textDecode($item->desc)],
  99. ['url'=> $link],
  100. ['image'=>$item->icon]
  101. ];
  102. $send_data=array(
  103. 'send_time'=>date("Y-m-d H:i:s"),
  104. 'data' => [
  105. 'openid'=>$openid,
  106. 'appid'=>$appid,
  107. 'type'=>'one_task',
  108. 'task_id'=>3,
  109. 'news_content'=>json_encode($send_content)
  110. ]
  111. );
  112. // $job = (new SendNews($send_data))->onConnection('rabbitmq')->delay($item->time_delay)->onQueue('send_news_list');
  113. // dispatch($job);
  114. }catch (\Exception $e){
  115. }
  116. }
  117. }
  118. public static function dequeue($openid){
  119. DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('openid',$openid)
  120. ->where('send_status','ready')->update([
  121. 'send_status'=>'unsubscribe',
  122. 'updated_at'=>date('Y-m-d H:i:s')
  123. ]);
  124. }
  125. public static function getSendList($time_delay){
  126. $result = DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('send_status','ready')
  127. ->where('predict_send_time','>=',date('Y-m-d H:i:s',time()-$time_delay*2))
  128. ->where('predict_send_time','<=',date('Y-m-d H:i:s',time()+$time_delay))
  129. ->select('openid','id','desc','link','icon','appid','title','distribution_channel_id','time_delay','mode','content')
  130. ->get();
  131. if($result){
  132. $client = new Client();
  133. $access_token_list = [];
  134. foreach ($result as $item){
  135. //用户类型是否满足条件
  136. $is_access = self::msgUserTypeIsAccess($item->distribution_channel_id,$item->time_delay,$item->openid,$msg);
  137. if(!$is_access) {
  138. DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('id',$item->id)
  139. ->update([
  140. 'send_status'=>$msg,
  141. 'send_time'=>date('Y-m-d H:i:s'),
  142. 'updated_at'=>date('Y-m-d H:i:s'),
  143. 'send_result'=>''
  144. ]);
  145. continue;
  146. }
  147. if(isset($access_token_list[$item->appid])){
  148. $access_token = $access_token_list[$item->appid];
  149. }else{
  150. $access_token = self::getAccessToken($item->appid);
  151. if($access_token){
  152. $access_token_list[$item->appid] = $access_token;
  153. }
  154. }
  155. if ($item->mode == 1 && $item->link) {
  156. if(stripos($item->link,'?') !== false){
  157. $link = $item->link.'&fromtype=subscribe_delay_'.$item->id;
  158. }else{
  159. $link = $item->link.'?fromtype=subscribe_delay_'.$item->id;
  160. }
  161. }
  162. if($access_token){
  163. if ($item->mode == 1) {
  164. $result = self::send($client,$access_token,$item->openid,textDecode($item->title),textDecode($item->desc),$link,$item->icon);
  165. }elseif ($item->mode == 2) {
  166. $nickname = DB::connection('api_mysql')->table('temp_force_subscribe_users')->leftjoin('users', 'users.id', '=', 'temp_force_subscribe_users.uid')->where(['temp_force_subscribe_users.openid'=>$item->openid, 'temp_force_subscribe_users.distribution_channel_id'=>$item->distribution_channel_id])->value('users.nickname');
  167. $content = textDecode(str_replace('{user}', $nickname, $item->content));
  168. $result = self::sendMsg($client,$access_token,$item->openid,$content);
  169. $content = $nickname = null;
  170. }
  171. $result_array = \GuzzleHttp\json_decode($result,1);
  172. if(isset($result_array['errcode']) && $result_array['errcode'] == 0){
  173. $send_status = 'send_success';
  174. }else{
  175. $send_status = 'send_fail';
  176. }
  177. DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('id',$item->id)
  178. ->update([
  179. 'send_status'=>$send_status,
  180. 'send_time'=>date('Y-m-d H:i:s'),
  181. 'updated_at'=>date('Y-m-d H:i:s'),
  182. 'send_result'=>$result
  183. ]);
  184. }
  185. }
  186. }
  187. }
  188. public static function msgUserTypeIsAccess($distribution_channel_id,$time_delay,$openid,&$msg){
  189. $forceSubscribeDelayMsg = ForceSubscribeDelayMsg::where('distribution_channel_id',$distribution_channel_id)
  190. ->where('time_delay',$time_delay)
  191. ->where('is_show',1)
  192. ->where('is_enable',1)
  193. ->select('user_type')
  194. ->first();
  195. $msg = '';
  196. if(!$forceSubscribeDelayMsg) {
  197. $msg = 'sys-error';
  198. return false;
  199. }
  200. if(strtoupper($forceSubscribeDelayMsg->user_type) == 'ALL') return true;
  201. //已付费用户
  202. $force_subscribe_user = DB::connection('api_mysql')->table('temp_force_subscribe_users')->where('openid',$openid)->where('is_subscribed',1)->select('uid')->first();
  203. // if(!$force_subscribe_user) {
  204. // $msg = 'no subscribe';
  205. // return false;
  206. // }
  207. // if(!$force_subscribe_user->uid) {
  208. // $msg = 'no subscribe uid';
  209. // return false;
  210. // }
  211. if(strtoupper($forceSubscribeDelayMsg->user_type) == 'PAID'){
  212. if (isset($force_subscribe_user->uid) && !empty($force_subscribe_user->uid)) {
  213. $paid_count = DB::connection('api_mysql')->table('orders')->where('uid',$force_subscribe_user->uid)->where('status','PAID')->count();
  214. if($paid_count && $paid_count >0)
  215. return true;
  216. $msg = 'need paid';
  217. return false;
  218. } else {
  219. return false;
  220. }
  221. }
  222. //未已付费用户
  223. if(strtoupper($forceSubscribeDelayMsg->user_type) == 'UNPAID'){
  224. if (isset($force_subscribe_user->uid) && !empty($force_subscribe_user->uid)) {
  225. $paid_count = DB::connection('api_mysql')->table('orders')->where('uid',$force_subscribe_user->uid)->where('status','PAID')->count();
  226. if($paid_count && $paid_count >0) {
  227. $msg = 'need unpaid';
  228. return false;
  229. }
  230. return true;
  231. }elseif ($force_subscribe_user) {
  232. return true;
  233. }else {
  234. return false;
  235. }
  236. }
  237. $msg = 'unknown type';
  238. return false;
  239. }
  240. private static function getAccessToken($appid){
  241. try{
  242. $WechatController = new WechatController($appid);
  243. $accessToken = $WechatController->app->access_token;
  244. $token = $accessToken->getToken();
  245. return $token;
  246. }catch(\Exception $e){
  247. \Log::error($e);
  248. }
  249. return '';
  250. }
  251. private static function send(Client $client,$access_token,$openid,$title,$description,$url,$picurl){
  252. $push_url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
  253. $request = new GuzzleRequest('post',$push_url,[],\GuzzleHttp\json_encode([
  254. 'touser'=>$openid,
  255. 'msgtype'=>'news',
  256. 'news'=>[
  257. 'articles'=>[compact('title','description','url','picurl')]
  258. ]
  259. ],JSON_UNESCAPED_UNICODE));
  260. try{
  261. return $client->send($request)->getBody()->getContents();
  262. }catch (\Exception $e){}
  263. return '';
  264. }
  265. // 发送文字消息
  266. private static function sendMsg(Client $client,$access_token,$openid,$content){
  267. $push_url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
  268. $request = new GuzzleRequest('post',$push_url,[],\GuzzleHttp\json_encode([
  269. 'touser'=>$openid,
  270. 'msgtype'=>'text',
  271. 'text'=>[
  272. 'content'=>$content
  273. ]
  274. ],JSON_UNESCAPED_UNICODE));
  275. try{
  276. return $client->send($request)->getBody()->getContents();
  277. }catch (\Exception $e){}
  278. return '';
  279. }
  280. }