Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
8.3 kB
2
Indexable
Never
<?php


namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\URL;

class Zoom
{
    /**
     * API Urls
     */
    const login_step1 = 'oauth/authorize';
    const oauth_token = 'oauth/token';
    const my_info = 'v2/users/me';
    const meetings_list = '/v2/users/me/meetings';
    const livestream = '/v2/meetings/{meetingId}/livestream';
    const revoke = '/v2/users/{userId}/token';


    const inv_access_token = 124;

    public $baseUrl = 'https://zoom.us/';
    public $baseApiUrl = 'https://api.zoom.us/';

    const CUSTOM_LIVE_STREAM_URL = 'rtmp://stream.pushx.app/live';



    /**
     * @var \App\Models\User
     */
    public $user;


    public function __construct(\App\Models\User $user)
    {
        $this->user = $user;
    }

    /**
     * @param $url
     * @param $params
     * @param bool $authenticate
     * @param array $headers
     * @param bool $api
     * @param bool $postRequest
     * @param string $httpMethod
     * @return array|mixed|object
     * @throws \Exception
     */
    public function callApi($url, $params, $authenticate = true, $headers = [], $api = false, $httpMethod = 'POST')
    {
        if ($authenticate) {
            if (!$this->user)
                $this->authenticate();

            $headers['Authorization'] =   'bearer ' . $this->user->zoom_access_token;
        }


        $req = Http::withHeaders($headers);
        if ($httpMethod == 'POST')
            $response = $req->post($this->getUrl($url, $api), $params);
        elseif ($httpMethod == 'GET')
            $response = $req->get($this->getUrl($url, $api), $params);
        elseif ($httpMethod == 'PATCH')
            $response = $req->patch($this->getUrl($url, $api), $params);
        elseif ($httpMethod == 'DELETE')
            $response = $req->delete($this->getUrl($url, $api), $params);
        $data = json_decode($response->body(), true);

        
        if (!$data && $response->status() != 204) {
           
            throw new \Exception('Something went wrong');
        }
        if (is_array($data) && array_key_exists('error', $data)) {
            throw new \Exception('Something went wrong ' . $data['error']);
        }
        if (is_array($data) && array_key_exists('code', $data) && $data['code'] == self::inv_access_token) {
            throw new \Exception('Something went wrong ', $data['code']);
        }
        if (is_array($data) && array_key_exists('message', $data)) {
            throw new \Exception('Something went wrong ' . $data['message']);
        }
        if (is_array($data) && array_key_exists('code', $data)) {
            throw new \Exception('Something went wrong ', $data['code']);
        }
        return $data;
    }

    /**
     * @param $url
     * @param $params
     * @param bool $authenticate
     * @param array $headers
     * @param bool $api
     * @param string $httpMethod
     * @return array|mixed|object
     * @throws \Exception
     * @throws \Throwable
     */
    public function getData($url, $params, $authenticate = true, $headers = [], $api = false, $httpMethod = 'POST')
    {
        $data = [];
        try {
            $data = $this->callApi($url, $params, $authenticate, $headers, $api, $httpMethod);
        } catch (\Throwable $e) {
            if ($e->getCode() == Zoom::inv_access_token) //access token in db is invalid so authenticate again
            {
                $this->refreshToken();
                $data = $this->callApi($url, $params, $authenticate, $headers, $api, $httpMethod);
            } else
                throw $e;
        }
        return $data;
    }

    public function me()
    {
        $mydata = $this->getData(Zoom::my_info, [], true, [], true, 'GET');
        return $mydata;
    }

    public function refreshToken()
    {
        
        $refresh_token_url =  Zoom::oauth_token . "?grant_type=refresh_token&refresh_token={$this->user->zoom_refresh_token}";
        
        $data = $this->callApi($refresh_token_url, [], false, [
            'Authorization' => ('Basic ' . base64_encode(env('ZOOM_CLIENT_ID') . ':' . env('ZOOM_SECRET')))
        ], false, 'POST');


        $this->user->zoom_refresh_token = $data['refresh_token'];
        $this->user->zoom_access_token = $data['access_token'];
     
        $this->user->save();

    }

