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

SMS-Benachrichtigungen im Browser anzeigen mit Next.JS, Ably und Vercel

Zuletzt aktualisiert am April 26, 2021

Lesedauer: 11 Minuten

Die Vonage SMS API ermöglicht Ihnen das weltweite Senden und Empfangen von Textnachrichten über eine virtuelle Nummer, die Sie bei Vonage mieten können.

In diesem Tutorial werden Sie die Vonage SMS API, die Ably Echtzeit-Messaging-Plattform, Next.js und Vercel verwenden, um SMS-Nachrichten in Echtzeit im Browser zu empfangen.

Hier erfahren Sie, wie das geht:

Abhängigkeiten

Vonage API-Konto

Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.

In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.

Um diese Anwendung zu erstellen, benötigen Sie außerdem:

Lokale Dev Vorraussetzungen

Sie benötigen einen API-Schlüssel von Ably, um sich bei dem Ably-Dienst zu authentifizieren. Um einen API-Schlüssel zu erhalten, müssen Sie ein Ably-Konto erstellt haben:

  1. Besuchen Sie Ihr App-Dashboard und klicken Sie auf "Neue App erstellen".

  2. Geben Sie der neuen Anwendung einen Namen

  3. Kopieren Sie den privaten API-Schlüssel, sobald die App erstellt wurde. Bewahren Sie ihn sicher auf, da Sie sich auf diese Weise beim Ably-Dienst authentifizieren werden.

Vercel stellt einige Next.js-Befehlszeilentools zur Verfügung, die uns helfen. Sie müssen nicht auf Ihrem System installiert sein, da sie mit npx.

WebSockets in Vercel mit Ably

Vercel and WebsocketsVercel and Websockets

Vercel ist eine Hosting-Plattform, die von Grund auf zum Hosten von Next.js-Apps und Serverless Functions entwickelt wurde. Sie ermöglicht Benutzern die Bereitstellung von Serverlose Funktioneneinzusetzen, die im Wesentlichen nur Codeblöcke sind, die auf eine HTTP-Anfrage reagieren.
Diese Funktionen haben jedoch ein maximales Ausführungs-Timeout, was bedeutet, dass es unmöglich ist, eine WebSocket-Verbindung auf diese Weise aufrechtzuerhalten.

An dieser Stelle kommt Ably ins Spiel. Der Client kann eine Verbindung zu einem Ably-Kanal verbinden und Nachrichten auf diesem Kanal senden und empfangen, um Ihrer Anwendung Echtzeitfunktionalität hinzuzufügen, indem er Ihre WebSocket-Verbindungen für Sie verwaltet. In dieser Anleitung wird beschrieben, wie man eine Anwendung erstellt, die Echtzeit-Funktionalität verwendet. Wenn Sie mehr über WebSockets in Next.js und Vercel erfahren möchten, lesen Sie "Erstellen einer Echtzeit-Chat-App mit Next.js und Vercel".

Aufbau der Realtime-SMS-App

So erstellen Sie die Starter-App:

  1. Geben Sie in Ihrem Terminal npx create-next-app ein, um eine leere Next.js-App zu erstellen.

  2. Erstellen Sie eine Datei namens .env in der Wurzel des Verzeichnisses; hier werden wir die Umgebungsvariablen des Projekts ablegen.

  3. Fügen Sie Ihren Ably-API-Schlüssel in die .env-Datei ein:

ABLY_API_KEY=your-ably-api-key:goes-here
  1. Navigieren Sie zum Verzeichnis Ihrer Next.js-Anwendung und geben Sie in die Konsole ein:

npm run dev

Der Next.js Dev-Server wird gestartet und Sie sehen eine leere Next.JS-Starter-App. Darauf bauen Sie unsere SMS-in-the-Browser-App auf.

Echtzeit-Pub/Sub-Messaging mit Ably

Diese Anwendung verwendet Ably für Pub/Sub-Nachrichten zwischen den Nutzern. Pub/Sub steht für "Publish and Subscribe" (Veröffentlichen und Abonnieren) und ist ein beliebtes Muster für die Echtzeit-Datenübertragung. Die Anwendung sendet, oder publishNachrichten über einen Ably-Kanal. Die Clients, die die App verwenden, werden subscribed mit dem Kanal verbunden und können die Nachrichten empfangen.

