https://d226lax1qjow5r.cloudfront.net/blog/blogposts/show-sms-notifications-in-the-browser-with-next-js-ably-and-vercel/ably_vonage_1200x600.png

Afficher les notifications SMS dans le navigateur avec Next.JS, Ably et Vercel

Publié le April 26, 2021

Temps de lecture : 12 minutes

L'API SMS API de Vonage vous permet d'envoyer et de recevoir des messages texte dans le monde entier à l'aide d'un numéro virtuel que vous pouvez louer auprès de Vonage.

Dans ce tutoriel, vous utiliserez l'API SMS de Vonage, la plateforme de messagerie en temps réel Ably, Next.js et Vercel pour recevoir des SMS dans le navigateur en temps réel au fur et à mesure de leur réception.

Suivez les instructions pour apprendre à.. :

Dépendances

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Pour créer cette application, vous aurez également besoin de :

Exigences préalables en matière de développement local

Vous aurez besoin d'une clé API d'Ably pour vous authentifier auprès du service Ably. Pour obtenir une clé API, une fois que vous avez créé un Account Ably:

  1. Visitez votre tableau de bord des applications et cliquez sur "Créer une nouvelle application".

  2. Donner un nom à la nouvelle application

  3. Copiez la clé API privée une fois l'application créée. Conservez-la précieusement, car c'est elle qui vous permettra de vous authentifier auprès du service Ably.

Vercel fournit quelques outils en ligne de commande Next.js pour nous aider. Ils n'ont pas besoin d'être installés sur votre système car ils sont exécutés en utilisant la commande npx.

WebSockets à Vercel avec Ably

Vercel and Websockets

Vercel est une plateforme d'hébergement construite dès le départ pour héberger des apps Next.js et des fonctions Serverless. Elle permet aux utilisateurs de déployer des fonctions sans serveurqui sont essentiellement des blocs de code qui répondent à une requête HTTP.
Cependant, ces fonctions ont un délai d'exécution maximal, ce qui signifie qu'il est impossible de maintenir une connexion WebSocket de cette façon.

C'est là qu'intervient Ably. Le client peut se connecter à un canal Ably et y envoyer et recevoir des messages afin d'ajouter une fonctionnalité temps réel à votre application en gérant vos connexions WebSocket pour vous. Nous allons voir comment construire une application qui utilise la fonctionnalité temps réel dans ce walkthrough. Si vous voulez en savoir plus sur les WebSockets dans Next.js et Vercel, consultez "Construire une application de chat en temps réel avec Next.js et Vercel".

Création de l'application SMS en temps réel

Pour créer l'application de démarrage :

  1. Dans votre terminal, tapez npx create-next-app pour créer une application Next.js vide.

  2. Créez un fichier appelé .env à la racine du répertoire ; c'est là que nous placerons les variables d'environnement du projet.

  3. Ajoutez votre clé API Ably au fichier .env :

ABLY_API_KEY=your-ably-api-key:goes-here
  1. Naviguez jusqu'au répertoire de votre application Next.js et tapez dans la console :

npm run dev

Le serveur de développement Next.js va démarrer, et vous verrez une application de démarrage Next.js vide. Vous allez construire notre application SMS dans le navigateur à partir de celle-ci.

Messagerie Pub/Sub en temps réel avec Ably

Cette application utilise Ably pour messagerie pub/sub entre les utilisateurs. Pub/Sub est l'abréviation de Publish and Subscribe (publier et s'abonner) et il s'agit d'un modèle populaire utilisé pour la livraison de données en temps réel. L'application enverra, ou publishdes messages sur un canal Ably. Les clients utilisant l'application seront subscribed Les clients utilisant l'application seront connectés au canal et pourront recevoir les messages.

Authentification avec le service Ably

Les applications Vercel Next.js n'exécutent pas de "code côté serveur" traditionnel. Cependant, vous pouvez ajouter des fichiers JavaScript à /pages/api/*et le moteur de déploiement Vercel traitera chacun d'entre eux comme un point d'extrémité d'API et les gérera comme des fonctions sans serveur pour vous.

Pour le développement local, les outils Next.js exécutent ces fonctions dans un serveur Node, de sorte qu'ils fonctionnent comme vous l'attendez dans votre environnement de développement local. Vous allez ajouter une fonction serverless Next.js / Vercel au code de démarrage que vous avez créé plus tôt pour authentifier votre app avec Messaging et permettre de commencer à envoyer et recevoir des messages sur le service Messaging.