    /**
     * @throws \Exception
     */
    public function authenticate()
    {
        if (!array_key_exists('code', $_GET))
            $this->requestAccess(Zoom::login_step1, [
                'response_type' => 'code',
                'client_id' => env('ZOOM_CLIENT_ID'),
                'redirect_uri' => URL::to('/') . '/' . Route::getFacadeRoot()->current()->uri()
            ]);
        else {
            $login_url = Zoom::oauth_token . '?grant_type=authorization_code&code=' . $_GET['code'] . '&redirect_uri=' . URL::to('/') . '/' . Route::getFacadeRoot()->current()->uri();
            $data = $this->callApi($login_url, [], false, [
                'Authorization' => ('Basic ' . base64_encode(env('ZOOM_CLIENT_ID') . ':' . env('ZOOM_SECRET')))
            ], false, 'POST');

            
            
            $this->user->zoom_access_token = $data['access_token'];
            $this->user->zoom_refresh_token = $data['refresh_token'];

            $this->user->save();
            $myinfoUrl = Zoom::my_info;
            $mydata = $this->callApi($myinfoUrl, [], true, [], true, 'GET');
            $this->user->zoom_account_id = $mydata['account_id'];
            $this->user->zoom_user_id = $mydata['id'];

            $this->user->save();
        }
    }

    /**
     * @param $url
     * @param $params
     */
    public function requestAccess($url, $params)
    {
        $url .= '?';
        foreach ($params as $k => $v) {
            $url .= $k . '=' . $v . '&';
        }
        header('Location: ' . filter_var($this->getUrl($url), FILTER_SANITIZE_URL));

        die();
    }

    /**
     * @param $url
     * @param bool $api
     * @return string
     */
    protected function  getUrl($url, $api = false)
    {
        $result = $this->baseUrl . $url;
        if ($api) {
            $result = $this->baseApiUrl . $url;
        }
        return $result;
    }

    /**
     * @return array|mixed|object
     */
    public function getMeetings()
    {
        $data = ['meetings' => []];
        try {
            $data = $this->getData(Zoom::meetings_list, [], true, [], true, 'GET');
        } catch (\Throwable $e) {
            echo $e->getMessage();
        }
        return $data;
    }

    /**
     * @return array|mixed|object
     */
    public function liveStreaming($meeting_id)
    {
        $data = [
            'data' => [],
            'value' => true,
            'message' => ''
        ];

        $unique_key = str_replace("-","",\Str::uuid()->toString()) ;
        $data_input = [
            'stream_url' => self::CUSTOM_LIVE_STREAM_URL,
            'stream_key' => $unique_key,
            'page_url' => env("APP_URL")."/app/stream/".$unique_key
        ];


        try {
            $url = str_replace('{meetingId}', $meeting_id, Zoom::livestream);
            $this->getData($url,  $data_input, true, [], true, 'PATCH');    
            $data['message'] =  "Updated with this stream key: ". $data_input['stream_key'];
            $data['stream_key'] = $data_input['stream_key'];
        } catch (\Throwable $e) {

            $data['value'] = false;
            $data['message'] = $e->getMessage();
        }

        return $data;
    }

    /**
     * @return array|mixed|object
     */
    public function revoke()
    {
        $data = [
            'data' => [],
            'value' => true,
            'message' => ''
        ];
        try {
            $user = User::where('user_id',$this->user->id)->first();
            if (!$user)
                throw new \Exception('Zoom user not found');
            $url = str_replace('{userId}', $user->zoom_user_id, Zoom::revoke);
            $data = $this->getData($url, [], true, [], true, 'DELETE');
        } catch (\Throwable $e) {

            $data['value'] = false;
            $data['message'] = $e->getMessage();
        }
        return $data;
    }
}