https://d226lax1qjow5r.cloudfront.net/blog/blogposts/using-vonage-apis-with-mongodb-atlas-part-5/mongodb_vonage_p5.png

Verwendung von Vonage APIs mit MongoDB Atlas - Teil 5

Zuletzt aktualisiert am May 24, 2023

Lesedauer: 7 Minuten

In dieser Serie:

Zum Abschluss unserer Serie über MongoDB Atlas und Vonage APIs werfen wir einen Blick auf unsere In-App Messaging API. In den anderen Teilen der Serie haben wir uns in Teil 1 mit der Einrichtung von MongoDB Atlas und Vonage befasst, in Teil 2 mit dem Hinzufügen von Vonage Verify zu einer Anwendung, mit der Ermöglichung von Kundeninteraktionen über unsere Messages API und Meetings API und schließlich mit der Nutzung unserer In-App Messaging API zum Senden von Benachrichtigungen an Benutzer, die im Admin-Bereich unserer Website angemeldet sind.

In-App Messaging

In-App Messaging ist Teil einer umfassenden Reihe von API Call Conversations, wobei die andere Hälfte der API unser In-App Voice-Produkt ist. Wie der Name schon sagt, ist In-App Messaging für das Senden von Textnachrichten von einem Client-Gerät zu einem anderen zuständig, während In-App Voice den Sprachverkehr abwickelt. Für diese APIs gibt es SDKs für iOS, Android und moderne Webbrowser. Wir zeigen das Web Client SDK für unsere Demo, aber Sie können es erweitern, um eine plattformübergreifende Kommunikation von jeder Kombination aus Web, iOS und Android zu ermöglichen.

In-App Messaging und In-App Voice werden von zwei weiteren APIs unterstützt, die unser Produkt Conversations umfassen. Dabei handelt es sich um die Conversation API, bei der es sich um Ereignisse zwischen einem oder mehreren Mitgliedern handelt, und um die Users API, die Informationen zum Benutzerkontext verarbeitet. Der allgemeine Arbeitsablauf besteht darin, dass sich ein Benutzer über Ihre Anwendung authentifiziert und mit einem Benutzer in unserer Benutzer-API verknüpft wird. Dieser Benutzer wird Mitglied in verschiedenen Konversationen oder Ereignisspeicher die aus verschiedenen ausgelösten Ereignissen bestehen wie text, message:submitted, member:joinedusw.

Jedes Client SDK kommuniziert mit diesen Backend-Servern, um die Echtzeit-Kommunikation durch Sprach- oder Text-Ereignisse zu erleichtern. Auf diese Weise haben Sie als Entwickler eine einzige Schnittstelle für die Interaktion mit unseren APIs, und die SDKs übernehmen die gesamte Arbeit der Verbindung und Arbeit mit unseren APIs. So müssen Sie sich keine plattformabhängigen Nachrichtensysteme oder Möglichkeiten zur Weiterleitung von Nachrichten zwischen verschiedenen Plattformen einfallen lassen.

Wir werden die In-App Messaging API für unsere Restaurant-Demo verwenden, um jedem angemeldeten Administrator eine Nachricht zu senden. Daraufhin erscheint ein Popup-Fenster mit einem Link zu der angeforderten Besprechung auf deren Bildschirm. Während wir es nur für eine einzige Benachrichtigung verwenden, können Sie dies auf ein ganzes Chat-System ausweiten. Wir verwenden die nexmo-client um die gesamte Arbeit im Browser zu erledigen, und wir werden einen benutzerdefinierten Client in unserem Backend-Servercode verwenden, um mit den Conversation APIs zu kommunizieren.

Die Admin-Benachrichtigungen

