<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: fo-789</title>
    <description>The latest articles on DEV Community by fo-789 (@fo789).</description>
    <link>https://dev.to/fo789</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1124023%2F21e0ff97-6c48-4804-b087-4e7f9f7c4871.png</url>
      <title>DEV Community: fo-789</title>
      <link>https://dev.to/fo789</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fo789"/>
    <language>en</language>
    <item>
      <title>Site Ground Cron Job</title>
      <dc:creator>fo-789</dc:creator>
      <pubDate>Mon, 07 Aug 2023 12:47:21 +0000</pubDate>
      <link>https://dev.to/fo789/site-ground-cron-job-1106</link>
      <guid>https://dev.to/fo789/site-ground-cron-job-1106</guid>
      <description>&lt;p&gt;I recently ran to this task so after search and support I thought about posting it here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dMxP-VYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5fgryxvrhmc8l48vu48e.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dMxP-VYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5fgryxvrhmc8l48vu48e.PNG" alt="Where you should be" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;
This is were you should be you can find it in &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(Site Tools -&amp;gt; Sidebar -&amp;gt; Dev Section -&amp;gt; Cron Jobs)&lt;br&gt;
or&lt;br&gt;
&lt;a href="https://tools.siteground.com/cron-job?siteId=%7BYourSiteId%7D"&gt;https://tools.siteground.com/cron-job?siteId={YourSiteId}&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1- Path
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /home/customer/www/domain/public_html/path/ &amp;amp;&amp;amp; php filname.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty self explanatory&lt;/p&gt;

&lt;h2&gt;
  
  
  2- Interval
&lt;/h2&gt;

&lt;p&gt;You can use the easy dropdown or if you want to add manually This is some info&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use UTC time&lt;/li&gt;
&lt;li&gt;Use 24-hour format&lt;/li&gt;
&lt;li&gt;if you want test set it after 5 or 10 minutes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's It.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ZOOM API</title>
      <dc:creator>fo-789</dc:creator>
      <pubDate>Fri, 21 Jul 2023 14:29:01 +0000</pubDate>
      <link>https://dev.to/fo789/zoom-api-3khm</link>
      <guid>https://dev.to/fo789/zoom-api-3khm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note: This is not a step-by-step guide you should have the basic knowledge&lt;/strong&gt;&lt;br&gt;
==What this post covers==&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replacing Zoom JWT with other zoom apps&lt;/li&gt;
&lt;li&gt;Adding zoom meetings to your personal account via API&lt;/li&gt;
&lt;li&gt;Allow Users to join zoom meetings without account through your website &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eStOLVZG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yn037knpq8y9apawag0a.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eStOLVZG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yn037knpq8y9apawag0a.PNG" alt="Joining through website" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have been busy to update my zoom integration after &lt;a href="https://developers.zoom.us/docs/internal-apps/jwt-faq/"&gt;JWT App type deprecation&lt;/a&gt; But 2days before I finally sat down to update it I took me 5HOURS of research just to understand it many many zoom links are broken and thanks to Max M for his clear answers in zoom developer forum&lt;/p&gt;
&lt;h2&gt;
  
  
  1. CREATE ZOOM MEETING API
&lt;/h2&gt;

