<?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: Huỳnh Quốc Dũng</title>
    <description>The latest articles on DEV Community by Huỳnh Quốc Dũng (@hqdung99).</description>
    <link>https://dev.to/hqdung99</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%2F1051936%2Fafc0b8cc-92a5-4e1d-8d75-769f53993cb9.jpeg</url>
      <title>DEV Community: Huỳnh Quốc Dũng</title>
      <link>https://dev.to/hqdung99</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hqdung99"/>
    <language>en</language>
    <item>
      <title>Create call invitation project work like Messenger App using ZegoCloud (ReactJS - step-by-step)</title>
      <dc:creator>Huỳnh Quốc Dũng</dc:creator>
      <pubDate>Sun, 26 Mar 2023 09:35:14 +0000</pubDate>
      <link>https://dev.to/hqdung99/create-call-invitation-project-work-like-messenger-app-using-zegocloud-reactjs-step-by-step-3e3e</link>
      <guid>https://dev.to/hqdung99/create-call-invitation-project-work-like-messenger-app-using-zegocloud-reactjs-step-by-step-3e3e</guid>
      <description>&lt;p&gt;Have you ever wanted to &lt;a href="https://www.zegocloud.com/blog/build-video-call-with-webrtc" rel="noopener noreferrer"&gt;create a call video&lt;/a&gt; app work like Messenger on Facebook? Pick up some friends, call them, and they will receive a notification. They would accept the call invitation, and you can talk with each other.&lt;/p&gt;

&lt;p&gt;In the first place, I think it isn't straightforward to create an app like this because it has many things to set up to do this app. But one day, I learned I don't need to do all the hard work. I found the &lt;a href="https://www.zegocloud.com/" rel="noopener noreferrer"&gt;ZegoCloud platform&lt;/a&gt;, which provides services for us to create a video, call, or chat application with simple steps. I need a little time to &lt;a href="https://www.zegocloud.com/product/video-call" rel="noopener noreferrer"&gt;make my first video call application&lt;/a&gt;. And I will show you how in this article, step by step.&lt;/p&gt;

&lt;p&gt;Let's do it with the following step.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create video-call-invitation ReactJS project
&lt;/h4&gt;

