Sample code for PHP with Zoom API / Zoom SDK

This is a sample code page for PHP. It shows the common code sample when interacting with Zoom Webhook, Zoom Meeting SDK Auth Signature, Zoom OAuth and Zoom REST API.

Github Link

github source code

Live Demo

webhook
s2soauth
redirecturlforoauth?code=xxxx
oauthrefreshtoken?code=xxxx
oauthrefreshtoken?code=xxxx (curl library)

Meeting SDK Token (firebase library)
Meeting SDK Token

call API
application adding url


Code Samples

Tab 1 Content

  

$config = include 'config.php';
$secretToken = $config['webhook_app_secret_token'];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // This block handles POST requests

    // Get the raw POST data from the request
    $input = file_get_contents("php://input");

    // Decode the JSON data
    $data = json_decode($input);

    // Check if the event type is "endpoint.url_validation"
    if ($data && isset($data->event) && $data->event === "endpoint.url_validation") {
        // Check if the payload contains the "plainToken" property
        if (isset($data->payload) && isset($data->payload->plainToken)) {
            // Get the plainToken from the payload
            $plainToken = $data->payload->plainToken;

            // Hash the plainToken using HMAC-SHA256
            $encryptedToken = hash_hmac("sha256", $plainToken, $secretToken);

            // Create the response JSON object
            $response = [
                "plainToken" => $plainToken,
                "encryptedToken" => $encryptedToken
            ];

            // Set the response HTTP status code to 200 OK
            http_response_code(200);

            // Set the response content type to JSON
            header("Content-Type: application/json");

            // Output the response JSON
            echo json_encode($response);

        } else {
            // Payload is missing the "plainToken" property
            http_response_code(400); // Bad Request
            echo "Payload is missing 'plainToken' property.";
        }
    } else {

        try{
        // Save the JSON data to a file
        $jsonFileName = '/var/www/php.asdc.cc/webhook.txt'; // Set the filename
        file_put_contents($jsonFileName, json_encode($data));
        echo "Data Saved: " .  json_encode($data);
        }
        catch(Exception $e){
            echo "An error occurred: " . $e->getMessage();
        }
    }
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') {
    // This block handles GET requests

    $jsonFileName = '/var/www/php.asdc.cc/webhook.txt'; 
    // Check if the file 'token.txt' exists
    if (file_exists('/var/www/php.asdc.cc/webhook.txt')) {
        try{
         // Read the JSON data from the file
         $jsonContents = file_get_contents($jsonFileName);

        // Parse the JSON data into a PHP object
        $jsonData = json_decode($jsonContents);

        // Convert the PHP object back to a JSON string
        $jsonString = json_encode($jsonData);

        // Echo the JSON string
        echo $jsonString;
        }
        catch(Exception $e){
            echo "An error occurred: " . $e->getMessage();
        }
    } else {
        // Token file does not exist
        echo "Token file does not exist.";
    }
} else {
    // Unsupported HTTP method
    http_response_code(405); // Method Not Allowed
    echo "Unsupported HTTP method.";
}


Tab 2 Content

  
$config = include 'config.php';


// Access the environment variables
$clientId  = $config['s2s_oauth_client_id'];
$clientSecret  = $config['s2s_oauth_client_secret'];
$accountId= $config['s2s_oauth_account_id'];
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId;  // Replace with your OAuth endpoint URL


    global $clientSecret, $clientId, $oauthUrl;


    try {
        // Create the Basic Authentication header
        $authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
     
        // Initialize cURL session
        $ch = curl_init($oauthUrl);

        // Set cURL options
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $authHeader));

        // Execute cURL session and get the response
        $response = curl_exec($ch);

        // Check if the request was successful (status code 200)
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($httpCode == 200) {
            // Parse the JSON response to get the access token
            $oauthResponse = json_decode($response, true);
            $accessToken = $oauthResponse['access_token'];
            //return $accessToken;
            http_response_code(200); // Replace 200 with your desired status code
            // Set the "Content-Type" header to "application/json"
            header('Content-Type: application/json');
            echo json_encode($accessToken);
      
            
        } else {
            echo 'OAuth Request Failed with Status Code: ' . $httpCode . PHP_EOL;
            echo $response . PHP_EOL;
            return null;
        }

        // Close cURL session
        curl_close($ch);
    } catch (Exception $e) {
        echo 'An error occurred: ' . $e->getMessage() . PHP_EOL;
        return null;
    }

    
    

