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! 😊

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay