Part 1: Section 2 - Building a meeting application in React with Zoom APIs and SDKs
Published: 2023-02-07 17:52:39

# Set up Zoom Rest APIs & Meeting SDK Backend integrations

In the [first part](https://dev.to/zoom/build-full-stack-meeting-conference-react-application-1no8) of this blog we setup Node.js/Express, organized the files in a way that makes maintenance easy, and used the .env file to securely store the API & SDK keys and secrets. Now we ready to add the backend logic.

### Install dependencies for Meeting SDK JWT

Now let's set up our Meeting SDK JWT SDK signature endpoint which will be used to authorize the Meeting SDK. To begin, in the root folder, run the following command to install the required dependencies: 

```bash
npm i axios btoa jsrsasign
```
____
#### API File

Now we are ready to add our functions to api file which making the HTTP requests and processing the responses from the Zoom Rest APIs. In the api/api.js file, add the following  functions to the code:

```js

// Working File: api/api.js

require("dotenv").config();
const axios = require("axios");
const btoa = require("btoa");

const getAccessToken = async () => {
  try {
    base_64 = btoa(process.env.CLIENT_ID + ":" + process.env.CLIENT_SECRET);

    const resp = await axios({
      method: "POST",
      url:
        "https://zoom.us/oauth/token?grant_type=account_credentials&account_id=" +
        `${process.env.ACCOUNT_ID}`,
      headers: {
        Authorization: "Basic " + `${base_64} `,
      },
    });

    return resp.data.access_token;
  } catch (err) {
    // Handle Error Here
    console.error(err);
  }
};

const listZoomMeetings = async () => {
  try {
    const resp = await axios({
      method: "get",
      url: "https://api.zoom.us/v2/users/me/meetings",
      headers: {
        Authorization: "Bearer " + `${await getAccessToken()} `,
        "Content-Type": "application/json",
      },
    });
    const meetings = resp.data.meetings;

    const newArray = meetings.map((obj) =>
      ["id", "topic"].reduce((newObj, key) => {
        newObj[key] = obj[key];
        return newObj;
      }, {})
    );

    return newArray;
  } catch (err) {
    if (err.status == undefined) {
      console.log("Error : ", err);
    }
  }
};

const createZoomMeeting = async (type) => {
  try {
    

    const data = JSON.stringify({
      type: type,
    });

    const resp = await axios({
      method: "post",
      url: "https://api.zoom.us/v2/users/me/meetings",
      headers: {
        Authorization: "Bearer " + `${await getAccessToken()} `,
        "Content-Type": "application/json",
      },
      data: data,
    });

    const { id, password } = resp.data;

    return { id, password };
  } catch (err) {
    if (err.status == undefined) {
      console.log("Error : ", err);
    }
  }
};
function generateOTP() {
  var digits = "0123456789";
  let OTP = "";
  for (let i = 0; i < 6; i++) {
    OTP += digits[Math.floor(Math.random() * 10)];
  }
  return OTP;
}

// ...

module.exports = {
  createZoomMeeting, 
  listZoomMeetings,
  thirdPartyAPICall,
};

```

____

#### Controllers File
 
The next thing we need to implement are the functions that will be called from the routes to perform the desired actions. In controllers/Zoomcontrollers.js file, add the following Application functions:

* Meeting SDK JWT signature generation endpoint for authorized use of the Meeting SDK.

* Create Appointment Endpoint, which handle creating Zoom Meetings.

* List Meeting Endpoint, which handles get Zoom Meetings.


```js
// Working File: controllers/Zoomcontrollers.js

const asyncHandler = require("express-async-handler");

require("dotenv").config();
const KJUR = require("jsrsasign");

const {
  createZoomMeeting,
  listZoomMeetings,
  thirdPartyAPICall,
  } = require("../api/zoomAPI.js");

  const getMsdkSignature = asyncHandler(async (req, res) => {
    const iat = Math.round(new Date().getTime() / 1000) - 30;
    const exp = iat + 60 * 60 * 2;
  
    const oHeader = { alg: "HS256", typ: "JWT" };
  
    const oPayload = {
      sdkKey: process.env.ZOOM_MSDK_KEY,
      mn: req.body.meetingNumber,
      role: req.body.role,
      iat: iat,
      exp: exp,
      tokenExp: iat + 60 * 60 * 2,
    };
  
    const sHeader = JSON.stringify(oHeader);
    const sPayload = JSON.stringify(oPayload);
    const signature = KJUR.jws.JWS.sign(
      "HS256",
      sHeader,
      sPayload,
      process.env.ZOOM_MSDK_SECRET
    );
  
    res.json({
      signature: signature,
    });
  });

const CreateAppointment = asyncHandler(async (req, res) => {
  const { type} = req.body;

  if (!type) {
    res.status(400);
    throw new Error("Please Fill all the fields");
  } else {
    const { id, password } = await createZoomMeeting(type);

    res.status(201).json({ id, password });
  }
});
  

  const ListMeeting = asyncHandler(async (req, res) => {
    const meetings = await listZoomMeetings();
    if (meetings === undefined) {
      res.status(400);
      throw new Error("No meeting found");
    } else {
      res.status(201).json({ meetings });
    }
  });


// ...

   module.exports = {
    getMsdkSignature,
    CreateAppointment,
    ListMeeting,
    ThirdPartyAPICall,
  };
  

```

___

### routes File

Next, all we need to do is define the endpoint URLs that will  maps incoming requests to the functions. In the zoomRoutes.js, add the getMsdkSignature, CreateAppointment, and ListMeeting endpoints. 
   

```js
// WorkDirectory : backend/routes/
// File : zoomRoutes.js

const express = require('express');
const router = express.Router();
const {
    getMsdkSignature,
    CreateAppointment,
    ListMeeting,
    ThirdPartyAPICall,
  } = require("../controllers/zoomControllers.js");

router.route('/').post();

// Get MSDK Signature Route
router.route("/msig").post(getMsdkSignature);

// Create routes. Test with Postman
router.route("/create").post(CreateAppointment);

// Create routes Test with Postman
router.route("/listmeetings").get(ListMeeting);

// Get routes Test with Postman
router.route("/thirdparty").get(ThirdPartyAPICall);

module.exports = router; // Export the router so it can be used in server.js

```
___

The last thing we need to configure before testing the  backend integration with Zoom API and SDK service is the .env file. This file contains the Zoom Rest APIs and MSDK credentials that should not be accessible to others. It is important to note,your Zoom credential should be stored locally and not be uploaded to code repositories online for everyone to read. 

In the .env file, add the following code, and insert your Zoom API and Meeting SDK Apps's Key and Secret found on the App Credentials page in the Zoom App Marketplace.

```bash
PORT = 30010

# Zoom API Credentials
ACCOUNT_ID = YOUR_ACCOUNT_ID

CLIENT_ID = YOUR_CLIENT_ID

CLIENT_SECRET = YOUR_CLIENT_SECRET

ZOOM_MSDK_KEY =YOUR_ZOOM_MSDK_KEY

ZOOM_MSDK_SECRET =YOUR_ZOOM_MSDK_SECRET

```

___

# Test with Postman

Now it is time to test with Postman and observe the results of GET request for listmeeting and msig endpoints.You should see your Zoom meeting in the response, assuming you have meetings scheduled !

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9se8gteeeg66b3rx2ec.png)

You should see your Zoom MSDK Signature in the response!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bf6ssk1b2ivk6nwn6qj1.png)



```json
{
    "signature": "YOUR_SIGNATURE_RETURNED"
}
```
# Conclusion

In this tutorial, you created a Node.js / Express server that  generates a Zoom Server-to-Server OAuth Token and a Meeting SDK signature via an http request from your frontend for use in the Meeting Conference React Application. In the next section, we will add the frontend for the application to the project.