&lt;p&gt;First You have to create 2 different apps&lt;br&gt;
For creating meeting through API you would have to create a Server-to-Server Oauth By going to &lt;a href="https://marketplace.zoom.us/develop/create"&gt;https://marketplace.zoom.us/develop/create&lt;/a&gt; and choosing the Server-to-Server Oauth complete the creation process these are the required scopes to create delete and record meetings and webinars&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;View all user meetings /meeting:read:admin&lt;br&gt;
View and manage all user meetings /meeting:write:admin&lt;br&gt;
View all user recordings /recording:read:admin&lt;br&gt;
View and manage all user recordings /recording:write:admin&lt;br&gt;
View all user Webinars /webinar:read:admin&lt;br&gt;
View and manage all user Webinars /webinar:write:admin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I did not write this code can't remember where I got it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createAMeeting($data = array()) {
    $post_time           = $data['date'];
    $start_time          = gmdate("Y-m-d\TH:i:s", strtotime($post_time));
    $createAMeetingArray = array();
    if (!empty($data['alternative_host_ids'])) {
        if (count($data['alternative_host_ids']) &amp;gt; 1) {
            $alternative_host_ids = implode(",", $data['alternative_host_ids']);
        } else {
            $alternative_host_ids = $data['alternative_host_ids'][0];
        }
    }
    $createAMeetingArray['topic']      = $data['title'];
    $createAMeetingArray['agenda']     = "";
    $createAMeetingArray['type']       = !empty($data['type']) ? $data['type'] : 2; //Scheduled
    $createAMeetingArray['weekly_days']= [1,2,3,4,5,6,7]; 
    $createAMeetingArray['start_time'] = $start_time;
    $createAMeetingArray['timezone']   = 'SA';
    $createAMeetingArray['password']   = !empty($data['password']) ? $data['password'] : "";
    $createAMeetingArray['duration']   = !empty($data['duration']) ? $data['duration'] : 60;
    $createAMeetingArray['settings']   = array(
        'join_before_host'  =&amp;gt; true,
        'host_video'        =&amp;gt;  true,
        'waiting_room'    =&amp;gt;  true,
        'participant_video' =&amp;gt; true,
        'mute_upon_entry'   =&amp;gt; false,
        'enforce_login'     =&amp;gt; false,
        'auto_recording'    =&amp;gt; "none",
        'private_meeting'      =&amp;gt; true,
        'alternative_hosts' =&amp;gt; isset($alternative_host_ids) ? $alternative_host_ids : "",
    );
    return sendRequest($createAMeetingArray);
}
function sendRequest($data){


    $request_url = 'https://api.zoom.us/v2/users/me/meetings';
    $headers     = array(
        'authorization: Bearer ' . generateJWTKey(),
        'content-type: application/json',
    );
    $postFields = json_encode($data);
    $ch         = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $request_url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $response    = curl_exec($ch);
    $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err         = curl_error($ch);
    curl_close($ch);
    if (!$response) {
        return false;
    }

    return json_decode($response);
}