Schauen wir uns zunächst an, wie der Verwaltungsbereich funktioniert. Wir möchten, dass eine Benachrichtigung erscheint, wenn ein Nutzer eine Besprechung beantragt. Für die Pop-up-Benachrichtigungen können wir Folgendes verwenden @meforma/vue-toasterverwenden, ein VueJS-Plugin, das Pop-up-Benachrichtigungen im Toast-Stil erzeugt (Toasts sind kleine Benachrichtigungen, die am unteren Rand des Bildschirms auftauchen und dann verschwinden).

Aber wie erhalten wir die Benachrichtigung? Wir müssen das nexmo-client Web-SDK verwenden, um eine Verbindung zu unserer Vonage-Anwendung herzustellen und dann die richtige Konversation oder Reihe von Nachrichten zu abonnieren. Wir haben eine Benachrichtigungskomponente erstellt, die sich mit der Konversation verbindet und alle neu eingehenden Benachrichtigungen anzeigt.

import ConversationClient from 'nexmo-client'
import { createToaster } from '@meforma/vue-toaster'
import { authenticationStore } from '../stores/authenticationStore';

const authStore = authenticationStore();
const toaster = createToaster({ dismissable: true });

async function boot() {
    const data = await fetch(import.meta.env.VITE_API_URL + '/jwt', {
        method: 'POST',
        body: JSON.stringify({username: authStore.username}),
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + authStore.token
        }
    })
        .then(resp => resp.json())
        .catch(err => console.log(err));
    
    const jwt = data.token
    const conversationID = data.conversation

    const client = new ConversationClient({ debug: true })
    let app = await client.createSession(jwt)
    const conversation = await app.getConversation(conversationID)

    conversation.on("support_request", async (sender: any, event: any) => {
        toaster.show(`${event.body.email} has request support: <a target="_blank" href="${event.body.host_url}">Join Meeting</a>`);
    });
}

boot()

Wir benötigen ein Autorisierungs-Token, um das Web-SDK mit Vonage zu verbinden. Dieses Token ist ein signiertes JWT mit dem privaten Schlüssel, den wir in Teil 1 beim Erstellen einer Vonage-Anwendung generiert haben. Dieses JWT ermöglicht es dem Web-SDK, mit den Vonage-APIs zu kommunizieren und sich zu authentifizieren. Dies entspricht in etwa der Art und Weise, wie MongoDB Realms unseren Admin-Benutzer authentifiziert hat.

Umfassende Informationen zur Erstellung von Client-JWTs für die Conversations-API finden Sie in unserer Dokumentation, finden Sie in unserer Dokumentation. In einer Sekunde werden wir uns ansehen, wie wir das JWT erstellen, damit Sie ein Beispiel sehen können, aber jetzt lassen Sie uns mit dem VueJS-Code fortfahren. Im Moment müssen wir uns nur darum kümmern, unseren Back-End-Server zu bitten, ein JWT für unsere Benutzer zu generieren.

Der Back-End-Server gibt zwei Informationen zurück - das signierte Vonage JWT und die Gesprächs-ID, mit der wir uns verbinden können. Diese benötigen wir, um dem Web-SDK mitzuteilen, welche Konversation wir anhören sollen.

Danach erstellen wir ein neues ConversationClient(), ein Objekt aus dem nexmo-client Paket. Wir rufen createSession(jwt) auf dieses Objekt auf und übergeben das JWT, das unser Backend für uns erstellt hat. Dadurch wird unsere Webanwendung bei Vonage authentifiziert. Dann weisen wir sie an, eine bestimmte Konversation abzurufen, nämlich die ID, die unser Backend-Server an uns zurückgegeben hat.

Unsere Anwendung hört jetzt auf Ereignisse, verarbeitet aber nichts. Wir müssen die conversation.on() Methode verwenden, um eingehende Nachrichten zu verarbeiten. Wir verwenden eine benutzerdefinierte Nachricht namens support_request um diesen Namen als ersten Parameter zu übergeben. Der zweite Parameter ist eine Handler-Funktion. Unsere Handler-Funktion extrahiert die Informationen aus der Support-Anfrage und zeigt eine Benachrichtigung an.

