Cómo crear una aplicación de chat grupal con Vanilla JS, Twilio y Node.js

 

 

 

  • ¡Registro!
  • Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX

  • Índice
    1. Requisitos previos
    2. La aplicación de fondo
      1. Iniciador del proyecto
      2. Dependencias
      3. Configuración
      4. Obtener credenciales de Twilio desde la consola
      5. Utilidades
      6. Controladores
      7. Rutas
      8. La aplicación de fondo
    3. El front-end
      1. Dependencias
      2. La página de índice
      3. La página de errores
      4. La página de conversaciones
      5. La página de chat

    En este tutorial, aprenderá cómo crear una aplicación de chat grupal. Creará una aplicación de backend utilizando Node.js que realizará chats grupales, autorizará a los participantes del chat y mantendrá sesiones para ellos. El front-end se construirá utilizando Vanilla JS, HTML y CSS. Permitirá a los usuarios iniciar sesión, crear nuevos grupos, invitar amigos e intercambiar mensajes. Al final, debería tener una aplicación funcional donde varios participantes puedan enviar mensajes en un grupo.

     

    El chat se está convirtiendo en un medio de comunicación cada vez más popular tanto en contextos empresariales como sociales. Las empresas utilizan el chat para la comunicación dentro de la empresa con clientes y empleados, como con Slack , Microsoft Teams , Chanty , HubSpot Live Chat , Help Scout , etc. La mayoría de las redes sociales y aplicaciones de comunicación también ofrecen chat como una opción predeterminada, como en Instagram, Facebook, Reddit y Twitter. Otras aplicaciones como Discord, Whatsapp y Telegram se basan principalmente en chats, siendo los chats grupales una de sus principales funcionalidades.

     

    Si bien existen numerosos productos para facilitar el chat, es posible que necesite una solución personalizada para su sitio que se ajuste a sus necesidades de comunicación particulares. Por ejemplo, muchos de estos productos son aplicaciones independientes y es posible que no puedan integrarse en su propio sitio. Hacer que sus usuarios abandonen su sitio web para chatear puede no ser la mejor opción, ya que puede afectar la experiencia del usuario y la conversión. Por otro lado, crear una aplicación de chat desde cero puede ser una tarea desalentadora y, a veces, abrumadora. Sin embargo, al utilizar API como Twilio Conversations, puedes simplificar el proceso de creación. Estas API de comunicación manejan la creación de grupos, agregar participantes, enviar mensajes, notificaciones, entre otras funciones importantes de chat. Las aplicaciones de backend que utilizan estas API solo tienen que manejar la autenticación y realizar llamadas a estas API. Luego, las aplicaciones de front-end muestran conversaciones, grupos y mensajes desde el backend.

    En este tutorial, aprenderá cómo crear una aplicación de chat grupal utilizando la API de conversaciones de Twilio . La interfaz de esta aplicación se creará utilizando HTML, CSS y Vanilla JavaScript. Permitirá a los usuarios crear chats grupales, enviar invitaciones, iniciar sesión y enviar y recibir mensajes. El backend será una aplicación Node.js. Proporcionará tokens de autenticación para los invitados al chat y gestionará la creación del chat.

    Requisitos previos

    Antes de poder comenzar este tutorial, debe tener lo siguiente:

    • Node.js instalado. Lo usará principalmente para la aplicación de backend y para instalar dependencias en la aplicación de frontend.
      Puede obtenerlo utilizando un instalador prediseñado disponible en la página de descargas de Node.js.
    • Una cuenta de Twilio .
      Puede crear uno en el sitio web de Twilio en este enlace .
    • http-serverpara servir la aplicación front-end.
      Puedes instalarlo ejecutando npm i -g http-server. También puedes ejecutarlo npx http-serverpara ejecuciones únicas.
    • MongoDB para almacenamiento de sesiones en la aplicación backend.
      Su página de instalación tiene una guía detallada sobre cómo hacerlo funcionar.

    La aplicación de fondo

    Para enviar mensajes de chat usando la API de Twilio, necesita una conversación . Los mensajes de chat se envían y reciben dentro de una conversación. Las personas que envían los mensajes se denominan participantes . Un participante solo puede enviar un mensaje dentro de una conversación si está agregado a ella. Tanto las conversaciones como los participantes se crean utilizando la API de Twilio. La aplicación backend realizará esta función.

     

    Un participante necesita un token de acceso para enviar un mensaje y recibir sus conversaciones suscritas. La parte inicial de este proyecto utilizará este token de acceso. La aplicación backend crea el token y lo envía al frontend. Allí se utilizará para cargar conversaciones y mensajes.

    Iniciador del proyecto

    Llamarás a la aplicación backend twilio-chat-server. Un iniciador de proyecto estructurado está disponible en Github . Para clonar el proyecto y obtener el iniciador, ejecute:

    git clone https://github.com/zaracooper/twilio-chat-server.gitcd twilio-chat-servergit checkout starter

    La aplicación backend toma esta estructura:

    .├── app.js├── config/├── controllers/├── package.json├── routes/└── utils/

    Para ejecutar la aplicación, usará el node index.jscomando.

    Dependencias

    La aplicación backend necesita 8 dependencias. Puedes instalarlos ejecutando:

    npm i 

    Aquí hay una lista de cada una de las dependencias:

    • connect-mongose conecta a MongoDB, que utilizará como almacén de sesiones;
    • corsmaneja CORS ;
    • dotenvcarga variables de entorno desde el .envarchivo que creará en un paso posterior;
    • expresses el marco web que usarás para el backend;
    • express-sessionproporciona middleware para manejar datos de sesión;
    • http-errorsayuda a crear errores en el servidor;
    • morganmaneja el registro;
    • twiliocrea el cliente Twilio, genera tokens, crea conversaciones y agrega participantes.

    Configuración

    La configcarpeta es responsable de cargar la configuración desde las variables de entorno. La configuración se agrupa en tres categorías: configuración para CORS, Twilio y la base de datos de sesión MongoDB. Cuando el entorno sea development, cargará configdesde el .envarchivo usando dotenv.

    Comience creando el .envarchivo en la terminal. Este archivo ya está agregado al .gitignorearchivo para evitar que los valores confidenciales que contiene se registren en el repositorio.

    touch .env

    Así es como .envdebería verse:

    # Session DB ConfigSESSION_DB_HOST=XXXXSESSION_DB_USER=XXXXSESSION_DB_PASS=XXXXSESSION_DB_PORT=XXXXSESSION_DB_NAME=XXXXSESSION_DB_SECRET=XXXX# Twilio ConfigTWILIO_ACCOUNT_SID=XXXXTWILIO_AUTH_TOKEN=XXXXTWILIO_API_KEY=XXXXTWILIO_API_SECRET=XXXX# CORS Client ConfigCORS_CLIENT_DOMAIN=XXXX

    Puede aprender cómo crear un usuario para su base de datos de sesión en esta entrada del manual de MongoDB . Una vez que cree una base de datos de sesión y un usuario que pueda escribir en ella, puede completar los valores SESSION_DB_USER, SESSION_DB_PASSy SESSION_DB_NAME. Si está ejecutando una instancia local de MongoDB, SESSION_DB_HOSTsería localhost, y SESSION_DB_PORTnormalmente es 27017. express-session SESSION_DB_SECRETutiliza el para firmar la cookie de ID de sesión y puede ser cualquier cadena secreta que establezca.

     

    En el siguiente paso, obtendrá las credenciales de Twilio Console . Las credenciales deben asignarse a las variables con el TWILIO_prefijo. Durante el desarrollo local, el cliente front-end se ejecutará en https://localhost:3000 . Entonces, puede usar este valor para la CORS_CLIENT_DOMAINvariable de entorno.

    Agregue el siguiente código para config/index.jscargar variables de entorno.

    import dotenv from 'dotenv';if (process.env.NODE_ENV == 'development') { dotenv.config();}const corsClient = { domain: process.env.CORS_CLIENT_DOMAIN};const sessionDB = { host: process.env.SESSION_DB_HOST, user: process.env.SESSION_DB_USER, pass: process.env.SESSION_DB_PASS, port: process.env.SESSION_DB_PORT, name: process.env.SESSION_DB_NAME, secret: process.env.SESSION_DB_SECRET};const twilioConfig = { accountSid: process.env.TWILIO_ACCOUNT_SID, authToken: process.env.TWILIO_AUTH_TOKEN, apiKey: process.env.TWILIO_API_KEY, apiSecret: process.env.TWILIO_API_SECRET};const port = process.env.PORT || '8000';export { corsClient, port, sessionDB, twilioConfig };

    Las variables de entorno se agrupan en categorías según lo que hacen. Cada una de las categorías de configuración tiene su propia variable de objeto y todas se exportan para usarlas en otras partes de la aplicación.

    Obtener credenciales de Twilio desde la consola

    Para construir este proyecto, necesitará cuatro credenciales de Twilio diferentes: un SID de cuenta , un token de autenticación , una clave API y un secreto API . En la consola, en la página Configuración general , desplácese hacia abajo hasta la sección Credenciales API . Aquí es donde encontrará el SID de su cuenta y el token de autenticación .

    Sección Credenciales API en la página Configuración general . ( Vista previa grande )

    Para obtener una clave API y un secreto , vaya a la página Claves API . Puedes verlo en la captura de pantalla a continuación. Haga clic en el +botón para ir a la página Nueva clave API .

    API KeyBotón Crear en la página de lista de claves API. ( Vista previa grande )

    En esta página, agregue un nombre de clave y déjelo KEY TYPEcomo Standardy luego haga clic en Create API Key. Copie la clave API y el secreto. Agregará todas estas credenciales en un .envarchivo como verá en los pasos siguientes.

    Nueva página de clave API. ( Vista previa grande )

    Utilidades

    La aplicación backend necesita dos funciones de utilidad. Uno creará un token y el otro empaquetará los controladores asíncronos y manejará los errores por ellos.

    En utils/token.js, agregue el siguiente código para crear una función llamada createTokenque generará tokens de acceso de Twilio:

    import { twilioConfig } from '../config/index.js';import twilio from 'twilio';function createToken(username, serviceSid) { const AccessToken = twilio.jwt.AccessToken; const ChatGrant = AccessToken.ChatGrant; const token = new AccessToken( twilioConfig.accountSid, twilioConfig.apiKey, twilioConfig.apiSecret, { identity: username } ); const chatGrant = new ChatGrant({ serviceSid: serviceSid, }); token.addGrant(chatGrant); return token.toJwt();}

    En esta función, genera tokens de acceso utilizando el SID de su cuenta , la clave API y el secreto API . Opcionalmente, puede proporcionar una identidad única que podría ser un nombre de usuario, correo electrónico, etc. Después de crear un token, debe agregarle una concesión de chat . La concesión de chat puede tomar un ID de servicio de conversación, entre otros valores opcionales. Por último, convertirá el token en un JWT y lo devolverá.

     

    El utils/controller.jsarchivo contiene una asyncWrapperfunción que envuelve las funciones del controlador asíncrono y detecta cualquier error que arrojen. Pegue el siguiente código en este archivo:

    function asyncWrapper(controller) { return (req, res, next) = Promise.resolve(controller(req, res, next)).catch(next);}export { asyncWrapper, createToken };

    Controladores

    La aplicación backend tiene cuatro controladores: dos para autenticación y dos para manejar conversaciones. El primer controlador de autenticación crea un token y el segundo lo elimina. Uno de los controladores de conversaciones crea nuevas conversaciones , mientras que el otro agrega participantes a las conversaciones existentes.

    Controladores de conversación

    En el controllers/conversations.jsarchivo, agregue estas importaciones y código para el StartConversationcontrolador:

    import { twilioConfig } from '../config/index.js';import { createToken } from '../utils/token.js';import twilio from 'twilio';async function StartConversation(req, res, next) { const client = twilio(twilioConfig.accountSid, twilioConfig.authToken); const { conversationTitle, username } = req.body; try { if (conversationTitle username) { const conversation = await client.conversations.conversations .create({ friendlyName: conversationTitle }); req.session.token = createToken(username, conversation.chatServiceSid); req.session.username = username; const participant = await client.conversations.conversations(conversation.sid) .participants.create({ identity: username }) res.send({ conversation, participant }); } else { next({ message: 'Missing conversation title or username' }); } } catch (error) { next({ error, message: 'There was a problem creating your conversation' }); }}

    El StartConversationcontrolador primero crea un Twilio clientusando tu twilioConfig.accountSidy twilioConfig.authTokendel que obtienes config/index.js. Mejores Opiniones y reviews

    A continuación, crea una conversación. Para ello necesita un título de conversación, que obtiene del cuerpo de la solicitud. Es necesario agregar un usuario a una conversación antes de que pueda participar en ella. Un participante no puede enviar un mensaje sin un token de acceso. Entonces, genera un token de acceso usando el nombre de usuario proporcionado en el cuerpo de la solicitud y el archivo conversation.chatServiceSid. Luego se agrega a la conversación el usuario identificado por el nombre de usuario. El controlador completa respondiendo con la conversación y el participante recién creados.

     

    A continuación, debe crear el AddParticipantcontrolador. Para hacer esto, agregue el siguiente código debajo de lo que acaba de agregar en el controllers/conversations.jsarchivo anterior:

    async function AddParticipant(req, res, next) { const client = twilio(twilioConfig.accountSid, twilioConfig.authToken); const { username } = req.body; const conversationSid = req.params.id; try { const conversation = await client.conversations.conversations .get(conversationSid).fetch(); if (username conversationSid) { req.session.token = createToken(username, conversation.chatServiceSid); req.session.username = username; const participant = await client.conversations.conversations(conversationSid) .participants.create({ identity: username }) res.send({ conversation, participant }); } else { next({ message: 'Missing username or conversation Sid' }); } } catch (error) { next({ error, message: 'There was a problem adding a participant' }); }}export { AddParticipant, StartConversation };

    El AddParticipantcontrolador agrega nuevos participantes a conversaciones ya existentes. Utilizando lo conversationSidproporcionado como parámetro de ruta, recupera la conversación. Luego crea un token para el usuario y lo agrega a la conversación usando su nombre de usuario del cuerpo de la solicitud. Por último, envía la conversación y el participante como respuesta.

    Controladores de autenticación

    Los dos controladores controllers/auth.jsse llaman GetTokeny DeleteToken. Agréguelos al archivo copiando y pegando este código:

    function GetToken(req, res, next) { if (req.session.token) { res.send({ token: req.session.token, username: req.session.username }); } else { next({ status: 404, message: 'Token not set' }); }}function DeleteToken(req, res, _next) { delete req.session.token; delete req.session.username; res.send({ message: 'Session destroyed' });}export { DeleteToken, GetToken };

    El GetTokencontrolador recupera el token y el nombre de usuario de la sesión, si existen, y los devuelve como respuesta. DeleteTokenelimina la sesión.

    Rutas

    La routescarpeta tiene tres archivos: index.js, conversations.jsy auth.js.

    Agregue estas rutas de autenticación al routes/auth.jsarchivo agregando este código:

    import { Router } from 'express';import { DeleteToken, GetToken } from '../controllers/auth.js';var router = Router();router.get('/', GetToken);router.delete('/', DeleteToken);export default router;

    La GETruta en la /ruta devuelve un token mientras que la DELETEruta elimina un token.

    A continuación, copie y pegue el siguiente código en el routes/conversations.jsarchivo:

     

    import { Router } from 'express';import { AddParticipant, StartConversation } from '../controllers/conversations.js';import { asyncWrapper } from '../utils/controller.js';var router = Router();router.post('/', asyncWrapper(StartConversation));router.post('/:id/participants', asyncWrapper(AddParticipant));export default router;

    En este archivo se crea el enrutador de conversaciones. Se agrega al enrutador una POSTruta para crear conversaciones con la ruta /y otra POSTruta para agregar participantes con la ruta ./:id/participants

    Por último, agregue el siguiente código a su nuevo routes/index.jsarchivo.

    import { Router } from 'express';import authRouter from './auth.js';import conversationRouter from './conversations.js';var router = Router();router.use('/auth/token', authRouter);router.use('/api/conversations', conversationRouter);export default router;

    Al agregar los enrutadores conversationy authaquí, los hará disponibles en /api/conversationsy /auth/tokenpara el enrutador principal respectivamente. Luego se exporta el enrutador.

    La aplicación de fondo

    Ahora es el momento de juntar las piezas del backend. Abra el index.jsarchivo en su editor de texto y pegue el siguiente código:

    import cors from 'cors';import createError from 'http-errors';import express, { json, urlencoded } from 'express';import logger from 'morgan';import session from 'express-session';import store from 'connect-mongo';import { corsClient, port, sessionDB } from './config/index.js';import router from './routes/index.js';var app = express();app.use(logger('dev'));app.use(json());app.use(urlencoded({ extended: false }));app.use(cors({ origin: corsClient.domain, credentials: true, methods: ['GET', 'POST', 'DELETE'], maxAge: 3600 * 1000, allowedHeaders: ['Content-Type', 'Range'], exposedHeaders: ['Accept-Ranges', 'Content-Encoding', 'Content-Length', 'Content-Range']}));app.options('*', cors());app.use(session({ store: store.create({ mongoUrl: `mongodb://${sessionDB.user}:${sessionDB.pass}@${sessionDB.host}:${sessionDB.port}/${sessionDB.name}`, mongoOptions: { useUnifiedTopology: true }, collectionName: 'sessions' }), secret: sessionDB.secret, cookie: { maxAge: 3600 * 1000, sameSite: 'strict' }, name: 'twilio.sid', resave: false, saveUninitialized: true}));app.use('/', router);app.use(function (_req, _res, next) { next(createError(404, 'Route does not exist.'));});app.use(function (err, _req, res, _next) { res.status(err.status || 500).send(err);});app.listen(port);

    Este archivo comienza creando la aplicación express. Luego configura el análisis de carga útil codificada en URL y JSON y agrega el middleware de registro. A continuación, configura CORS y el manejo de la sesión. Como se mencionó anteriormente, MongoDB se utiliza como almacén de sesiones.

    Después de configurar todo, agrega el enrutador creado en el paso anterior antes de configurar el manejo de errores. Por último, hace que la aplicación escuche y acepte conexiones en el puerto especificado en el .envarchivo. Si no ha configurado el puerto, la aplicación escuchará en el puerto 8000.

     

    Una vez que haya terminado de crear la aplicación backend, asegúrese de que MongoDB se esté ejecutando e inícielo ejecutando este comando en la terminal:

    NODE_ENV=development npm start

    Pasa la NODE_ENV=developmentvariable para que la configuración se cargue desde el .envarchivo local.

    El front-end

    La parte inicial de este proyecto cumple un par de funciones. Permite a los usuarios crear conversaciones, ver la lista de conversaciones de las que forman parte, invitar a otros a las conversaciones que crearon y enviar mensajes dentro de las conversaciones. Estos roles se logran mediante cuatro páginas:

    • una página de conversaciones ,
    • una página de chat ,
    • una página de error ,
    • una página de inicio de sesión .

    Llamarás a la aplicación front-end twilio-chat-app. Existe un iniciador andamiado para ello en Github . Para clonar el proyecto y obtener el iniciador, ejecute:

    git clone https://github.com/zaracooper/twilio-vanilla-js-chat-app.gitcd twilio-vanilla-js-chat-appgit checkout starter

    La aplicación toma esta estructura:

    .├── index.html├── pages│ ├── chat.html│ ├── conversation.html│ ├── error.html│ └── login.html├── scripts│ ├── chat.js│ ├── conversation.js│ └── login.js└── styles ├── chat.css ├── main.css └── simple-page.css

    El estilo y el marcado HTML ya se han agregado para cada una de las páginas del inicio. Esta sección solo cubrirá los scripts que debe agregar.

    Dependencias

    La aplicación tiene dos dependencias: axiosy @twilio/conversations. Lo utilizará axiospara realizar solicitudes a la aplicación backend y @twilio/conversationspara enviar y recuperar mensajes y conversaciones en scripts. Puedes instalarlos en la terminal ejecutando:

    npm i

    La página de índice

    Esta página sirve como página de inicio para la aplicación. Puede encontrar el marcado de esta página ( index.html) aquí . Utiliza dos hojas de estilo CSS: styles/main.cssla que utilizan todas las páginas y styles/simple-page.cssla que utilizan las páginas más pequeñas y menos complicadas.

    Puede encontrar el contenido de estas hojas de estilo vinculado en el párrafo anterior. Aquí hay una captura de pantalla de cómo se verá esta página:

    Página de inicio de la aplicación Twilio Vanilla JS Chat. ( Vista previa grande )

    La página de errores

    Esta página se muestra cuando ocurre un error. El contenido de pages/error.htmlse puede encontrar aquí. Si se produce un error, un usuario puede hacer clic en el botón para ir a la página de inicio. Allí podrán volver a intentar lo que estaban intentando.

    Página de error de la aplicación Twilio Vanilla JS Chat. ( Vista previa grande )

    La página de conversaciones

    En esta página, un usuario proporciona el título de una conversación que se creará y su nombre de usuario en un formulario.

     

    El contenido de pages/conversation.htmlse puede encontrar aquí. Agregue el siguiente código al scripts/conversation.jsarchivo:

    window.twilioChat = window.twilioChat || {};function createConversation() { let convoForm = document.getElementById('convoForm'); let formData = new FormData(convoForm); let body = Object.fromEntries(formData.entries()) || {}; let submitBtn = document.getElementById('submitConvo'); submitBtn.innerText = "Creating..." submitBtn.disabled = true; submitBtn.style.cursor = 'wait'; axios.request({ url: '/api/conversations', baseURL: 'https://localhost:8000', method: 'post', withCredentials: true, data: body }) .then(() = { window.twilioChat.username = body.username; location.href = '/pages/chat.html'; }) .catch(() = { location.href = '/pages/error.html'; });}

    Cuando un usuario hace clic en el Submitbotón, createConversationse llama a la función. En él, el contenido del formulario se recopila y se utiliza en el cuerpo de una POSTsolicitud realizada https://localhost:8000/api/conversations/en el backend.

    Utilizarás axiospara realizar la solicitud. Si la solicitud tiene éxito, se crea una conversación y se agrega al usuario. Luego, el usuario será redirigido a la página de chat donde podrá enviar mensajes en la conversación.

    A continuación se muestra una captura de pantalla de la página de conversaciones:

    Página de conversación de la aplicación Twilio Vanilla JS Chat. ( Vista previa grande )

    La página de chat

    En esta página, un usuario verá una lista de conversaciones de las que forma parte y les enviará mensajes. Puede encontrar el marcado pages/chat.htmlaquí y el estilo styles/chat.cssaquí .

    El scripts/chat.jsarchivo comienza definiendo un espacio de nombres twilioDemo.

    window.twilioChat = window.twilioChat || {};

    Agregue la initClientfunción a continuación. Es responsable de inicializar el cliente Twilio y cargar conversaciones.

    async function initClient() { try { const response = await axios.request({ url: '/auth/token', baseURL: 'https://localhost:8000', method: 'GETget', withCredentials: true }); window.twilioChat.username = response.data.username; window.twilioChat.client = await Twilio.Conversations.Client.create(response.data.token); let conversations = await window.twilioChat.client.getSubscribedConversations(); let conversationCont, conversationName; const sideNav = document.getElementById('side-nav'); sideNav.removeChild(document.getElementById('loading-msg')); for (let conv of conversations.items) { conversationCont = document.createElement('button'); conversationCont.classList.add('conversation'); conversationCont.id = conv.sid; conversationCont.value = conv.sid; conversationCont.onclick = async () = { await setConversation(conv.sid, conv.channelState.friendlyName); }; conversationName = document.createElement('h3'); conversationName.innerText = ` ${conv.channelState.friendlyName}`; conversationCont.appendChild(conversationName); sideNav.appendChild(conversationCont); } } catch { location.href = '/pages/error.html'; }};

    Cuando se carga la página, initClientrecupera el token de acceso del usuario del backend y luego lo usa para inicializar el cliente. Una vez que se inicializa el cliente, se utiliza para recuperar todas las conversaciones a las que está suscrito el usuario. Después de eso, las conversaciones se cargan en el archivo side-nav. En caso de que ocurra algún error, el usuario es enviado a la página de error.

    La setConversionfunción carga una sola conversación. Copie y pegue el siguiente código en el archivo para agregarlo:

    async function setConversation(sid, name) { try { window.twilioChat.selectedConvSid = sid; document.getElementById('chat-title').innerText = '+ ' + name; document.getElementById('loading-chat').style.display = 'flex'; document.getElementById('messages').style.display = 'none'; let submitButton = document.getElementById('submitMessage') submitButton.disabled = true; let inviteButton = document.getElementById('invite-button') inviteButton.disabled = true; window.twilioChat.selectedConversation = await window.twilioChat.client.getConversationBySid(window.twilioChat.selectedConvSid); const messages = await window.twilioChat.selectedConversation.getMessages(); addMessagesToChatArea(messages.items, true); window.twilioChat.selectedConversation.on('messag 




    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Cómo crear una aplicación de chat grupal con Vanilla JS, Twilio y Node.js

    Cómo crear una aplicación de chat grupal con Vanilla JS, Twilio y Node.js

    ¡Registro! Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX Índice Requisit

    programar

    es

    https://pseint.es/static/images/programar-como-crear-una-aplicacion-de-chat-grupal-con-vanilla-js-1145-0.jpg

    2024-04-04

     

    Cómo crear una aplicación de chat grupal con Vanilla JS, Twilio y Node.js
    Cómo crear una aplicación de chat grupal con Vanilla JS, Twilio y Node.js

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20