JPushMessageJob.php 3.28 KB
<?php

namespace App\Jobs;

use Arr;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use JPush\Client;
use JPush\Exceptions\APIRequestException;
use JPush\Exceptions\ServiceNotAvaliable;
use Log;


class JPushMessageJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var \JPush\Client
     */
    protected Client $client;

    protected array $user;

    protected string $title;

    protected string $content;

    protected array $extras;

    protected array $config;


    /**
     * Create a new job instance.
     * @param array<int,string>|string $user
     * @param string                   $title
     * @param string                   $content
     * @param array<string,mixed>      $extras
     */
    public function __construct(array|string $user, string $title, string $content, array $extras = [])
    {
        $this->config = config('services.jpush');

        $this->client = new Client($this->getConfig('key'), $this->getConfig('secret'), NULL);

        $this->user = Arr::map(Arr::wrap($user), fn($item) => $this->getConfig('prefix') . $item);

        [$this->title, $this->content, $this->extras] = [$title, $content, $extras];
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws \Random\RandomException
     */
    public function handle(): void
    {
        try {
            $response = $this->send();
        } catch (APIRequestException|ServiceNotAvaliable $exception) {
            $response = ['http_code' => $exception->getHttpCode(), 'body' => $exception->getMessage()];
        }

        Log::channel('jpush')->info('JPush Message Status[' . $response['http_code'] . ']: ' . PHP_EOL, [
            'user'     => $this->user,
            'request'  => ['title' => $this->title, 'content' => $this->content, 'extras' => $this->extras],
            'response' => $response['body']
        ]);
    }

    /**
     * @param string $key
     * @return mixed
     */
    private function getConfig(string $key): mixed
    {
        return Arr::get($this->config, $key);
    }

    /**
     * @return array
     * @throws \Random\RandomException
     */
    private function send(): array
    {
        return $this->client->push()->setPlatform('all')->addAlias($this->user)
            ->iosNotification(['title' => $this->title, 'body' => $this->content], ['extras' => $this->extras])
            ->androidNotification($this->content, ['title' => $this->title, 'alert_type' => 7, 'extras' => $this->extras])
            ->options([
                'apns_production'     => $this->getConfig('apns_production'),
                'time_to_live'        => 86400 * 3,
                'sendno'              => random_int(100, 99999999),
                'third_party_channel' => [
                    'xiaomi' => ['importance' => 'HIGH'],
                    'huawei' => ['importance' => 'HIGH'],
                    'honor'  => ['importance' => 'NORMAL'],
                    'meizu'  => ['importance' => 'HIGH'],
                    'oppo'   => ['importance' => 'HIGH'],
                    'vivo'   => ['importance' => 'HIGH'],
                ]
            ])
            ->send();
    }
}