Das war's. Wenn Sie sich im Admin-Bereich anmelden und zu Aufträge anzeigengehen, können Sie dies in Aktion sehen. Wenn Sie ein neues Fenster öffnen, sich als Kunde anmelden und eine Bestellung abschicken, einen Videoanruf einleiten, sollte eine neue Benachrichtigung im Verwaltungsfenster erscheinen.

Wie haben wir einen Token erzeugt?

Bevor wir uns den Backend-Code ansehen, wollen wir uns ansehen, wie wir das JWT erstellt haben. Wir müssen dem JWT zwei wichtige Informationen hinzufügen, um ein gültiges clientseitiges Token zu erstellen. Dies ist subdas ist der Benutzer, für den das Token generiert wird. Die andere Information ist patheine Liste von Pfaden, auf die das JWT zugreifen kann.

app.post('/jwt', async (req, res) => {
    const { username } = req.body;
    const conversation = await conversations.fetchByName('pos-notifications');
    const conversationPath = `/*/conversations/${conversation.id}/**`;
    let acl = {
        "paths": {
            "/*/sessions/**": {},
          }
    }
    acl.paths[conversationPath] = { methods: ['GET'] }

    const key = readFileSync(process.env.VONAGE_PRIVATE_KEY);
    const token = tokenGenerate(process.env.VONAGE_APPLICATION_ID, key, {
        sub: username,
        acl: acl,
    });
    res.json({ token, conversation: conversation.id })
})

