PHP 实现VIVO推送

<?php

namespace App\Helper;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use Carbon\Carbon;
use App\Helper\Cache;

class VivoMessage
{
    /**
     * 推送URL
     */
    const URL = 'https://api-push.vivo.com.cn';

    /**
     * token过期时间
     */
    const TOKEN_TTL = 43200;

    /**
     * 推送消息 单条
     * @param $setting 消息配置
     * @param $message 消息体
     * @param $regId 用户regId
     */
    public function send($setting, $message, $regId)
    {
        $url = sprintf('%s/message/send', self::URL);
        $accessToken = $this->getAccessToken($setting);

        $requestId = $this->getrequestId();
        $params = [
            'appId' => $setting->app_id,
            'regId' => $regId,
            'notifyType' => 4,
            'title' => $message['title'],
            'content' => $message['content'],
            'skipType' => 4,
            'skipContent' => $message['url'],
            'requestId' => $requestId,
            'clientCustomMap' => $message['params'] ?? null,
        ];
        $this->request($url, $params, $accessToken);
    }

    /**
     * 获取taskId
     * @param setting 推送配置
     * @param message 消息体
     */
    public  function getTaskId($setting, $message)
    {
        $url = sprintf('%s/message/saveListPayload', self::URL);

        $accessToken = $this->getAccessToken($setting);

        $requestId = $this->getrequestId();
        $params = [
            'appId' => $setting->app_id,
            'notifyType' => 4,
            'title' => $message['title'],
            'content' => $message['content'],
            'skipType' => 4,
            'skipContent' => $message['url'],
            'requestId' => $requestId,
            'clientCustomMap' => $message['params'] ?? null,
        ];

        $result = $this->request($url, $params, $accessToken);
        return $result['taskId'];
    }

    /**
     * 推送消息 多条
     * @param setting 推送配置
     * @param message 消息体
     * @param regIds 推送用户regId
     */
    public function pushRegIds($setting, $message, $regIds)
    {
        $url = sprintf('%s/message/pushToList', self::URL);

        $accessToken = $this->getAccessToken($setting);
        $requestId = $this->getrequestId();
        $taskId = self::getTaskId($setting, $message);
        $params = [
            'appId' => $setting->app_id,
            'taskId' => $taskId,
            'regIds' => $regIds,
            'requestId' => $requestId,
        ];
        $this->request($url, $params, $accessToken);
    }

    /**
     * 推送消息 广播
     * @param setting 推送配置
     * @param message 消息体
     */
    public function pushAll($setting, $message)
    {
        $url = sprintf('%s/message/all', self::URL);
        $accessToken = $this->getAccessToken($setting);
        $requestId = $this->getrequestId();
        $params = [
            'appId' => $setting->app_id,
            'notifyType' => 4,
            'title' => $message['title'],
            'content' => $message['content'],
            'skipType' => 4,
            'skipContent' => $message['url'],
            'requestId' => $requestId,
            'clientCustomMap' => $message['params'] ?? null,
        ];
        $this->request($url, $params, $accessToken);
    }

    /**
     * 创建AccessToken
     */
    public function createAccessToken($setting)
    {
        $timestamp = Carbon::now()->getPreciseTimestamp(3);
        $sign = strtolower(md5($setting->app_id . $setting->app_key . $timestamp . $setting->app_secret));
        $params = [
            'appId' => $setting->app_id,
            'appKey' => $setting->app_key,
            'timestamp' => $timestamp,
            'sign' => $sign,
        ];

        $url = sprintf('%s/message/auth', self::URL);
        $result = $this->request($url, $params);

        $key = $this->tokenKey($setting->app_key);
        Cache::set($key, $result['authToken'], self::TOKEN_TTL);
        return $result['authToken'];
    }

    /**
     * 获取AccessToken
     */
    public function getAccessToken($setting)
    {
        $key = $this->tokenKey($setting->app_key);
        $accessToken = Cache::get($key);
        if (!$accessToken) {
            $accessToken = $this->CreateAccessToken($setting);
        }

        return $accessToken;
    }

    /**
     * 获取缓存key
     */
    public function tokenKey($appKey)
    {
        return sprintf('message:vivo:%s', $appKey);
    }

    /**
     * 请求
     */
    public function request($url, $params, $authToken = null)
    {
        $headers = [
            'Content-type' => 'application/json',
        ];

        if ($authToken) {
            $headers['authToken'] = $authToken;
        }

        $options = [
            'headers' => $headers,
        ];

        try {
            $result = make(Client::class)->request('POST', $url, $params, $options)->getResult();
            if ($result['result'] !== 0) {
                throw new BusinessException(ErrorCode::BIZ_ERROR, $result['desc']);
            }
        } catch (\Exception $exception) {
            throw new BusinessException(ErrorCode::BIZ_ERROR, $exception->getMessage());
        }

        return $result;
    }

    /**
     * 生成唯一请求ID
     */
    public function getrequestId()
    {
        $chars = md5(uniqid(mt_rand(), true));
        return substr($chars, 0, 8) . '-'
            . substr($chars, 8, 4) . '-'
            . substr($chars, 12, 4) . '-'
            . substr($chars, 16, 4) . '-'
            . substr($chars, 20, 12);
    }
}

猜你喜欢

转载自blog.csdn.net/wyh757787026/article/details/130152147