function generateJWTKey()
{
    $zoom_api_key    = ZOOM_API_KEY;
    $zoom_api_secret = ZOOM_API_SECRET;

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, 'https://zoom.us/oauth/token');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=account_credentials&amp;amp;account_id={NOT-THE-PROFILE-ID-THE-APP-ID");

    $headers = array();
    $headers[] = 'Host: zoom.us';
    $headers[] = 'Authorization: Basic '.base64_encode($zoom_api_key.':'.$zoom_api_secret);
    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $result = json_decode(curl_exec($ch));
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close($ch);

    return $result-&amp;gt;access_token;`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Join From Web SDK
&lt;/h2&gt;

&lt;p&gt;Navigate back to the create app choose meeting SDK and go through the steps &lt;br&gt;
Do not forget to download the sample code and this is as I believe a more explanatory page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

    use \Firebase\JWT\JWT;

    //Validate if user is allowed to join



    function generate_signature($sdkKey, $sdkSecret, $meetingNumber, $role) {
        $iat = time();
        $exp = $iat + 60 * 60 * 2;

        $token_payload = [
          "sdkKey"=&amp;gt; $sdkKey,
          "mn"=&amp;gt; $meetingNumber,
          "role"=&amp;gt; $role,
          "iat"=&amp;gt; $iat,
          "exp"=&amp;gt; $exp,
          "tokenExp"=&amp;gt; $exp
        ];
        $token_header = [
          'alg'=&amp;gt; 'HS256',
          'typ'=&amp;gt; 'JWT'
        ];
        $jwt = JWT::encode($token_payload, $sdkSecret);

        return $jwt;
    }

?&amp;gt;


&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en" dir="ltr"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;title&amp;gt;{YOUR_TITLE}&amp;lt;/title&amp;gt;

    &amp;lt;!-- For Client View --&amp;gt;
    &amp;lt;link type="text/css" rel="stylesheet" href="https://source.zoom.us/2.14.0/css/bootstrap.css" /&amp;gt;
    &amp;lt;link type="text/css" rel="stylesheet" href="https://source.zoom.us/2.14.0/css/react-select.css" /&amp;gt;
    &amp;lt;link rel="shortuct icon" type="image/png" href="favicon url"&amp;gt;
    &amp;lt;link rel="stylesheet" href="styles.css"&amp;gt;

    &amp;lt;!-- Origin Trials to enable Gallery View in Chrome/Edge --&amp;gt;
    &amp;lt;!-- More Info: https://developers.zoom.us/docs/meeting-sdk/web/gallery-view/ --&amp;gt;
    &amp;lt;!-- SharedArrayBuffers in non-isolated pages on Desktop platforms --&amp;gt;
    &amp;lt;meta https-equiv="origin-trial" content=""&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;

    &amp;lt;main&amp;gt;
      &amp;lt;h1&amp;gt;Processing View...&amp;lt;/h1&amp;gt;

      &amp;lt;!-- For Component View --&amp;gt;
      &amp;lt;div id="meetingSDKElement"&amp;gt;
        &amp;lt;!-- Zoom Meeting SDK Rendered Here --&amp;gt;
      &amp;lt;/div&amp;gt;

    &amp;lt;/main&amp;gt;

    &amp;lt;!-- For Component and Client View --&amp;gt;
    &amp;lt;script src="https://source.zoom.us/2.14.0/lib/vendor/react.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="https://source.zoom.us/2.14.0/lib/vendor/react-dom.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="https://source.zoom.us/2.14.0/lib/vendor/redux.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="https://source.zoom.us/2.14.0/lib/vendor/redux-thunk.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="https://source.zoom.us/2.14.0/lib/vendor/lodash.min.js"&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;!-- For Client View --&amp;gt;
    &amp;lt;script src="https://source.zoom.us/zoom-meeting-2.14.0.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;!-- &amp;lt;script type="text/javascript" src="client-view.js"&amp;gt;&amp;lt;/script&amp;gt; --&amp;gt;
    &amp;lt;script&amp;gt;
      ZoomMtg.setZoomJSLib('https://source.zoom.us/2.14.0/lib', '/av')

      ZoomMtg.preLoadWasm()
      ZoomMtg.prepareWebSDK()
      // loads language files, also passes any error messages to the ui
      ZoomMtg.i18n.load('en-US')
      ZoomMtg.i18n.reload('en-US')

      var authEndpoint = ''
      var sdkKey = '&amp;lt;?= ZOOM_SDK_KEY ?&amp;gt;'
      var role = 0
      var userEmail = ''
      var registrantToken = ''
      var zakToken = ''
      var leaveUrl = '&amp;lt;?= $leaveUrl ?&amp;gt;'
      var meetingNumber = '&amp;lt;?= $meetingID ?&amp;gt;'
      var userName = '&amp;lt;?= $name ?&amp;gt;'
      var passWord = '&amp;lt;?= $room_password ?&amp;gt;'
      var signature = '&amp;lt;?= generate_signature(ZOOM_SDK_KEY, ZOOM_SDK_SECRET, $meetingID, $role); ?&amp;gt;'


        document.getElementById('zmmtg-root').style.display = 'block'

        ZoomMtg.init({
          leaveUrl: leaveUrl,
          success: (success) =&amp;gt; {
            console.log(success)
            ZoomMtg.join({
              sdkKey: sdkKey,
              signature: signature,
              meetingNumber: meetingNumber,
              passWord: passWord,
              userName: userName,
              success: (success) =&amp;gt; {
                console.log(success)
              },
              error: (error) =&amp;gt; {
                console.log(error)
              },
            })
          },
          error: (error) =&amp;gt; {
            console.log(error)
          }
        })

    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hardest part was not the code it was understanding what I am supposed to do and what apps to create wish this will save someone's time comment if any issues appear&lt;br&gt;
resources:&lt;br&gt;
&lt;a href="https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetingCreate"&gt;Create Zoom Meeting API Docs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://devforum.zoom.us/"&gt;Zoom Developer Forum&lt;/a&gt;&lt;/p&gt;

</description>
      <category>zoom</category>
      <category>api</category>
      <category>jwt</category>
    </item>
  </channel>
</rss>
