Kit SDK de messagerie client IVS Chat : didacticiel JavaScript, partie 1 : salles de chat - Amazon IVS

Kit SDK de messagerie client IVS Chat : didacticiel JavaScript, partie 1 : salles de chat

Il s'agit de la première partie d'un didacticiel en deux volets. Vous apprendrez les bases de l'utilisation du kit SDK de messagerie client Amazon IVS Chat pour JavaScript en créant une application entièrement fonctionnelle utilisant JavaScript/TypeScript. Nous appelons l'application Chatterbox.

Le public cible est constitué de développeurs expérimentés qui découvrent le kit SDK de messagerie Amazon IVS Chat. Vous devez être à l'aise avec le langage de programmation JavaScript/TypeScript et la bibliothèque React.

Par souci de concision, nous ferons référence au kit SDK de messagerie client Amazon IVS Chat pour JavaScript en le nommant kit SDK Chat JS.

Remarque : dans certains cas, les exemples de code pour JavaScript et TypeScript sont identiques et sont donc combinés.

Cette première partie du didacticiel est divisée en plusieurs sections :

Pour une documentation complète sur le kit SDK, commencez par le kit SDK de messagerie client Amazon IVS Chat (ici dans le Guide de l'utilisateur Chat Amazon IVS) et la Messagerie du client de chat : référence du kit SDK pour JavaScript (sur GitHub).

Prérequis

Configurer un serveur d'authentification/d'autorisation local

Votre application backend est chargée à la fois de créer des salles de chat et de générer les jetons de chat nécessaires au kit SDK Chat JS pour authentifier et autoriser vos clients à accéder à vos salles de chat. Vous devez utiliser votre propre backend, car vous ne pouvez pas stocker de manière sécurisée les clés AWS dans une application mobile ; des attaquants avertis pourraient les extraire et accéder à votre compte AWS.

Consultez la section Create a Chat Token (Créer un jeton de chat) dans Mise en route avec Amazon IVS Chat. Comme le montre l'organigramme, votre application côté serveur est chargée de créer un jeton de chat. Cela signifie que votre application doit fournir ses propres moyens de générer un jeton de chat en demandant un jeton à votre application côté serveur.

Dans cette section, vous apprendrez les bases de la création d'un fournisseur de jetons dans votre backend. Nous utilisons l'infrastructure express pour créer un serveur local en direct qui gère la création de jetons de chat à l'aide de votre environnement AWS local.

Créez un projet npm vide à l'aide de NPM. Créez un répertoire pour héberger votre application et faites-en votre répertoire de travail :

$ mkdir backend & cd backend

Utilisez npm init pour créer un fichier package.json pour votre application :

$ npm init

Cette commande vous invite à fournir plusieurs informations, notamment le nom et la version de votre application. Pour l'instant, appuyez simplement sur ENTRÉE pour accepter les valeurs par défaut pour la plupart d'entre elles, à l'exception de la suivante :

entry point: (index.js)

Appuyez sur ENTRÉE pour accepter le nom de fichier par défaut index.js suggéré ou saisissez le nom que vous souhaitez donner au fichier principal.

Installez maintenant les dépendances obligatoires :

$ npm install express aws-sdk cors dotenv

aws-sdk nécessite des variables d'environnement de configuration, qui se chargent automatiquement à partir d'un fichier nommé .env situé dans le répertoire racine. Pour le configurer, créez un fichier nommé .env et renseignez les informations de configuration manquantes :

# .env # The region to send service requests to. AWS_REGION=us-west-2 # Access keys use an access key ID and secret access key # that you use to sign programmatic requests to AWS. # AWS access key ID. AWS_ACCESS_KEY_ID=... # AWS secret access key. AWS_SECRET_ACCESS_KEY=...

Créons maintenant un fichier de point d'entrée dans le répertoire racine avec le nom que vous avez saisi ci-dessus dans la commande npm init. Dans ce cas, nous utilisons index.js et importons tous les packages requis :

// index.js import express from 'express'; import AWS from 'aws-sdk'; import 'dotenv/config'; import cors from 'cors';

Créez maintenant une nouvelle instance de express :

const app = express(); const port = 3000; app.use(express.json()); app.use(cors({ origin: ['http://127.0.0.1:5173'] }));

Ensuite, vous pouvez créer votre première méthode POST de point de terminaison pour le fournisseur de jetons. Prenez les paramètres requis dans le corps de la demande (roomId, userId, capabilities et sessionDurationInMinutes) :

app.post('/create_chat_token', (req, res) => { const { roomIdentifier, userId, capabilities, sessionDurationInMinutes } = req.body || {}; });

Ajoutez la validation des champs obligatoires :

app.post('/create_chat_token', (req, res) => { const { roomIdentifier, userId, capabilities, sessionDurationInMinutes } = req.body || {}; if (!roomIdentifier || !userId) { res.status(400).json({ error: 'Missing parameters: `roomIdentifier`, `userId`' }); return; } });

Après avoir préparé la méthode POST, nous intégrons createChatToken avec aws-sdk pour la fonctionnalité de base d'authentification/autorisation :

app.post('/create_chat_token', (req, res) => { const { roomIdentifier, userId, capabilities, sessionDurationInMinutes } = req.body || {}; if (!roomIdentifier || !userId || !capabilities) { res.status(400).json({ error: 'Missing parameters: `roomIdentifier`, `userId`, `capabilities`' }); return; } ivsChat.createChatToken({ roomIdentifier, userId, capabilities, sessionDurationInMinutes }, (error, data) => { if (error) { console.log(error); res.status(500).send(error.code); } else if (data.token) { const { token, sessionExpirationTime, tokenExpirationTime } = data; console.log(`Retrieved Chat Token: ${JSON.stringify(data, null, 2)}`); res.json({ token, sessionExpirationTime, tokenExpirationTime }); } }); });

À la fin du fichier, ajoutez un écouteur de port pour votre application express :

app.listen(port, () => { console.log(`Backend listening on port ${port}`); });

À présent, vous pouvez exécuter le serveur à l'aide de la commande suivante depuis la racine du projet :

$ node index.js

Conseil : ce serveur accepte les requêtes URL sur https://localhost:3000.

Créer un projet Chatterbox

Vous créez d'abord le projet React appelé chatterbox. Exécutez cette commande :

npx create-react-app chatterbox

Vous pouvez intégrer le kit SDK de messagerie client Chat pour JS via Node Package Manager ou Yarn Package Manager :

  • Npm : npm install amazon-ivs-chat-messaging

  • Yarn : yarn add amazon-ivs-chat-messaging

Se connecter à une salle de chat

Ici, vous créez une ChatRoom et vous vous y connectez à l'aide de méthodes asynchrones. La classe ChatRoom gère la connexion de votre utilisateur au kit SDK Chat JS. Pour vous connecter correctement à une salle de chat, vous devez fournir une instance de ChatToken dans votre application React.

Accédez au fichier App créé dans le projet chatterbox par défaut et supprimez tout ce qui se trouve entre les deux balises <div>. Aucun code prérempli n'est nécessaire. À ce stade, notre App est assez vide.

// App.jsx / App.tsx import * as React from 'react'; export default function App() { return <div>Hello!</div>; }

Créez une instance ChatRoom et transmettez-la à l'état à l'aide du hook useState. Cela nécessite de passer regionOrUrl (la région AWS dans laquelle votre salle de chat est hébergée) et tokenProvider (utilisé pour le flux d'authentification/autorisation backend qui est créé dans les étapes suivantes).

Important : vous devez utiliser la même région AWS que celle dans laquelle vous avez créé la salle dans la Mise en route avec Amazon IVS Chat. L'API est un service régional AWS. Pour obtenir la liste des régions prises en charge et des points de terminaison du service HTTPS Amazon IVS Chat, consultez la page des régions Amazon IVS Chat.

// App.jsx / App.tsx import React, { useState } from 'react'; import { ChatRoom } from 'amazon-ivs-chat-messaging'; export default function App() { const [room] = useState(() => new ChatRoom({ regionOrUrl: process.env.REGION as string, tokenProvider: () => {}, }), ); return <div>Hello!</div>; }

Créer un fournisseur de jetons

À l'étape suivante, nous devons créer une fonction tokenProvider sans paramètre requise par le constructeur ChatRoom. Tout d'abord, nous allons créer une fonction fetchChatToken qui enverra une requête POST à l'application backend que vous avez configurée dans Configurer un serveur d'authentification/d'autorisation local. Les jetons de chat contiennent les informations nécessaires au kit SDK pour établir avec succès une connexion à la salle de chat. L'API de chat utilise ces jetons comme moyen sécurisé de valider l'identité d'un utilisateur, ses capacités au sein d'une salle de chat et la durée de la session.

Dans le navigateur de projet, créez un fichier TypeScript/JavaScript nommé fetchChatToken. Créez une demande de récupération à l'application backend et renvoyez l'objet ChatToken de la réponse. Ajoutez les propriétés du corps de la demande nécessaires à la création d'un jeton de chat. Utilisez les règles définies pour les Amazon Resource Name (ARN). Ces propriétés sont documentées dans le point de terminaison CreateChatToken.

Remarque : l'URL que vous utilisez ici est la même que celle que votre serveur local a créée lorsque vous avez exécuté l'application backend.

TypeScript
// fetchChatToken.ts import { ChatToken } from 'amazon-ivs-chat-messaging'; type UserCapability = 'DELETE_MESSAGE' | 'DISCONNECT_USER' | 'SEND_MESSAGE'; export async function fetchChatToken( userId: string, capabilities: UserCapability[] = [], attributes?: Record<string, string>, sessionDurationInMinutes?: number, ): Promise<ChatToken> { const response = await fetch(`${process.env.BACKEND_BASE_URL}/create_chat_token`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId, roomIdentifier: process.env.ROOM_ID, capabilities, sessionDurationInMinutes, attributes }), }); const token = await response.json(); return { ...token, sessionExpirationTime: new Date(token.sessionExpirationTime), tokenExpirationTime: new Date(token.tokenExpirationTime), }; }
JavaScript
// fetchChatToken.js export async function fetchChatToken( userId, capabilities = [], attributes, sessionDurationInMinutes) { const response = await fetch(`${process.env.BACKEND_BASE_URL}/create_chat_token`, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ userId, roomIdentifier: process.env.ROOM_ID, capabilities, sessionDurationInMinutes, attributes }), }); const token = await response.json(); return { ...token, sessionExpirationTime: new Date(token.sessionExpirationTime), tokenExpirationTime: new Date(token.tokenExpirationTime), }; }

Observer les mises à jour de la connexion

Réagir aux modifications de l'état de connexion d'une salle de chat est un élément essentiel de la création d'une application de chat. Commençons par nous abonner aux événements pertinents :

// App.jsx / App.tsx import React, { useState, useEffect } from 'react'; import { ChatRoom } from 'amazon-ivs-chat-messaging'; import { fetchChatToken } from './fetchChatToken'; export default function App() { const [room] = useState( () => new ChatRoom({ regionOrUrl: process.env.REGION as string, tokenProvider: () => fetchChatToken('Mike', ['SEND_MESSAGE']), }), ); useEffect(() => { const unsubscribeOnConnecting = room.addListener('connecting', () => {}); const unsubscribeOnConnected = room.addListener('connect', () => {}); const unsubscribeOnDisconnected = room.addListener('disconnect', () => {}); return () => { // Clean up subscriptions. unsubscribeOnConnecting(); unsubscribeOnConnected(); unsubscribeOnDisconnected(); }; }, [room]); return <div>Hello!</div>; }

Ensuite, nous devons fournir la possibilité de lire l'état de la connexion. Nous utilisons notre hook useState pour créer un état local dans App et définir l'état de connexion dans chaque écouteur.

TypeScript
// App.tsx import React, { useState, useEffect } from 'react'; import { ChatRoom, ConnectionState } from 'amazon-ivs-chat-messaging'; import { fetchChatToken } from './fetchChatToken'; export default function App() { const [room] = useState( () => new ChatRoom({ regionOrUrl: process.env.REGION as string, tokenProvider: () => fetchChatToken('Mike', ['SEND_MESSAGE']), }), ); const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected'); useEffect(() => { const unsubscribeOnConnecting = room.addListener('connecting', () => { setConnectionState('connecting'); }); const unsubscribeOnConnected = room.addListener('connect', () => { setConnectionState('connected'); }); const unsubscribeOnDisconnected = room.addListener('disconnect', () => { setConnectionState('disconnected'); }); return () => { unsubscribeOnConnecting(); unsubscribeOnConnected(); unsubscribeOnDisconnected(); }; }, [room]); return <div>Hello!</div>; }
JavaScript
// App.jsx import React, { useState, useEffect } from 'react'; import { ChatRoom } from 'amazon-ivs-chat-messaging'; import { fetchChatToken } from './fetchChatToken'; export default function App() { const [room] = useState( () => new ChatRoom({ regionOrUrl: process.env.REGION, tokenProvider: () => fetchChatToken('Mike', ['SEND_MESSAGE']), }), ); const [connectionState, setConnectionState] = useState('disconnected'); useEffect(() => { const unsubscribeOnConnecting = room.addListener('connecting', () => { setConnectionState('connecting'); }); const unsubscribeOnConnected = room.addListener('connect', () => { setConnectionState('connected'); }); const unsubscribeOnDisconnected = room.addListener('disconnect', () => { setConnectionState('disconnected'); }); return () => { unsubscribeOnConnecting(); unsubscribeOnConnected(); unsubscribeOnDisconnected(); }; }, [room]); return <div>Hello!</div>; }

Après vous être abonné à l'état de connexion, affichez l'état de la connexion et connectez-vous à la salle de chat en utilisant la méthode room.connect indiquée dans le hook useEffect :

// App.jsx / App.tsx // ... useEffect(() => { const unsubscribeOnConnecting = room.addListener('connecting', () => { setConnectionState('connecting'); }); const unsubscribeOnConnected = room.addListener('connect', () => { setConnectionState('connected'); }); const unsubscribeOnDisconnected = room.addListener('disconnect', () => { setConnectionState('disconnected'); }); room.connect(); return () => { unsubscribeOnConnecting(); unsubscribeOnConnected(); unsubscribeOnDisconnected(); }; }, [room]); // ... return ( <div> <h4>Connection State: {connectionState}</h4> </div> ); // ...

Vous avez correctement mis en place une connexion à la salle de chat.

Créer un composant de bouton d'envoi

Dans cette section, vous créez un bouton d'envoi qui a une apparence différente pour chaque état de connexion. Le bouton d'envoi facilite l'envoi de messages dans une salle de chat. Il sert également d'indicateur visuel indiquant si et quand des messages peuvent être envoyés, par exemple en cas de perte de connexion ou de sessions de chat expirées.

Commencez par créer un fichier dans le répertoire src de votre projet Chatterbox et nommez-le SendButton. Ensuite, créez un composant qui affichera un bouton pour votre application de chat. Exportez votre SendButton et importez-le dans App. Dans le champ <div></div> vide, ajoutez <SendButton />.

TypeScript
// SendButton.tsx import React from 'react'; interface Props { onPress?: () => void; disabled?: boolean; } export const SendButton = ({ onPress, disabled }: Props) => { return ( <button disabled={disabled} onClick={onPress}> Send </button> ); }; // App.tsx import { SendButton } from './SendButton'; // ... return ( <div> <div>Connection State: {connectionState}</div> <SendButton /> </div> );
JavaScript
// SendButton.jsx import React from 'react'; export const SendButton = ({ onPress, disabled }) => { return ( <button disabled={disabled} onClick={onPress}> Send </button> ); }; // App.jsx import { SendButton } from './SendButton'; // ... return ( <div> <div>Connection State: {connectionState}</div> <SendButton /> </div> );

Ensuite, dans App, définissez une fonction nommée onMessageSend et transmettez-la à la propriété SendButton onPress. Définissez une autre variable nommée isSendDisabled (qui empêche l'envoi de messages lorsque la salle n'est pas connectée) et transmettez-la à la propriété SendButton disabled.

// App.jsx / App.tsx // ... const onMessageSend = () => {}; const isSendDisabled = connectionState !== 'connected'; return ( <div> <div>Connection State: {connectionState}</div> <SendButton disabled={isSendDisabled} onPress={onMessageSend} /> </div> ); // ...

Créer une entrée de message

La barre de messages Chatterbox est le composant avec lequel vous allez interagir pour envoyer des messages à une salle de chat. Elle contient généralement une entrée de texte pour rédiger votre message et un bouton pour envoyer votre message.

Pour créer un composant MessageInput, créez d'abord un fichier dans le répertoire src et nommez-le MessageInput. Ensuite, créez un composant d'entrée contrôlé qui affichera une entrée pour votre application de chat. Exportez votre MessageInput et importez-le dans App (au-dessus du <SendButton />).

Créez un état nommé messageToSend à l'aide du hook useState, avec une chaîne vide comme valeur par défaut. Dans le corps de votre application, passez messageToSend à value de MessageInput et transmettez setMessageToSend à la propriété onMessageChange :

TypeScript
// MessageInput.tsx import * as React from 'react'; interface Props { value?: string; onValueChange?: (value: string) => void; } export const MessageInput = ({ value, onValueChange }: Props) => { return ( <input type="text" value={value} onChange={(e) => onValueChange?.(e.target.value)} placeholder="Send a message" /> ); }; // App.tsx // ... import { MessageInput } from './MessageInput'; // ... export default function App() { const [messageToSend, setMessageToSend] = useState(''); // ... return ( <div> <h4>Connection State: {connectionState}</h4> <MessageInput value={messageToSend} onMessageChange={setMessageToSend} /> <SendButton disabled={isSendDisabled} onPress={onMessageSend} /> </div> );
JavaScript
// MessageInput.jsx import * as React from 'react'; export const MessageInput = ({ value, onValueChange }) => { return ( <input type="text" value={value} onChange={(e) => onValueChange?.(e.target.value)} placeholder="Send a message" /> ); }; // App.jsx // ... import { MessageInput } from './MessageInput'; // ... export default function App() { const [messageToSend, setMessageToSend] = useState(''); // ... return ( <div> <h4>Connection State: {connectionState}</h4> <MessageInput value={messageToSend} onMessageChange={setMessageToSend} /> <SendButton disabled={isSendDisabled} onPress={onMessageSend} /> </div> );

Étapes suivantes

Maintenant que vous avez fini de créer une barre de messages pour Chatterbox, passez à la seconde partie de ce didacticiel JavaScript, Messages et événements.