&lt;p&gt;Using create-react-app (If you do not familiar with create-react-app, you can learn more here &lt;a href="https://create-react-app.dev/docs/getting-started" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app video-call-invitation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a React project with the following structure: &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzvypeljcbltorr1ciff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzvypeljcbltorr1ciff.png" alt="Project structure"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Install the call kit plug-in to your project
&lt;/h4&gt;

&lt;p&gt;You need to cd to the root folder and install the plug-in package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; npm i @zegocloud/zego-uikit-prebuilt zego-zim-web --save 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi72o4iv35w7qtob84af.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi72o4iv35w7qtob84af.png" alt="Install ZegoCloud package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change App.js file to this. I import instances from &lt;code&gt;zego-zim-web&lt;/code&gt; and &lt;code&gt;@zegocloud/zego-uikit-prebuilt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// App.js
import React from 'react';
import { ZIM } from "zego-zim-web";
import { ZegoUIKitPrebuilt } from '@zegocloud/zego-uikit-prebuilt';

export default function App() {
  return (
    &amp;lt;div&amp;gt;App&amp;lt;/div&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Create ZegoCloud account, and set up a project to get appID and ServerSecret:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You can sign up for 10.000 free mins monthly here: &lt;a href="https://bit.ly/3yXsodf" rel="noopener noreferrer"&gt;https://bit.ly/3yXsodf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sign up with some simple step &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4h3q5pxkdlwowrqfx6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4h3q5pxkdlwowrqfx6a.png" alt="Signup page"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After sign up and login, access to console admin of ZegoCloud here: &lt;a href="https://console.zegocloud.com/dashboard" rel="noopener noreferrer"&gt;https://console.zegocloud.com/dashboard&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ezt2ce10hhch869k72p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ezt2ce10hhch869k72p.png" alt="Step to create project in ZegoCloud"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Image 0: Click to create your project&lt;br&gt;
Image 1: Select Voice &amp;amp; Video Call&lt;br&gt;
Image 2: Scroll down to the bottom and click Next&lt;br&gt;
Image 3: Fill Project name and click Start with UIKits&lt;br&gt;
Image 4: ZegoCloud will create a new project for you and redirect you to this page. You can click on For web to get the guide for Web setting&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F763lw1m7yhn4scd1xawm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F763lw1m7yhn4scd1xawm.png" alt="Step to get appId and ServerSecret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Image 5: This is some config, you can change the config by toggle switch button, then click Save &amp;amp; start to integrate&lt;br&gt;
Image 6: You can try it out with this demo&lt;br&gt;
Image 7: Click on overview in the sidebar to get a list of your project. Click on your project.&lt;br&gt;
Image 8: Now, you can get appId and ServerSecret for the coding project. This is unique to your project, so don't share it with anyone, ok =)).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  4. Codinggggg
&lt;/h4&gt;

&lt;p&gt;This is the entire code of App.js file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState, useRef } from "react";
import { ZIM } from "zego-zim-web";
import { ZegoUIKitPrebuilt } from "@zegocloud/zego-uikit-prebuilt";

function randomID(len) {
  let result = "";
  if (result) return result;
  var chars = "12345qwertyuiopasdfgh67890jklmnbvcxzMNBVCZXASDQWERTYHGFUIOLKJP",
    maxPos = chars.length,
    i;
  len = len || 5;
  for (i = 0; i &amp;lt; len; i++) {
    result += chars.charAt(Math.floor(Math.random() * maxPos));
  }
  return result;
}

export default function App() {
  const [userInfo, setUserInfo] = useState({
    userName: "",
    userId: "",
  });
  const [calleeId, setCalleeId] = useState("");
  const zeroCloudInstance = useRef(null);

  async function init() {
    const userId = randomID(5);
    const userName = "user_" + userId;
    setUserInfo({
      userName,
      userId,
    });
    const appID = 62xxxx016;
    const serverSecret = "bead82axxxxxx470404736";

    const KitToken = ZegoUIKitPrebuilt.generateKitTokenForTest(
      appID,
      serverSecret,
      null,
      userId,
      userName
    );

    zeroCloudInstance.current = ZegoUIKitPrebuilt.create(KitToken);
    // add plugin
    zeroCloudInstance.current.addPlugins({ ZIM });
  }

  function handleSend(callType) {
    const callee = calleeId;
    if (!callee) {
      alert("userID cannot be empty!!");
      return;
    }

    // send call invitation
    zeroCloudInstance.current
      .sendCallInvitation({
        callees: [{ userID: callee, userName: "user_" + callee }],
        callType: callType,
        timeout: 60,
      })
      .then((res) =&amp;gt; {
        console.warn(res);
        if (res.errorInvitees.length) {
          alert("The user dose not exist or is offline.");
        }
      })
      .catch((err) =&amp;gt; {
        console.error(err);
      });
  }

  useEffect(() =&amp;gt; {
    init();
  }, []);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div&amp;gt;My username: &amp;lt;span&amp;gt;{userInfo.userName}&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;My userId: &amp;lt;span&amp;gt;{userInfo.userId}&amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;input
        type="text"
        is="userId"
        placeholder="callee's userID"
        onChange={(event) =&amp;gt; {
          setCalleeId(event.target.value);
        }}
      /&amp;gt;
      &amp;lt;button
        onClick={() =&amp;gt; {
          handleSend(ZegoUIKitPrebuilt.InvitationTypeVideoCall);
        }}
      &amp;gt;
        Video call
      &amp;lt;/button&amp;gt;
      &amp;lt;button
        onClick={() =&amp;gt; {
          handleSend(ZegoUIKitPrebuilt.InvitationTypeVoiceCall);
        }}
      &amp;gt;
        Voice call
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function randomID(len) used to generate random userId, because it user adds to room need have unique userId
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const [userInfo, setUserInfo] = useState({
    userName: "",
    userId: "",
  });
  const [calleeId, setCalleeId] = useState("");
  const zeroCloudInstance = useRef(null);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;userInfo used to store userName and userId&lt;/li&gt;
&lt;li&gt;calleeId store calleeId, which it will send invitations to.&lt;/li&gt;
&lt;li&gt;zeroCloudInstance using to store ZeroCloud variable used to access API from ZegoUIKitPrebuilt
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  async function init() {
    const userId = randomID(5);
    const userName = "user_" + userId;
    setUserInfo({
      userName,
      userId,
    });
    const appID = 62xxxx016;
    const serverSecret = "bead82a3061xxxxxxx70404736";

    const KitToken = ZegoUIKitPrebuilt.generateKitTokenForTest(
      appID,
      serverSecret,
      null,
      userId,
      userName
    );

    zeroCloudInstance.current = ZegoUIKitPrebuilt.create(KitToken);
    // add plugin
    zeroCloudInstance.current.addPlugins({ ZIM });
  }

  useEffect(() =&amp;gt; {
    init();
  }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;init function used to init variable, it is called from useEffect hook. It inits userId, userName. It uses the generateKitTokenForTest function from ZegoUIKitPrebuilt to create a token to access the server from Zegocloud. It passes the following params - the name shows itself
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(appID, serverSecret, null, userId, userName)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Except for null value, it is roomId value. Because this is called invitation, so we leave null.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ZIM is a call invitation plugin, so we need to add it so we can use the function of call invitation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zeroCloudInstance.current.addPlugins({ ZIM });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;function handleSend use to send call invitations to callee users. It receives callType. We use two call types here: ZegoUIKitPrebuilt.InvitationTypeVideoCall (for Video) and ZegoUIKitPrebuilt.InvitationTypeVoiceCall (for voice).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function handleSend(callType) {
    const callee = calleeId;
    if (!callee) {
      alert("userID cannot be empty!!");
      return;
    }

    // send call invitation
    zeroCloudInstance.current
      .sendCallInvitation({
        callees: [{ userID: callee, userName: "user_" + callee }],
        callType: callType,
        timeout: 60,
      })
      .then((res) =&amp;gt; {
        console.warn(res);
        if (res.errorInvitees.length) {
          alert("The user dose not exist or is offline.");
        }
      })
      .catch((err) =&amp;gt; {
        console.error(err);
      });
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Remember to delete React.Strict mode in index.js file. Because if you not, useEffect will call 2 times, leading to a bug.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zl941vr5zl5nguheopc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zl941vr5zl5nguheopc.png" alt="Delete react strict mode to prevent bug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the result:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zq7u0g6goz8wds39q4c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zq7u0g6goz8wds39q4c.gif" alt="The result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github repositories: &lt;a href="https://github.com/hqdung99/video-call-invitation" rel="noopener noreferrer"&gt;https://github.com/hqdung99/video-call-invitation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is it.&lt;/p&gt;

&lt;p&gt;I think this platform is very useful. It helps me to build a video call application with a very little amount of code to write. Documentation is easy to understand, and examples and live coding are available.&lt;/p&gt;

&lt;p&gt;ZegoCloud has many other features and it supports various platforms, languages, libraries, and frameworks (Android, IOS, flutter, ReactJS, Angular ...)&lt;/p&gt;

&lt;p&gt;I think startups can try UI KIT to build MVP products quickly and with SDK you can deep dive to customize it.&lt;/p&gt;

&lt;p&gt;You can learn more from ZegoCloud website and documentation: &lt;a href="https://www.zegocloud.com/" rel="noopener noreferrer"&gt;https://www.zegocloud.com/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up for 10,000 free mins monthly: &lt;a href="https://bit.ly/3yXsodf" rel="noopener noreferrer"&gt;https://bit.ly/3yXsodf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Find out more about ZEGOCLOUD: &lt;a href="http://bit.ly/3LqKuLY" rel="noopener noreferrer"&gt;http://bit.ly/3LqKuLY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to make video call app: &lt;a href="https://bit.ly/3Ft8Lx5" rel="noopener noreferrer"&gt;https://bit.ly/3Ft8Lx5&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ZEGOCLOUD allows you to easily build your live video chat apps within minutes.&lt;/p&gt;

&lt;p&gt;Refer: &lt;a href="https://docs.zegocloud.com/article/15385" rel="noopener noreferrer"&gt;https://docs.zegocloud.com/article/15385&lt;/a&gt;&lt;/p&gt;

</description>
      <category>zegocloud</category>
      <category>videocall</category>
      <category>reactj</category>
      <category>callinvitation</category>
    </item>
  </channel>
</rss>