Authentifizierung mit dem Ably-Dienst

Vercel Next.js-Anwendungen führen keinen traditionellen "serverseitigen Code" aus. Sie können jedoch JavaScript-Dateien zu /pages/api/*hinzufügen, und die Vercel Deployment-Engine wird jede einzelne als API-Endpunkt behandeln und sie als serverlose Funktionen für Sie verwalten.

Für die lokale Entwicklung führen die Next.js-Tools diese Funktionen in einem Node-Server aus, sodass sie so funktionieren, wie Sie es in Ihrer lokalen Entwicklungsumgebung erwarten würden. Sie fügen eine Next.js / Vercel serverlose Funktion zum Startcode hinzu, den Sie zuvor erstellt haben, um Ihre App mit Ably zu authentifizieren und das Senden und Empfangen von Nachrichten über den Ably-Dienst zu ermöglichen.

Schreiben der Serverless-Funktion zur Verbindung mit Ably

Sie müssen das Ably npm-Paket (es ist wichtig, dass Sie Ably 1.2.5+ für diese Anwendung verwenden, um mit Vercel kompatibel zu sein).

Führen Sie im Terminal, im Stammverzeichnis Ihrer neuen Anwendung, aus:

npm install ably@1.2.5-beta.1

Als nächstes erstellen Sie eine Datei namens ./pages/api/createTokenRequest.js an, in die Sie den folgenden Code einfügen:

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);
};

Diese serverlose Funktion verwendet das Ably SDK, um eine tokenRequest mit Ihrem API-Schlüssel. Dieses Token werden Sie später verwenden - es ermöglicht Ihnen, Ihren "echten" API-Schlüssel sicher aufzubewahren, während Sie ihn in der Next.js-App verwenden.
Standardmäßig ist diese API so konfiguriert, dass sie auf http://localhost:3000/api/createTokenRequest. Sie werden diese URL dem Ably SDK in Ihrem Client zur Verfügung stellen, um sich bei Ably zu authentifizieren.

Empfangen einer SMS mit Vonage und Vercel

Vonage ermöglicht Ihnen die Konfiguration von Mobiltelefonnummern in seinem API-Dashboard. Wenn eine SMS empfangen wird, wird sie Ihre API auslösen.

Zu diesem Zweck müssen Sie eine Vercel Serverless function zu unserer Next.js-App hinzufügen. Diese serverlose Funktion wird von Vonage jedes Mal aufgerufen, wenn eine SMS empfangen wird (sobald Sie eine Telefonnummer eingerichtet haben!). Sie müssen etwas Code in diese Funktion einfügen, um die SMS-Nachricht zu entpacken, und sie dann an Ihre React-App senden, indem Sie eine Ably channel.

Dieser Vorgang ähnelt der Einrichtung Ihres Ably createTokenRequest.

Erstellen Sie eine Datei namens ./pages/api/acceptWebhook.js in die der folgende Code eingefügt wird:

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']
    };
}

Wir kehren jetzt zur App zurück, aber wir werden am Ende auf diese Funktion zurückkommen, sobald die App auf Vercel und Ihre Funktion hat eine public url.

Reagieren auf SMS-Nachrichten mit der SmsComponent

Seiten in Next.js sind React-Komponenten, also ist die pages/index.js Homepage ist die React-Komponente, die das Seitenlayout enthält.

Dies ist die Standardseite, die von create-next-appgeneriert wird; Sie fügen Ihre Komponente hinzu - die Anwendungslogik befindet sich in SmsComponent.jsx.

Beginnen Sie damit, die benötigten Importe am Anfang der Datei zu referenzieren:

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

Definieren Sie dann die Funktion, die als React-Komponente exportiert werden soll.

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

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

und benutzen Sie Ihre erste react hook:

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

useChannel ist ein react-hook artige API für das Abonnieren von Nachrichten aus einem Ably-Kanal. Sie übermitteln ihr einen Kanalnamen und einen Callback, der aufgerufen wird, sobald eine Nachricht empfangen wird.

Als Nächstes formatieren Sie die Daten für den Bildschirm, damit jede Nachricht zusammen mit der Uhrzeit ihres Eingangs und der Telefonnummer des Absenders angezeigt werden kann.

   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>
    );
  });

Erstellen Sie schließlich Ihre Komponente und geben Sie sie zurück:

  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>
  )
}

Ganz unten in der Datei wird die Funktion exportiert als SmsComponent exportiert, so dass sie in der Indexseite Next.js referenziert werden kann.

Korrekte Verwendung von Ably in React-Komponenten

Eine der kniffligeren Aufgaben bei der Verwendung von Ably mit React Functional Components ist es, zu wissen, wann und wo die Instanz des SDK zu erstellen ist und wann und wo eine Verbindung zu Ihrem Kanal/Ihren Kanälen herzustellen ist. Sie möchten vermeiden, das SDK zu instanzieren, wenn die Komponente gerendert wird, da dies mehrere Verbindungen herstellen und Ihr Ably-Kontolimit ausreizen könnte.

Um sicherzustellen, dass die Anwendung das Neuzeichnen von Komponenten sowie das Ein- und Aushängen korrekt handhabt, - AblyReactEffect exportiert einen React-Hook um mit dem Ably SDK zu interagieren.

React-Hooks können beim ersten Mal etwas ungewöhnlich erscheinen. Ein Hook ist eine Funktion, die:

  • Führt die Funktionalität aus, die Sie erwarten würden componentDidMount ausführen

  • Liefert eine weitere Funktion zurück, die vom Framework ausgeführt wird, wo componentDidUnmount aufgerufen werden würde

  • Führt jedes andere Verhalten aus, das es braucht

Dieser React Hook basiert auf useEffect. Wenn er referenziert wird, erstellt er eine Instanz des Ably SDK (er tut dies nur einmal), die so konfiguriert ist, dass sie die URL Ihrer Serverless-Funktion an createTokenRequest für die Authentifizierung:

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

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

Die Instanzierung der Ably-Bibliothek außerhalb des Anwendungsbereichs der Komponente bedeutet, dass sie nur einmal erstellt wird, was die Nutzung des Limits gering hält.

Als Nächstes müssen Sie die Funktion erstellen, die Sie exportieren werden, Ihren Hook, um ihn in Ihrer Komponente zu verwenden. Nennen wir sie useChannelSie benötigt den Kanalnamen und einen Rückruf als Argumente. Jedes Mal, wenn useChannel aufgerufen wird, erhalten Sie get den angeforderten Kanal aus dem Ably-JS SDK und bereiten die Hook-Funktionen vor.

  • onMount ist der Code, der jedes Mal ausgeführt wird, wenn Ihre Komponente gerendert wird. Innerhalb von onMount abonnieren Sie den angegebenen Kanal und lösen callbackOnMessage wenn eine Nachricht empfangen wird.

  • onUnmount ist der Code, der immer dann ausgeführt wird, wenn die Komponente abgemountet wird, bevor sie neu gerendert wird. Hier wird der Kanal abgemeldet, wodurch eine versehentliche Vervielfachung der Verbindungen verhindert wird, was wiederum unsere Kontolimits schont.

  • useEffectHook ist eine Funktion, die diese Funktionen korrekt aufruft und onUnmount zur Verwendung durch React zurückgibt.

Der exportierte Hook in AblyReactEffect.js wird wie folgt aussehen:

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];
}

Der useChannel Hook gibt sowohl den aktuellen Ably-Kanal als auch das Ably-SDK zurück, das der aufrufende Code zum Senden von Nachrichten verwenden kann. Dieser Hook kapselt Ably pub/sub für funktionale React-Komponenten an einer Stelle, so dass Sie sich nicht an anderer Stelle darum kümmern müssen und der Code, der ihn verwendet, die empfangenen Nachrichten verarbeiten kann.

Alles schön machen mit Modul-CSS -SmsComponent.module.css

Beim Schreiben der Chat-Komponente haben Sie vielleicht bemerkt, dass Next.js einige vom Compiler erzwungene Konventionen hat, die vorschreiben, wo Sie Ihr CSS aufbewahren und wie Sie es importieren.

Erstellen Sie für diese Anwendung eine CSS-Datei mit demselben Namen wie die .jsx Datei, nur mit den Erweiterungen .module.cssDadurch wird die Verwaltung der Komponente einfacher. Wenn Sie diese Komponente in Zukunft löschen möchten, können Sie auch die CSS-Datei einfach entfernen.

Einmal erstellt, kann es in die Komponente importiert werden:

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

Wenn Sie eine CSS-Klasse für ein JSX-Element erstellen, verwenden Sie die folgende Syntax für das Element:

className={styles.yourClassName}

und das zugehörige CSS würde wie folgt aussehen:

.yourClassName {
  styles: gohere;
}

Hosting auf Vercel

Wir verwenden Vercel als Entwicklungsserver und Build-Pipeline.

Der einfachste Weg, Next.js in der Produktion einzusetzen, ist die Verwendung der Vercel-Plattform von den Machern von Next.js. Vercel ist eine All-in-One-Plattform mit Global CDN, die statische und Jamstack-Bereitstellung und Serverless-Funktionen unterstützt. -- Die Next.js-Dokumentation

Um Ihre neue SMS-in-the-Browser-Anwendung in Vercel bereitzustellen, müssen Sie Folgendes tun:

  1. Erstellen Sie ein GitHub-Konto (falls Sie noch keins haben)

  2. Veröffentlichen Sie Ihre Anwendung in einem GitHub-Repository

  3. Ein Vercel Konto erstellen

  4. Erstellen Sie eine neue Vercel-App und importieren Sie Ihre App aus Ihrem GitHub-Repository. (Dazu müssen Sie Vercel autorisieren, Ihr GitHub-Konto zu nutzen)

  5. Fügen Sie Ihre ABLY_API_KEY als Umgebungsvariable

  6. Beobachten Sie die Bereitstellung Ihrer Anwendung

  7. Besuchen Sie die neu erstellte URL in Ihrem Browser!

Einrichten einer SMS-Nummer für Ihre App

Um SMS-Nachrichten zu empfangen, müssen Sie bei Vonage eine virtuelle Telefonnummer mieten und diese konfigurieren.

Melden Sie sich zunächst bei Ihrem Vonage-Konto an, indem Sie das Dashboard. Sobald Sie Ihr Konto erstellt und verifiziert haben, können Sie eine Nummer kaufen, indem Sie zu Nummern => Nummern kaufen gehen. Suchen Sie nach einer Nummer, die für Sie geeignet ist, und fügen Sie ein Guthaben hinzu, um die Nummer zu bezahlen.

Sobald Sie Ihre Nummer erworben haben, müssen Sie die SMS Inbound Webhook URL.

Gehen Sie dazu auf Zahlen => Ihre Zahlen => Klicken Sie auf das Stiftsymbol.

Sie werden mit einem modalen Dialogfeld begrüßt, in das Sie Ihre acceptWebhook API-URL in das Feld eingeben.

Heißt Ihre Vercel-App your-vercel-appheißt, würde die Webhook-URL lauten https://your-vercel-app.vercel.app/api/acceptWebhook.

Machen Sie es zu Ihrem!

Diese Demo ist quelloffen, forken Sie sie und machen Sie sie zu Ihrer eigenen. Vergiss nicht, uns zu zeigen, was du gebaut hast @ablyRealtime.

Wenn Sie nach Möglichkeiten suchen, dieses Projekt zu erweitern, könnten Sie dies in Betracht ziehen:

  • Aufbau einer Televoting-App

  • Hinzufügen einer Datenbank zum Speichern von Nachrichten

  • Hinzufügen der Möglichkeit, einen Antworttext zu senden.

Informieren Sie uns

Wenn dieses Tutorial hilfreich war oder Sie Next.js und Ably in Ihrem Projekt verwenden, würden wir uns freuen, wenn Sie uns davon berichten. Schreiben Sie uns eine Nachricht auf Twitter oder senden Sie uns eine E-Mail an devrel@ably.io.

Share:

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.