DEV Community

Diego Oliveira
Diego Oliveira

Posted on

Criando um Sistema de Teleatendimento com Twilio Video e React

Há algum tempo, trabalhei na implementação de um sistema de teleatendimento utilizando Twilio Video para permitir que médicos e pacientes se comunicassem de forma segura e eficiente. Além disso, implementei um mecanismo para que outras pessoas pudessem entrar na sala através de links com tokens de autorização.

Neste artigo, vou compartilhar minha experiência, os desafios enfrentados e como fiz a integração do Twilio Video com React no frontend.

📌 Por que escolhi o Twilio Video?

O Twilio Video é uma solução robusta para chamadas de vídeo, oferecendo segurança, escalabilidade e fácil integração com outras ferramentas. Algumas das razões que me levaram a escolhê-lo incluem:

  • Suporte a múltiplos participantes
  • Baixa latência e qualidade de vídeo ajustável
  • Controle de permissões com tokens JWT
  • APIs bem documentadas

🔧 Configuração do Backend com Twilio

Na empresa, o backend foi desenvolvido em Java, mas aqui vou mostrar a implementação usando Node.js, pois é a tecnologia que mais domino quando se trata de backend.

Para gerar tokens JWT e autenticar usuários no Twilio, podemos criar um pequeno servidor em Node.js com Express:

const express = require("express");
const twilio = require("twilio");
require("dotenv").config();

const app = express();
const port = 3001;

const { TWILIO_ACCOUNT_SID, TWILIO_API_KEY, TWILIO_API_SECRET } = process.env;

app.use(express.json());

app.post("/token", (req, res) => {
    const { identity, room } = req.body;
    const AccessToken = twilio.jwt.AccessToken;
    const VideoGrant = AccessToken.VideoGrant;

    const token = new AccessToken(
        TWILIO_ACCOUNT_SID,
        TWILIO_API_KEY,
        TWILIO_API_SECRET,
        { identity }
    );

    token.addGrant(new VideoGrant({ room }));

    res.json({ token: token.toJwt() });
});

app.listen(port, () => {
    console.log(`Servidor rodando em http://localhost:${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Esse servidor simples gera um token JWT para que os usuários possam ingressar na sala de vídeo com segurança.

🎨 Criando a Interface com React

Com o backend pronto, o próximo passo foi a integração no frontend usando React.

1️⃣ Instalando o SDK do Twilio

No frontend, instalei o pacote necessário:

npm install @twilio/video
Enter fullscreen mode Exit fullscreen mode

2️⃣ Criando a Conexão com a Sala

Dentro do React, criei um hook para conectar o usuário a uma sala de vídeo:

import { useState, useEffect } from "react";
import Video from "twilio-video";

export const useVideoChat = (token, roomName) => {
    const [room, setRoom] = useState(null);
    const [participants, setParticipants] = useState([]);
    const [isMuted, setIsMuted] = useState(false);
    const [isCameraOn, setIsCameraOn] = useState(true);

    useEffect(() => {
        if (token) {
            Video.connect(token, { name: roomName }).then(room => {
                setRoom(room);
                setParticipants([...room.participants.values()]);

                room.on("participantConnected", participant => {
                    setParticipants(prev => [...prev, participant]);
                });

                room.on("participantDisconnected", participant => {
                    setParticipants(prev => prev.filter(p => p !== participant));
                });
            });
        }
    }, [token]);

    const toggleMute = () => {
        setIsMuted(!isMuted);
    };

    const toggleCamera = () => {
        setIsCameraOn(!isCameraOn);
    };

    const leaveRoom = () => {
        room?.disconnect();
        setRoom(null);
    };

    return { room, participants, isMuted, isCameraOn, toggleMute, toggleCamera, leaveRoom };
};
Enter fullscreen mode Exit fullscreen mode

3️⃣ Exibindo o Vídeo e Controles

Por fim, criei um componente VideoRoom para exibir os vídeos dos participantes conectados e adicionar os botões de controle:

import React, { useRef, useEffect, useState } from "react";

const Participant = ({ participant }) => {
    const videoRef = useRef();

    useEffect(() => {
        participant.tracks.forEach(trackPub => {
            if (trackPub.track) {
                videoRef.current.appendChild(trackPub.track.attach());
            }
        });
    }, [participant]);

    return (
        <div>
            <h3>{participant.identity}</h3>
            <div ref={videoRef}></div>
        </div>
    );
};

export const VideoRoom = ({ participants, toggleMute, toggleCamera, leaveRoom }) => {
    const [showModal, setShowModal] = useState(false);
    const shareLink = "https://meusite.com/sala?token=xyz";

    return (
        <div>
            {participants.map(participant => (
                <Participant key={participant.sid} participant={participant} />
            ))}
            <button onClick={toggleMute}>Mutar</button>
            <button onClick={toggleCamera}>Ligar/Desligar Câmera</button>
            <button onClick={() => setShowModal(true)}>Compartilhar</button>
            <button onClick={leaveRoom}>Finalizar Chamada</button>

            {showModal && (
                <div className="modal">
                    <p>Compartilhe este link:</p>
                    <input type="text" value={shareLink} readOnly />
                    <button onClick={() => setShowModal(false)}>Fechar</button>
                </div>
            )}
        </div>
    );
};
Enter fullscreen mode Exit fullscreen mode

🚀 Conclusão

A integração do Twilio Video com React foi uma experiência desafiadora, mas gratificante. O sistema agora permite que médicos e pacientes se comuniquem por vídeo de forma segura, e terceiros podem ingressar na sala com um link autorizado. Além disso, implementei botões para mutar o microfone, ligar/desligar a câmera, compartilhar o link da sala e finalizar a chamada (removendo o usuário da sessão).

Se você estiver pensando em implementar algo similar, recomendo fortemente explorar a documentação oficial do Twilio e testar diferentes configurações para otimizar a experiência do usuário.

Caso tenha dúvidas ou queira compartilhar sua experiência, deixe um comentário! 😊

Top comments (0)