Écrire la fonction Serverless pour se connecter à Ably

Vous devez installer le paquetage Ably npm package (il est essentiel que vous utilisiez Ably 1.2.5+ pour cette application, pour des raisons de compatibilité avec Vercel).

Dans le terminal, à la racine de votre nouvelle application, exécutez :

npm install ably@1.2.5-beta.1

Ensuite, créez un fichier appelé ./pages/api/createTokenRequest.js dans lequel vous ajouterez le code suivant :

import Ably from "ably/promises";

export default async function handler(req, res) {
    const client = new Ably.Realtime(process.env.ABLY_API_KEY);
    const tokenRequestData = await client.auth.createTokenRequest({ clientId: 'ably-nextjs-demo' });
    res.status(200).json(tokenRequestData);
};

Cette fonction sans serveur utilise le SDK d'Ably pour créer un fichier tokenRequest avec votre clé API. Vous utiliserez ce jeton plus tard - il vous permet de garder votre "vraie" clé API en sécurité tout en l'utilisant dans l'application Next.js.
Par défaut, cette API est configurée pour être disponible sur http://localhost:3000/api/createTokenRequest. Vous allez fournir cette URL au Client SDK d'Ably dans votre client pour vous authentifier auprès d'Ably.

Réception d'un SMS avec Vonage et Vercel

Vonage vous permet de configurer des numéros de téléphone mobile dans son tableau de bord API. Lorsqu'un SMS est reçu, il déclenche votre API.

Pour ce faire, vous devez ajouter un Vercel Serverless function à notre application Next.js. Cette fonction sans serveur sera appelée par Vonage à chaque fois qu'un SMS sera reçu (une fois que vous aurez configuré un numéro de téléphone !). Vous devez mettre du code dans cette fonction pour décompresser le SMS, puis l'envoyer à votre app React à l'aide d'une fonction Ably channel.

Ce processus est assez similaire à la mise en place de votre Ably createTokenRequest.

Créez un fichier appelé ./pages/api/acceptWebhook.js dans lequel vous ajouterez le code suivant :

import Ably from "ably/promises";

export default async function handler(req, res) {

    // Unpack the SMS details from the request query string
    const incomingData = getSmsDetails(req, res);

    // If the request was invalid, return status 400.
    if (!incomingData.success) {
        res.status(400).end();
        return;
    }

    // Create an Ably client, get your `sms-notifications` channel
    const client = new Ably.Realtime(process.env.ABLY_API_KEY);
    const channel = client.channels.get("sms-notifications");

    // Publish your SMS contents as an Ably message for the browser
    await channel.publish({ name: "smsEvent", data: incomingData });

    // Return the received data as a 200 OK for debugging.
    res.send(incomingData);
    res.status(200).end();
};

function getSmsDetails(req, res) {

    const params = req.query;

    if (!params.to || !params.msisdn) {
        console.log('This is not a valid inbound SMS message!');
        return { success: false };
    }

    return {
        success: true,
        messageId: params.messageId,
        from: params.msisdn,
        text: params.text,
        type: params.type,
        timestamp: params['message-timestamp']
    };
}

Nous allons revenir à l'application pour l'instant, mais nous reviendrons à cette fonction à la fin, une fois que l'application sera déployée sur Vercel et que votre fonction aura un public url.

Réagir aux messages SMS avec le composant SmsComponent

Les pages dans Next.js sont des composants React, de sorte que la page d'accueil pages/index.js est le composant React qui contient la mise en page.

Il s'agit de la page par défaut générée par create-next-app; vous y ajouterez votre composant - la logique de l'application est contenue à l'intérieur de SmsComponent.jsx.

Commencez par référencer les importations dont vous aurez besoin au début du fichier :

import React, { useEffect, useState } from 'react';
import { useChannel } from "./AblyReactEffect";
import styles from './SmsComponent.module.css';

Définissez ensuite la fonction qui sera exportée en tant que composant React.