Um unser Token auf das zu beschränken, was wir brauchen, setzen wir unsere ACL auf /*/sessions/** und /*/conversations/<conversation-id>/**. Das bedeutet, dass unser JWT nur für die spezifische Konversation gültig ist, an die unsere Benachrichtigungen gesendet werden, nämlich pos-notifications. Sollte jemand das Token entführen, würde es nur den Zugriff auf eine Konversation ermöglichen.

Wir sichern das JWT weiter ab, indem wir ihm sagen, dass wir nur GET Anfragen an die Konversation zulassen. Das bedeutet, dass unser Frontend oder jeder, der versucht, das JWT zu verwenden, die Konversation nur lesen und nicht verändern kann. In Ihrer Anwendung sollten Sie die Pfade und Methoden für das JWT so streng wie möglich einschränken.

Erstellen einer Benachrichtigung

Wir wissen, wie wir aus einem Gespräch lesen können, aber wie bringen wir ein Ereignis in ein Gespräch ein? Wenn wir in unserer server.ts Datei und gehen zu unserer /api/website/video-call Route gehen, erzeugen wir dort ein neues Ereignis.

const orderRecord = await client.db('restaurant_pos_demo')
    .collection('orders')
    .updateOne(
        { _id: new ObjectId(orderNumber) },
        { $set: { meetingUrl: data._links.host_url.href}}
    )
    .then(async (document) => {
        const userRecord = await client.db('restaurant_pos_demo')
            .collection('users')
            .findOne({ _id: new ObjectId(decodedToken.user_id) });

        await conversations.addEventToConversation(
            'pos-notifications',
            userRecord.username, 
            {
                type: 'custom:support_request',
                body: { 
                    host_url: data._links.host_url.href,
                    email: userRecord.username
                }
            });

        res.json({
            guest_url: data._links.guest_url.href
        })
    });

Wir aktualisieren den Auftrag mit den neuen Besprechungs-URLs. Sobald dies abgeschlossen ist, suchen wir den Benutzer in MongoDB mit Hilfe der users Sammlung und findOne(). Dadurch erhalten wir den Benutzerdatensatz für den authentifizierten Benutzer und können dann mit conversations.addEventToConversation() verwenden, um ein neues Ereignis in unsere Konversation einzubringen. Für alle Benachrichtigungen verwenden wir eine Konversation namens pos-notifications.

addEventToConversation() ist ein Wrapper, der einen Großteil der zugrundeliegenden Arbeit erledigt, die nötig ist, um ein Ereignis zu einer Konversation hinzuzufügen, und ist Teil einer Sammlung von Methoden in conversation.ts die eine Menge von Nachforschungen und Einstellungen für uns erledigen werden.

Wie ich bereits erwähnt habe, ist die Konversations-API eine Kombination aus einer Konversations- und einer Benutzer-API. Wenn wir die Methode addEventToConversation()aufruft, wird die Methode versuchen, eine Unterhaltung mit einem bestimmten Namen zu finden. Diese Gesprächssuche erzeugt ein Gespräch mit einem Namen (in unserem Fall, pos-notification), wenn keine vorhanden ist.

Als Nächstes benötigen wir ein Mitglied, um das Ereignis zu verknüpfen. Mitglieder sind Benutzer, die Teil einer bestimmten Konversation sind. Ein Mitglied ist nur an einer einzigen Unterhaltung beteiligt. Dennoch kann ein Benutzer Mitglied in mehreren Konversationen sein. addEventToConversation() versucht, ein Mitglied anhand der angegebenen E-Mail-Adresse zu finden. Wenn dieses Mitglied nicht Teil der Konversation ist, fügen wir das Ereignis ebenfalls hinzu. Es wird nach einem Benutzer mit dieser E-Mail-Adresse gesucht. Wenn dieser Benutzer nicht existiert, wird er erstellt. Dieser Benutzer wird dann der Unterhaltung als Mitglied hinzugefügt, und die Mitgliederinformationen werden zurückgegeben.

Wir können dann das neue Ereignis in die Konversation einfügen. Das Ereignis wird an alle verbundenen Clients weitergegeben, die die Konversation abhören. Wenn wir ein Ereignis auf dem Server übermitteln, erhalten alle angemeldeten Benutzer auf der Seite "Bestellungen" das Ereignis und die Popup-Benachrichtigung.

Schlussfolgerung

Dies ist nur ein kleiner Vorgeschmack auf die Möglichkeiten der Conversations-API. Sie können Chat-Schnittstellen mit allen Funktionen erstellen, die die Benutzer erwarten, wie z. B. Tippbenachrichtigungen, Bildfreigabe und Nachrichtenspeicherung. Darüber hinaus ist alles in Echtzeit und plattformübergreifend. Ein Webbenutzer kann eine Benachrichtigung an einen iOS-Client auf die gleiche Weise senden wie an einen Android-Client oder einen anderen Web-Client.

Sie können dies auch mit der In-App Voice koppeln, um Echtzeit-Sprachkommunikation zwischen mehreren Clients zu ermöglichen, oder dies mit unserer Voice API kombinieren, damit ein Anwendungsnutzer ein Telefon anrufen kann oder umgekehrt. Der Kunde könnte stattdessen das Restaurant anrufen, und das Restaurant könnte in seinem Browser antworten!

Damit endet unser Rundgang durch MongoDB Atlas und einige ergänzende APIs von Vonage. Wir hoffen, dass diese Serie Sie dazu inspiriert hat, sich anzusehen, was jede unserer Plattformen bietet und wie sie für Sie hilfreich sein könnten. Wenn Sie Fragen haben, wenden Sie sich bitte wie immer an unsere Entwicklerberater.

Viel Spaß beim Codieren!

Teilen Sie:

https://a.storyblok.com/f/270183/384x384/3bc39cbd62/christankersley.png
Chris TankersleyTooling-Manager für Entwicklerbeziehungen

Chris ist Developer Relations Tooling Manager und leitet das Team, das Ihre Lieblingstools entwickelt. Er programmiert seit mehr als 15 Jahren in verschiedenen Sprachen und für verschiedene Projekttypen, von der Kundenarbeit bis hin zu Big-Data-Großsystemen. Er lebt in Ohio, verbringt seine Zeit mit seiner Familie und spielt Video- und TTRPG-Spiele.