Tab 3 Content

 
$config = include 'config.php';
$oauthClientId = $config['oauth_client_id'];
$oauthClientSecret = $config['oauth_client_secret'];


$path='redirecturlforoauth.php';
$code =$_GET['code'];


    //echo "handleRedirectUrlDataRequest\n";
    $url = "https://zoom.us/oauth/token";
    $redirectUri = "https://php.asdc.cc/$path";
    //echo "$redirectUri\n";
    
    // Encode the client ID and client secret
    $credentials = "$oauthClientId:$oauthClientSecret";
    //echo "$credentials\n";
    $credentialsEncoded = base64_encode($credentials);

    $headers = [
        "Authorization: Basic $credentialsEncoded",
        "Content-Type: application/x-www-form-urlencoded"
    ];
    //echo "$credentialsEncoded\n";

    $data = [
        'grant_type' => 'authorization_code',
        'redirect_uri' => $redirectUri,
        'code' => $code
    ];
     //echo "$data\n";
    // Encode the data dictionary as x-www-form-urlencoded
    $dataEncoded = http_build_query($data);
    //echo "$dataEncoded\n";
    $options = [
        'http' => [
            'header' => implode("\r\n", $headers),
            'method' => 'POST',
            'content' => $dataEncoded
        ]
    ];
    $context = stream_context_create($options);
   
    $response = file_get_contents($url, false, $context);
    
    $httpStatus = $http_response_header[0]; // Get the HTTP status from the headers

    if (strpos($httpStatus, '200 OK') !== false) {
        //echo "response 200\n";
        $responseJson = json_decode($response, true); // Decode JSON as associative array
        
        // Optionally, you can return an HTTP status code
        http_response_code(200); // Replace 200 with your desired status code
        
        // Set the "Content-Type" header to "application/json"
        header('Content-Type: application/json');

        // Encode the JSON data and return it
        echo json_encode($responseJson);

   
    } else {
        // Handle the case where the response has an error status code
        echo "$httpStatus\n";
    }




Tab 4 Content

  
// Step 1: Include Composer's autoload.php
require 'vendor/autoload.php';

// Step 2: Import the Firebase JWT class
use Firebase\JWT\JWT;


$config = include 'config.php';
$meetingSDKClientKey=$config['meetingSDKClientKey'];
$meetingSDKClientSecret= $config['meetingSDKClientSecret'];


$iat = time();
$exp = $iat + 60 * 60 * 2;
$token_payload = [

    'sdkKey' => $meetingSDKClientKey,
    'mn' => 9898533313,
    'role' => 1,
    'iat' => $iat,
    'exp' => $exp,
    'tokenExp' => $exp
];

$jwt = JWT::encode($token_payload, $meetingSDKClientSecret, 'HS256');
echo $jwt;

Tab 5 Content

  
$config = include 'config.php';
$meetingSDKClientKey = $config['meetingSDKClientKey'];
$meetingSDKClientSecret = $config['meetingSDKClientSecret'];


$iat = time()    - 30;
$exp = $iat + 60 * 60 * 10;
//$client_request = $this->request->input('json_decode');

// Define the payload data for your JWT token
$token_payload = [
    'sdkKey' => $meetingSDKClientKey,
    'mn' => 9898533313,
    'role' => 1,
    'iat' => $iat, // Issued at timestamp
    'exp' => $exp,  // Expiration timestamp (2 hours from now)
    'appKey' => $meetingSDKClientKey,
    'tokenExp' => $exp 
];

// Encode the JWT token
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$payload = json_encode($token_payload);

$headers_encoded = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
$payload_encoded = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

$signature = hash_hmac('sha256', $headers_encoded . '.' . $payload_encoded, $meetingSDKClientSecret, true);
$signature_encoded = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