const SmsComponent = () => {
    
  let messageEnd = null;

  const [receivedMessages, setMessages] = useState([]);

et utilisez votre premier react hook:

  const [channel, ably] = useChannel("sms-notifications", (message) => {
    const history = receivedMessages.slice(-199);
    setMessages([...history, message]);
  });

useChannel est un react-hook pour s'abonner aux messages d'un canal Ably. Vous lui fournissez un nom de canal et un callback à invoquer à chaque fois qu'un message est reçu.

Ensuite, vous allez formater les données pour l'écran afin que chaque message puisse être affiché, avec l'heure à laquelle il est arrivé et le numéro de téléphone de l'expéditeur.

   const messages = receivedMessages.map((message, index) => {
    console.log(message);
    let from = [message.data.from.slice(0, 2) + " " + message.data.from.slice(2, 6) +  " " + message.data.from.slice(6, 9) + " "+ message.data.from.slice(9)];
    let date = new Date(message.data.timestamp);
    let day = date.toDateString().replace(/^\S+\s/,'');
    let time = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });

    return (
      <div key={index} className={styles.message}>
        <span className={styles.from}>{from}</span>
        <span className={styles.when}>{day}, {time}</span>
        <span className={styles.text}>{message.data.text}</span>
      </div>
    );
  });

Enfin, créez votre composant et renvoyez-le :

  return (
    <div className={styles.chatHolder}>
      <h1 className={styles.title}>Text Messages</h1>
      <div className={styles.chatText}>
        {messages}
        <div ref={(element) => { messageEnd = element; }}></div>
      </div>
    </div>
  )
}

Tout en bas du fichier, la fonction est exportée en tant que SmsComponent afin qu'elle puisse être référencée dans la page d'index Next.js.

Utiliser correctement Ably dans les composants React

L'une des parties les plus délicates de l'utilisation d'Ably avec les composants fonctionnels React est de savoir quand et où créer l'instance du SDK et quand et où se connecter à votre (vos) canal(aux). Vous voudrez éviter d'instancier le SDK lorsque le composant est rendu, car cela pourrait établir plusieurs connexions et brûler les limites de votre Account Ably.

Pour s'assurer que l'application gère correctement le redécoupage des composants, le montage et le démontage - AblyReactEffect exporte un crochet React pour interagir avec le SDK Ably.

Les hooks de React peuvent sembler un peu inhabituels la première fois que vous les utilisez. Un hook est une fonction qui :

  • Exécute la fonctionnalité que vous attendez componentDidMount qu'elle s'exécute

  • Retours une autre qui sera exécutée par le cadre où componentDidUnmount serait appelée

  • Effectue tout autre comportement nécessaire

Ce React Hook est construit sur useEffect. Lorsqu'il est référencé, il crée une instance du SDK Ably (il ne le fait qu'une seule fois) qui est configurée pour utiliser la fonction URL de votre fonction Serverless à createTokenRequest pour l'authentification :

import Ably from "ably/promises";
import { useEffect } from 'react'

const ably = new Ably.Realtime.Promise({ authUrl: '/api/createTokenRequest' });

Instancier la bibliothèque Ably en dehors de la portée du composant signifie qu'elle n'est créée qu'une seule fois et permet de limiter l'utilisation de la limite.

Ensuite, vous devez créer la fonction que vous allez exporter, votre crochet, pour l'utiliser dans votre composant. Appelons-la useChannel; elle aura besoin du nom du canal et d'un rappel comme arguments. Chaque fois que useChannel est appelée, vous get le canal demandé à partir du SDK Ably-JS et préparez les fonctions d'accroche.

  • onMount est le code exécuté à chaque fois que votre composant est rendu. Dans onMount, vous vous abonnez au canal spécifié et vous vous déclenchez callbackOnMessage à chaque fois qu'un message est reçu.

  • onUnmount est le code exécuté chaque fois que le composant est démonté avant d'être rendu à nouveau. Ici, vous vous désabonnerez du canal, ce qui mettra fin aux multiples connexions accidentelles, épargnant une fois de plus les limites de notre Account.

  • useEffectHook est une fonction qui appelle ces fonctions correctement, retournant onUnmount pour que React l'utilise.

Le crochet exporté dans AblyReactEffect.js ressemblera à ceci :

export function useChannel(channelName, callbackOnMessage) {
    const channel = ably.channels.get(channelName);

    const onMount = () => {
        channel.subscribe(msg => { callbackOnMessage(msg); });
    }

    const onUnmount = () => {
        channel.unsubscribe();
    }

    const useEffectHook = () => {
        onMount();
        return () => { onUnmount(); };
    };

    useEffect(useEffectHook);

    return [channel, ably];
}

