send();
}
private function generateRequest()
{
$switch_array = [];
$now_hour = date('G');
$temp = 0;
$info = DB::connection('api_mysql')->table('custom_msg_switchs')->where('custom_category','continue_read')->first();
if(!$info) return ;
$default_status = $info->default_switch_status;
while (true){
$user = DB::connection('api_mysql')->table('temp_force_subscribe_users')
->select('id','uid','distribution_channel_id','openid','appid')
->where('id','>',$temp)
//->whereIn('id',[3032288,3042985])
->where('last_interactive_time','>',date('Y-m-d H:i:s',time()-86400*2))
->orderBy('id')
->limit(1000)
->get();
if(!$user) break;
foreach ($user as $item){
if(isInnerSites($item->distribution_channel_id)) continue;
//if(!in_array($item->distribution_channel_id,[70])) continue;
//\Log::info( '---------------------------start--start-------------------------------------------' );
//\Log::info('$item->distribution_channel_id is :'.$item->distribution_channel_id );
//\Log::info( '$item->id is :'.$item->id );
if(!isset($switch_array[$item->distribution_channel_id])){
$switch = DB::connection('api_mysql')->table('custom_msg_switchs_msgs')
->where('distribution_channel_id',$item->distribution_channel_id)
->where('custom_category','continue_read')
->select('status')
->first();
if($switch){
$switch_array[$item->distribution_channel_id] = $switch->status;
}else{
$switch_array[$item->distribution_channel_id] = $default_status;
}
}
$switch_status = $switch_array[$item->distribution_channel_id];
//if(!in_array($item->distribution_channel_id,[5,123,14,13,8])) continue;
if($switch_status != 1) continue;
//\Log::info( '$item->distribution_channel_id in is :'.$item->distribution_channel_id );
//$data = ['first'=>[],'seconds'=>[]];
$read_info = $this->getReadRecord($item->uid);
if(empty($read_info['first'])){
continue;
}
//获取本次发送的时间间隔
$this_push_hour = Redis::hget('book_read:'.$item->uid,'next_push_hour');
//上次发送时间
$prev_send_info = DB::connection('api_mysql')->table('custom_push_keep_continue')->where('uid',$item->uid)->select('send_time')->orderBy('id','desc')->first();
$diff = $this_push_hour?$this_push_hour:8;
if($diff == 8){
if((time()-$read_info['time']) > 3600*8){
$send_hour = $now_hour;
}else{
$send_hour = -1;
}
}else{
if($prev_send_info){
//$send_hour = date('G',strtotime($prev_send_info->send_time)+$diff*3600);
if((time()-strtotime($prev_send_info->send_time)) >$diff*3600){
$send_hour = $now_hour;
}else{
$send_hour = -1;
}
}else{
$send_hour = $now_hour;
}
}
$domain = sprintf('https://site%s.%s.com',encodeDistributionChannelId($item->distribution_channel_id),
env('CUSTOM_HOST'));
if($send_hour != $now_hour ) continue;
$openid = $item->openid;
$appid = $item->appid;
$user_info = DB::connection('api_mysql')->table('users')->where('id',$item->uid)->select('nickname')->first();
$nickname = '读者';
if($user_info && $user_info->nickname)$nickname = $user_info->nickname;
//$content_format = "您看的小说有更新\r\n\r\n《%s》剧情已更新,点击继续阅读 \r\n\r\n记得点击菜单栏签到领书币哦";
$content_format = "@%s 为您推荐上次未看完的小说\r\n\r\n点击继续阅读❤\r\n\r\n";
/*$content = sprintf($content_format,
sprintf($continueReadUrlFormat,
encodeDistributionChannelId($item->distribution_channel_id),
env('CUSTOM_HOST'),
$read_info['url']
),
$read_info['book_name']
)*/;
$content = sprintf($content_format,$nickname,$domain.$read_info['first']['url']);
if(!empty($read_info['seconds'])){
$content .= "历史阅读记录:\r\n\r\n";
foreach ($read_info['seconds'] as $record_item){
$content .= sprintf(" 🌳 %s\r\n",$domain.$record_item['url'],$record_item['book_name']);
}
}
$content .= "\r\n为了方便下次阅读,请置顶公众号";
$access_token = $this->getAccessToken($appid);
if(!$access_token)continue;
$url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
$request = new GuzzleRequest('post',$url,[],\GuzzleHttp\json_encode([
'touser'=>$openid,
'msgtype'=>'text',
'text'=>['content'=>$content]
],JSON_UNESCAPED_UNICODE));
DB::connection('api_mysql')->table('custom_push_keep_continue')->insert([
'uid'=>$item->uid,
'time_diff'=>$diff,
'send_time'=>date('Y-m-d H:i:s'),
'day'=>date('Y-m-d'),
'created_at'=>date('Y-m-d H:i:s'),
'updated_at'=>date('Y-m-d H:i:s')
]);
if($diff == 8){
$next = 24;
}else{
$next = 24;
}
Redis::hset('book_read:'.$item->uid,'next_push_hour',$next);
//\Log::info( '----------------------------end-end-end-------------------------------------------' );
yield $request;
}
$temp = $item->id;
}
}
private function getFirstReadRecord($uid){
//Redis::hget('book_base:' . $uid, 'last_read', "{$bid}_{$cid}_{$book_name}_{$chapter_name}_" . time());
$record = Redis::hget('book_read:' . $uid, 'last_read');
if($record){
$record_arr = explode('_',$record);
$bid = $record_arr[0];
$book_name = $this->bid2BookName($bid);
//$hash = new Hashids('D6M97LIvpp4qWuz3nKzqi6yYN4GAA61b',32,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
$bid = $hash->encode($bid);
$cid = $record_arr[1];
$time = $record_arr[2];
$res = [
'url' => '/reader?bid='.$bid.'&cid='.$cid.'&fromtype=continue_read',
'book_name'=>$book_name,
'bid'=>$bid,
'time'=>$time
];
return $res;
}
return [];
}
private function getReadRecord($uid){
//$hash = new Hashids('D6M97LIvpp4qWuz3nKzqi6yYN4GAA61b',32,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
$records = Redis::hgetall('book_read:' . $uid);
$data = ['first'=>[],'seconds'=>[],'time'=>''];
foreach ($records as $k=>$item){
if($k == 'last_read'){
$record_arr = explode('_',$item);
$bid = $record_arr[0];
//$book_name = $this->bid2BookName($bid);
$bid = Hashids::encode($bid);
$cid = $record_arr[1];
$time = $record_arr[2];
$data['first'] = [
'url' => '/reader?bid='.$bid.'&cid='.$cid.'&fromtype=continue_read',
'book_name'=>'',
];
$data['time'] = $time;
continue;
}
if(!is_numeric($k)) continue;
$record = explode('_', $item);
$latest_read_cid = $record[0];
$book_name = self::bid2BookName($k);
$latest_read_time = $record[count($record) - 1];
$data['seconds'][] =[
'url' => '/reader?bid='.Hashids::encode($k).'&cid='.$latest_read_cid.'&fromtype=continue_read',
'book_name'=>$book_name,
'time'=>$latest_read_time
];
}
$temp = $data['seconds'];
if($temp){
usort($temp, function ($a, $b) {
if ($a['time'] >= $b['time']) return -1;
return 1;
});
}
$temp_res = [];
foreach ($temp as $k=>$it){
$temp_res[] = $it;
if($k>=2) break;
}
$data['seconds'] = $temp_res;
return $data;
}
private function bid2BookName($bid){
$book_name = null;
if(is_null($book_name)){
$book_key = 'wap:string:book:'.$bid;
$book_name = Redis::get($book_key);
Redis::EXPIRE($book_key,3600);
if(!$book_name){
$book_name = '';
$book_info = DB::connection('api_mysql')->table('book_configs')->where('bid',$bid)->select('book_name')->first();
//$book_info = BookConfigService::getBookById($bid);
if($book_info && isset($book_info->book_name)){
$book_name = $book_info->book_name;
Redis::setex($book_key,3600,$book_name);
}
}
}
return $book_name;
}
private function getAccessToken($appid){
try{
$WechatController = new WechatController($appid);
$accessToken = $WechatController->app->access_token; // EasyWeChat\Core\AccessToken 实例
$token = $accessToken->getToken(); // token 字符串
return $token;
}catch(\Exception $e){
\Log::error($e->getMessage());
}
return '';
}
private function send(){
$client = new Client();
$requests = $this->generateRequest();
$pool = new Pool($client, $requests, [
'concurrency' => 5,
'fulfilled' => function ($response, $index) {
},
'rejected' => function ($reason, $index) {
},
]);
$promise = $pool->promise();
$promise->wait();
}
}