$jwt = $headers_encoded . '.' . $payload_encoded . '.' . $signature_encoded;

echo $jwt;


Tab 6 Content

  
$config = include 'config.php';
$oauthClientId=$config['oauth_client_id'];
$oauthClientSecret= $config['oauth_client_secret'];
$refreshToken=$_GET['code'];



    $url = 'https://zoom.us/oauth/token';


    // Encode the client ID and client secret
    $credentials = "$oauthClientId:$oauthClientSecret";
   
    $credentialsEncoded = base64_encode($credentials);

    $headers = [
        "Authorization: Basic $credentialsEncoded",
        "Content-Type: application/x-www-form-urlencoded"
    ];
  

    $data = [
        'grant_type' => 'refresh_token',
        'refresh_token' => $refreshToken,
    ];
   
    // Encode the data dictionary as x-www-form-urlencoded
    $dataEncoded = http_build_query($data);
    
    $options = [
        'http' => [
            'header' => implode("\r\n", $headers),
            'method' => 'POST',
            'content' => $dataEncoded
        ]
    ];
    $context = stream_context_create($options);
   
    $response = file_get_contents($url, false, $context);
    
    $httpStatus = $http_response_header[0]; // Get the HTTP status from the headers

    if (strpos($httpStatus, '200 OK') !== false) {
        //echo "response 200\n";
        $responseJson = json_decode($response, true); // Decode JSON as associative array
        
        // Optionally, you can return an HTTP status code
        http_response_code(200); // Replace 200 with your desired status code
        
        // Set the "Content-Type" header to "application/json"
        header('Content-Type: application/json');

        // Encode the JSON data and return it
        echo json_encode($responseJson);

   
    } else {
        // Handle the case where the response has an error status code
        echo "$httpStatus\n";
    }
    

Tab 7 Content

  
$config = include 'config.php';
$oauthClientId=$config['oauth_client_id'];
$oauthClientSecret= $config['oauth_client_secret'];
$refreshToken=$_GET['code'];



$url = 'https://zoom.us/oauth/token';

// Encode the client ID and client secret
$basic = base64_encode($oauthClientId . ':' . $oauthClientSecret);

$headers = [
    "Authorization: Basic $basic",
    "Content-Type: application/x-www-form-urlencoded"
];

$data = [
    'grant_type' => 'refresh_token',
    'refresh_token' => $refreshToken,
];

// Encode the data dictionary as x-www-form-urlencoded
$dataEncoded = http_build_query($data);

$options = [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => $dataEncoded,
];

$ch = curl_init();
curl_setopt_array($ch, $options);

$response = curl_exec($ch);
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

if (strpos($httpStatus, '200') !== false) {
    $responseJson = json_decode($response, true);
    http_response_code(200);
    header('Content-Type: application/json');
    echo json_encode($responseJson);
    //echo $response;
} else {
    echo "$httpStatus\n";
}


Tab 8 Content

  
#$access_token =$_GET['accesstoken'];
$access_token = 'xxxx.yyyy.zzzz';

$meeting_data = [
    "topic" =>  'hello world',
    "type" => 2,
    "start_time" => "2023-10-01T10:00:00Z",
    "duration" =>  120,
    "password" => "12345678",
    "agenda" => "40 mins limit demonstration",
    "pre_schedule" => false,
    "timezone"=> "Asia/Singapore",
    "default_password" => false
];

$api_url = 'https://api.zoom.us/v2/users/me/meetings';
$ch_meeting = curl_init($api_url );


curl_setopt($ch_meeting, CURLOPT_HTTPHEADER, array(
  "Authorization: Bearer $access_token",
  'Content-Type: application/json',
  'Accept: application/json'
));

curl_setopt($ch_meeting, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch_meeting, CURLOPT_POSTFIELDS, json_encode($meeting_data));
curl_setopt($ch_meeting, CURLOPT_RETURNTRANSFER, true);

    $meeting_response = curl_exec($ch_meeting);
    echo "Détails de la réunion : ";
    echo $meeting_response;

$this->revokeAccessToken($CLIENT_ID, $CLIENT_SECRET, $access_token);