Le crochet useChannel renvoie à la fois le canal Ably actuel et le SDK Ably que le code appelant doit utiliser pour envoyer des messages. Ce crochet encapsule les composants fonctionnels Ably pub/sub for React en un seul endroit, de sorte que vous n'avez pas besoin de vous en soucier ailleurs, et le code qui l'utilise peut traiter les messages qu'il reçoit.

Pour que tout soit beau avec le module CSS -SmsComponent.module.css

Lors de l'écriture du composant de chat, vous avez peut-être remarqué que Next.js a quelques conventions imposées par le compilateur qui dictent l'endroit où vous gardez votre CSS et comment l'importer.

Pour cette application, créez un fichier CSS portant le même nom que le fichier .jsx mais avec les extensions .module.css; cela facilite la gestion du composant. Si vous souhaitez supprimer ce composant à l'avenir, il est très simple de supprimer également son CSS.

Une fois créé, il peut être importé dans le composant :

import styles from './SmsComponent.module.css';

Lors de la création d'une classe CSS sur un élément JSX, utilisez la syntaxe suivante sur l'élément :

className={styles.yourClassName}

et la feuille de style CSS correspondante ressemblerait à ceci :

.yourClassName {
  styles: gohere;
}

Hébergement sur Vercel

Nous utilisons Vercel comme serveur de développement et pipeline de construction.

La façon la plus simple de déployer Next.js en production est d'utiliser la plateforme Vercel des créateurs de Next.js. Vercel est une plateforme tout-en-un avec un CDN global prenant en charge le déploiement statique et Jamstack et les fonctions Serverless. -- La documentation de Next.js

Pour déployer votre nouvelle application "sms-in-the-browser" sur Vercel, vous aurez besoin de :

  1. Créer un compte Account GitHub (si vous n'en avez pas encore)

  2. Pousser votre application vers un dépôt GitHub

  3. Créer un compte Vercel

  4. Créez une nouvelle application Vercel et importez votre application depuis votre dépôt GitHub. (Pour ce faire, vous devrez autoriser Vercel à utiliser votre compte GitHub).

  5. Ajoutez votre ABLY_API_KEY comme variable d'environnement

  6. Observez le déploiement de votre application

  7. Visitez l'URL nouvellement créée dans votre navigateur !

Configurer un numéro de SMS pour votre application

Pour recevoir des SMS, vous devez louer un numéro de téléphone virtuel auprès de Vonage et le configurer.

Tout d'abord, ouvrez une session dans votre Account Vonage en visitant le tableau de bord. Une fois que vous avez créé et vérifié votre Account, vous pouvez acheter un numéro en allant sur Numbers => Buy Numbers. Recherchez un numéro qui vous convient et ajoutez des crédits pour payer le numéro.

Une fois que vous avez acheté votre numéro, vous devez configurer le SMS Inbound Webhook URL.

Pour ce faire, allez dans Numbers => Your Numbers => Cliquez sur l'icône du stylo.

Vous serez accueilli par une boîte de dialogue modale, et vous devrez insérer votre acceptWebhook dans la boîte.

Si votre application Vercel s'appelle your-vercel-appl'URL du webhook serait https://your-vercel-app.vercel.app/api/acceptWebhook.

Faites-le vôtre !

Cette démo est open-source, vous pouvez la forker et vous l'approprier. N'oubliez pas de nous montrer ce que vous construisez @ablyRealtime.

Si vous cherchez des moyens d'étendre ce projet, vous pouvez envisager de le faire :

  • Création d'une application de télévote

  • Ajout d'une base de données pour stocker les messages

  • Ajout de la possibilité d'envoyer un texte de réponse.

Faites-nous savoir

Si ce tutoriel vous a été utile, ou si vous utilisez Next.js et Ably dans votre projet, nous aimerions en savoir plus. Envoyez-nous un message sur Twitter ou envoyez-nous un courriel à devrel@ably.io.

Partager:

https://a.storyblok.com/f/270183/400x533/e7cf7a7926/jo-frank.png
Jo Franchetti

Jo is a developer advocate at Ably. She is passionate about Realtime Data, PWAs and great CSS. She has 10 years of experience as a front end developer and has worked in various parts of the tech industry from startups, agencies, charities to large organisations. She is also an instructor/mentor at codebar.io and Front End Foxes where she is able to act on her goals of not only teaching good use of the web but also improving the diversity and inclusivity of the tech industry.