In diesem Artikel erfahren Sie, wie Sie einen GitHub -Tracker erstellen, der Benutzer benachrichtigt, wenn es ein neues Problem/PR auf einem verfolgten Repository gibt, indem Push -Benachrichtigungen gesendet werden.
GitHub sendet bereits Benachrichtigungen über E -Mails, wenn Sie sich entschieden haben. Viele Studien haben jedoch gezeigt, dass Push -Benachrichtigungen Benutzer besser erreichen als E -Mails. Nachdem Sie den Github -Tracker durch das folgende Tutorial erstellt haben, haben Sie gelernt, wie man:
gelernt hatEs gibt einige Fähigkeiten und Dienste, die Sie diesem Artikel folgen müssen:
Schauen wir uns an, was diese sogenannten "Push -Benachrichtigungen" sind.
Sie müssen mit regelmäßigen Benachrichtigungen vertraut sein. Dies sind kleine Textblasen, die auf Ihrem Bildschirm erscheinen, um Sie über etwas zu benachrichtigen. Push-Benachrichtigungen sind ähnlich, außer dass sie nicht on-Demand erzeugt werden, aber sie werden nach Erhalt von Push-Ereignissen erzeugt. Push -Benachrichtigungen funktionieren Wenn eine App geschlossen ist , während regelmäßige Benachrichtigungen von Ihnen erforderlich sind, die App zu öffnen.
Push -Benachrichtigungen werden in modernen Webbrowsern wie Chrome unterstützt, indem sie etwas namens Servicearbeiter verwenden. Servicemitarbeiter sind kleine JavaScript -Teile, die getrennt vom Haupt -Thread des Browsers ausgeführt werden, und können daher offline ausgeführt werden, wenn Ihre App als PWA (progressive Webanwendung) installiert ist.
Push -Benachrichtigungen werden in Chat -Anwendungen verwendet, um Benutzer zu benachrichtigen, wenn sie über ungelesene Nachrichten, in Spielen, um Benutzer über Spielereignisse, in Nachrichtenseiten, die Benutzung von Benutzern über Bruchartikel und für viele andere Zwecke zu informieren.
Es gibt vier Schritte, um Push -Benachrichtigungen in Ihrer App anzuzeigen:
Wählen Sie das Framework aus. Sie können TypeScript verwenden, wenn Sie möchten. Ich werde reguläre JavaScript verwenden.
<span>npm init vite </span>
Als nächstes CD in den Projektordner und Sie können Ihrer Anwendung Tailwindcss hinzufügen und alle Abhängigkeiten mit diesen Befehlen installieren:
<span>npm init vite </span>
Öffnen Sie schließlich das Projekt in Ihrem bevorzugten Code -Editor und führen Sie NPM Run Dev oder Yarn Dev aus, um die Anwendung unter http: // localhost: 3000 zu starten.
Wir werden die GitHub -API verwenden, um eine Liste von Problemen zu erhalten und Anfragen für ein Repository zu ziehen, den der Benutzer verfolgt hat. Die nachverfolgten Repositorys eines Benutzers und sein Benutzername werden in der MongoDB -Datenbank gespeichert.
Der erste Schritt wäre, den Benutzer für seinen Benutzernamen zu fordern. Erstellen Sie src/lib/userernamePrompt.svelte, die die Komponente sein wird, die dies tun wird. Hier ist meine Benutzeroberfläche für das Formular, aber Sie können sie so entwerfen, wie Sie möchten:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Fügen Sie diese Komponente in app.svelte wie SO:
hinzu<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Fügen Sie als nächstes die Haupt -Tracker -Benutzeroberfläche hinzu. Datei erstellen SRC/lib/Tracker.svelte und fügen Sie den folgenden Code hinzu:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
, um Ihre Komponente zu testen, vorübergehend Die BenutzernAmePrompt -Komponente für die neue Trackerkomponente in App.svelte:
auszutauschen<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
Ihr Bildschirm sollte jetzt so aussehen:
Hinweis: Denken Sie daran, App.sumvelte in seinem vorherigen Code wiederherzustellen!
Wir müssen einen Back-End-Server haben, um Push-Ereignisse an unsere Anwendung zu senden. Dies bedeutet, dass Sie ein neues (vielleicht) ExpressJS -Projekt erstellen und dann separat einsetzen müssen. Dies alles wird Kopfschmerzen für jemanden sein, der gerade mit Push -Benachrichtigungen experimentiert.
Vercel Cloud für die Rettung! Cloud -Funktionen sind wie Expressrouten. Sie können Code ausführen und Ihnen eine Antwort geben, wenn Sie die URL abrufen. Vercel hat Unterstützung für Cloud -Funktionen; Sie müssen nur Dateien im API -Ordner erstellen. Sie verwenden Cloud-Funktionen, um mit MongoDB zu interagieren, da die Client-Seite der Geheimnisse niemals eine gute Sache ist.
Stellen Sie zunächst sicher, dass Sie einen Cluster in MongoDB Atlas haben. MongoDB hat einen kostenlosen Plan ( m0 ). Erstellen Sie also einen, wenn Sie es noch nicht getan haben. Gehen Sie nun in der Seitenleiste Ihres Atlas Dashboard zur Registerkarte "Datenbankzugriff". Fügen Sie einen neuen Datenbankbenutzer hinzu, indem Sie auf der rechten Seite auf die grüne Schaltfläche klicken. Geben Sie die Details des Benutzers ein (vergessen Sie das Kennwort nicht) und erstellen Sie den Benutzer.
Um eine Verbindung zur Datenbank herzustellen, benötigen Sie die Verbindungszeichenfolge. Speichern Sie den neuen Benutzer und das Passwort irgendwo und gehen Sie in den Überblick Ihres Clusters. Klicken Sie rechts auf die Schaltfläche "Verbinden Sie" und wählen Sie Ihre Anwendung als Verbindungsmethode an. Sie sollten eine Verbindungszeichenfolge sehen, die dem unten ähnelt.
Jetzt, da Sie die Verbindungszeichenfolge haben, können Sie eine Verbindung zu Ihrer Datenbank herstellen. Zuerst müssen Sie die aktuelle Anwendung für Vercel bereitstellen. Der einfachste Weg, dies zu tun, ist Github zu verwenden.
Erstellen Sie ein neues Github -Repository und drücken Sie Ihren Code darauf. Gehen Sie anschließend zu Ihrem Vercel Dashboard und klicken Sie auf die Schaltfläche Neue Projekt. Importieren Sie Ihr GitHub -Repository, stellen Sie sicher, dass das Framework vite ist, und fügen Sie eine Umgebungsvariable, die als mongoDB_url bezeichnet wird. Setzen Sie ihren Wert auf die Verbindungszeichenfolge der MongoDB -Datenbank.
Sobald Ihre Website bereitgestellt wurde, müssen Sie Ihren lokalen Entwicklungsbefehl von Yarn Dev in Vercel Dev ändern. Wenn Sie den Befehl ausführen, klicken Sie auf Ja.
Hinweis: Stellen Sie sicher Wie ich, wenn Sie mit der Verwendung von VITE mit Vercel Dev auf ein Problem stoßen, ändern Sie den Befehl Entwicklungsbefehl
Ihres Projekts zu vite -Port $ port aus vite im Vercel Dashboard.Dies ermöglicht es uns, Cloud -Funktionen mit den richtigen Umgebungsvariablen lokal zu verwenden.
Fügen wir eine Helferdatei hinzu, mit der wir auf MongoDB zugreifen können, ohne zu viele Verbindungen zu öffnen. Erstellen Sie die Datei -API/_mongo.js und geben Sie den folgenden Code hinein. Eine Datei im API -Verzeichnis, die mit einem _ vorangestellt ist, wirdnicht als Wolkenfunktion behandelt. Auf diese Weise können wir Helfer und andere Logik in separaten Dateien hinzufügen:
Das Verbindungsversprechen anstelle des Hauptclients selbst verhindert, dass wir überflüssige Verbindungen haben, da wir auf einer serverlosen Plattform arbeiten.
Verwenden von CommonJs anstelle von Esmodules<span>npm init vite </span>
Beachten Sie, wie ich die Forderung verwende, anstatt importieren? Dies liegt daran, dass Vercel Cloud zum Zeitpunkt des Schreibens
nichtHier gibt es ein Problem. Wenn Sie das paket.json unserer App sehen, werden Sie feststellen, dass es eine Zeile "Typ" hat: "Modul". Dies bedeutet, dass jede JavaScript -Datei im Projekt eine Esmodule ist. Dies ist nicht das, was wir wollen, um alle Dateien im API -Verzeichnis als CommonJS -Dateien zu markieren, sodass wir die Erforderliche Anweisung verwenden, api/package.json erstellen und diese Zeile darin hinzufügen können:
Dies ermöglicht es uns nun, Erforderliche Aussagen im API -Verzeichnis zu verwenden. Installieren Sie den MongoDB -Verbindungs -Treiber mit diesem Befehl:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Der Tracker funktioniert ab sofort nicht wirklich, also lass uns das beheben.
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Zur Authentifizierung müssen wir den Benutzernamen speichern, den der Benutzer in der MongoDB -Datenbank eingibt.
Holen Sie sich den MongoDB -Client als nächstes wie SO:
<span>npm init vite </span>
extrahieren Sie den Benutzernamen aus dem Körper der Anfrage:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Als nächstes müssen Sie diesen Benutzernamen in der Datenbank speichern:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Schließlich sollte die Datei api/storesusername.js aussehen:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
Bereiten Sie Ihre Anwendung in Vercel mit Vercel ein oder durch Drücken auf GitHub, und Ihre serverlose Funktion sollte live sein! Sie können es mit Curl mit diesem Befehl testen:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
Dies sollte ein neues Dokument in der Benutzersammlung erstellen, wobei das Feld _id der Benutzername ist, den wir gerade angegeben haben.
Jetzt ist nur noch übrig, diese Funktion am vorderen Ende zu holen. In SRC/LIB/usernamePrompt.svelte müssen Sie in der Subjektfunktion zunächst eine Anfrage an die Cloud -Funktion senden und dann den Benutzernamen in LocalStorage einsetzen, damit wir wissen, dass der Benutzer authentifiziert ist. Sie können Anfragen mit der Fetch -Funktion senden:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>
Wir laden die Seite neu, denn in App.sum., wenn die Seite geladen wird, müssen wir überprüfen, ob es in LocalStorage einen Benutzernamen gibt. Wenn dies der Fall ist, können wir den Bildschirm "BenutzernamePrompt" überspringen. Fügen Sie diesen Code dazu in das Skript -Tag von App.svelte hinzu:
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
Der obige Code überprüft den LocalStorage auf einen Benutzernamen und setzt Isloggedin auf true, wenn er existiert. Als nächstes müssen wir nur das DOM aktualisieren. Fügen Sie direkt unter dem Skript -Tag von App.svelte Folgendes hinzu:
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>
Fügen wir nun die Funktionalität für die tatsächlichen Tracking -Funktionen des Tracker hinzu. Wenn Sie Tracker.svelte öffnen, werden Sie feststellen, dass es zwei Funktionen gibt - Track () und Untrack (). Diese Funktionen sollten Repositorys und nicht verfolgen, indem sie der Datenbank hinzugefügt werden.
Aber vorher müssen Sie ein paar weitere Cloud -Funktionen hinzufügen. Eine, um ein Repository zu verfolgen, ein anderer, und eine zuletzt, um die nachverfolgten Repositorys eines Benutzers zu erhalten.
Lassen Sie uns nacheinander an ihnen arbeiten.
Datei -API/TrackRepo.js erstellen. Dies wird /api /trackrepo zugeordnet:
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
Wenn ein Benutzer ein Repository verfolgen möchte, sendet er eine Postanforderung an diese Funktion mit dem Namen des Repositorys und ihrem Benutzernamen im Körper. Die Funktion fügt den Namen des Repositorys im Feld TrackedRepos der Benutzersammlung hinzu. Fügen Sie einen Code hinzu, um diese Felder aus dem Körper zu erhalten:
<span>const mongoPromise = require("../src/lib/mongo"); </span><span>// All cloud functions must export a function that takes a req and res object. </span><span>// These objects are similar to their express counterparts. </span>module<span>.exports = async (req<span>, res</span>) => { </span> <span>// TODO </span><span>}; </span>
und schließlich fügen Sie den Code hinzu, um das Repository zu verfolgen, indem Sie es der Datenbank hinzufügen:
module<span>.exports = async (req<span>, res</span>) => </span> <span>// Wait for the client to connect </span> <span>const mongo = await mongoPromise; </span><span>} </span>
Und so sollte API/TrackRepo.js aussehen:
<span>// ... </span><span>const { username } = req.body; </span> <span>// Check if the username is valid </span><span>if (typeof username !== "string" || !username.trim()) { </span> res<span>.status(400).json({ message: "Please send the username" }); </span> <span>return; </span><span>} </span>
Jetzt ist es Zeit, diese Funktion im Tracker zu verwenden. Öffnen Sie SRC/lib/treaker.svelt und ändern Sie die Funktion der Track () in dieser Stelle:
<span>// Get the collection </span><span>const usersCol = mongo.db().collection("users"); </span><span>// Check if the username already exists in the database </span><span>if (await usersCol.findOne({ _id: username })) { </span> res<span>.status(400).json({ message: "User already exists!" }); </span> <span>return; </span><span>} </span><span>// We want the username to be the identifier of the user </span><span>await usersCol.insertOne({ _id: username }); </span> <span>// Everything went well :) </span>res<span>.status(200).json({ message: "Username recorded" }); </span>
Wenn Sie nun ein Repository in die Eingabe eingeben und auf die Spur klicken, sollte es in der Datenbank gespeichert werden.
Fügen wir eine Cloud -Funktion hinzu, um ein Repository zu entziehen. Erstellen Sie die Datei -API/untrackrepo.js. Dies wird /api /untrackrepo zugeordnet:
<span>npm init vite </span>
Der Anforderungskörper dieser Cloud -Funktion ist der der der TrackRepo -Funktion entspricht - der Benutzername des Benutzers und das Repo:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Nächst
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
Listing verfolgte Repositories
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
<span>const mongoPromise = require("../src/lib/mongo"); </span><span>// All cloud functions must export a function that takes a req and res object. </span><span>// These objects are similar to their express counterparts. </span>module<span>.exports = async (req<span>, res</span>) => { </span> <span>// TODO </span><span>}; </span>
module<span>.exports = async (req<span>, res</span>) => </span> <span>// Wait for the client to connect </span> <span>const mongo = await mongoPromise; </span><span>} </span>
installierten Apps unterstützt. Ja, Sie können Webanwendungen als reguläre Anwendungen mithilfe von unterstützten Browsern installieren-nämlich Chrom- und andere Chrombasis-Browser.
Um eine App installierbar zu machen, müssen Sie sie in eine progressive Web -App umwandeln. Dies ist ein dreistufiger Prozess:Wenn alle drei Schritte ausgeführt werden, wird bei der Bewerbung eine Installationsschaltfläche in der Adressleiste angezeigt.
Servicearbeiter sind JavaScript -Dateien, die im Hintergrund aus dem Haupt -Thread des Browsers ausgeführt werden können. Auf diese Weise können sie Dinge wie offline ausführen, im Hintergrund ausführen und große Dateien herunterladen. Sie werden hauptsächlich zum Zwischenspeichern von Anfragen und zum Anhören von Ereignissen verwendet, die beide tun werden.
Um einen Servicearbeiter hinzuzufügen, müssen Sie wie alle CSS -Dateien eine öffentlich verfügbare JavaScript -Datei hinzufügen. Der Name spielt keine Rolle, aber er wird normalerweise als Service-Worker.js oder Sw.js. genannt. Diese Datei sollte öffentlich wie Ihr CSS bedient werden, also setzen Sie sie in das öffentliche Verzeichnis.
Servicearbeiter arbeiten, indem sie Veranstaltungen anhören. Für das Zwischenspeichern von Dateien, sodass Ihre App offline funktioniert, hören Sie die Installation, aktivieren und holen Sie Ereignisse an. Das Installationsereignis wird aufgerufen, wenn der Servicearbeiter installiert wird. Die Aktivierungsereignis wird aufgerufen, wenn der Servicearbeiter ausgeführt wird, und das Fetch -Ereignis wird aufgerufen, wenn eine Netzwerkanforderung gestellt wird. Event -Hörer können mit self.adDeVentListener () hinzugefügt werden. Erstellen wir eine öffentliche/Service-Arbeiter.js-Datei und fügen Sie den folgenden Code hinzu:
<span>npm init vite </span>
Alles, was übrig bleibt, ist, diesen Servicemitarbeiter zu registrieren. Wir werden das in der Onmount -Funktion von app.svelte tun. Fügen Sie diesen Code am Ende des Rückrufs in Onmount hinzu:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Der obige Code prüft zuerst den Support für Servicearbeiter im Browser und registriert dann unseren Servicearbeiter. Es muss beachtet werden, dass der Pfad in der Funktion "Register () der Pfad relativ zu Ihrer Domäne , nicht zum Projektordner ist - was bedeutet, dass der Servicearbeiter bei HTTP zugänglich sein sollte : // localhost: 3000/service-arbeiter.js, was es ist, da es im öffentlichen Verzeichnis ist.
Wenn Sie nun die Seite neu laden und die Konsole öffnen, sollten Sie die obigen Nachrichten sehen.
Um eine App offline zum Laufen zu bringen, müssen Sie ihren Inhalt mit einem Servicemitarbeiter zwischenspeichern. Da unsere App Anfragen nach Cloud -Funktionen stellt, kann sie nicht viel tun, wenn kein Netzwerk vorhanden ist. Anstatt eine zwischengespeicherte, funktionslose Version der App anzuzeigen, zeigen wir eine Seite an, die angibt, dass wir offline sind. Erstellen Sie eine öffentliche/offline.html -Datei und geben Sie den folgenden Code ein:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Sie können diese Seite, wie Sie möchten, anpassen. Sie müssen diese Seite jetzt zwischenspeichern. Das Caching ist auch ein dreistufiger Prozess, bei dem die drei oben genannten Ereignisse der Dienstarbeiter verwendet werden, die wir angehört haben. So funktioniert es:
Der Cache wird geöffnet und die gewünschten Routen werden mithilfe von cache.add zum Cache hinzugefügt. Dies geschieht während der Installation.
Der ältere Cache wird gelöscht, sodass nur die neueste auf dem Computer des Benutzers gespeichert wird. Dies verwendet weniger Speicher. Dies geschieht während der Aktivierung.
Wir nehmen alle Netzwerkanforderungen ab und prüfen, ob diese Anforderungen Seite Navigations sind - dh sich ändern. Wenn die Anfrage erfolgreich ist, ist alles gut und gut, aber wenn die Anfrage fehlschlägt, liefern wir die Offline.html -Seite, die dem Benutzer angezeigt werden soll. Dies geschieht während des Fetchs.
implementieren wir den ersten Schritt. Öffnen Sie die Service Worker -Datei und ändern Sie den Handler des Installationsereignisses wie SO:
<span>npm init vite </span>
event.waituntil () ist eine Funktion, die dem wartenden Schlüsselwort ähnelt. Callbacks von AddEventListener können nicht asynchron sein. Um diese Funktionalität zu implementieren, sollten wir das Ereignis verwenden.
self.skipwaiting () teilt dem Browser mit, dass wir mit dem Installationsprozess fertig sind. Aktivieren Sie also den Servicearbeiter. Apropos Aktivieren, fügen wir nun den Code hinzu, um alte Caches zu löschen:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
F12 gedrückt haben, und wählen Sie die Registerkarte "Anwendung". In der Seitenleiste sollte es eine Registerkarte Cache Speicher geben. Klicken Sie darauf und Sie sollten /offline.html. bemerken
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Aktualisieren Sie nun die Seite und schalten Sie Ihr Wi-Fi oder Ethernet aus. Sie sollten jetzt unsere Offline -Seite anstelle der Standard -Chrome -Seite "No -Netzwerk" sehen, wenn Sie aktualisiert werden. Diese Offline -Seite hat leider nicht das Dinosaurierspiel, ermöglicht es uns jedoch, die Anwendung als PWA zu installieren.
Hier ist, wie der Servicearbeiter aussehen sollte:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
mit dem -Tag in der HTML mit Ihrer Website verknüpft sein, z. B. wie Sie CSS -Dateien verknüpfen. Fügen wir ein Manifest für unsere Anwendung hinzu. Fühlen Sie sich frei, einen Generator für diesen zu verwenden:
Sie müssen eine Reihe von Symbolen für die Anwendung herunterladen. Diese Ikonen haben unterschiedliche Größen und werden von verschiedenen Betriebssystemen verwendet. Sie können sie aus dem Quellcode -Repository oder mit diesem Link herunterladen. Stellen Sie sicher, dass Sie die ZIP -Datei an öffentliche/Symbole extrahieren.Als nächstes müssen Sie das Manifest und die Symbole zur index.html -Datei hinzufügen. Sie können dies tun, indem Sie den folgenden Code einlegen:
<span>npm init vite </span>
Offene Chrome -Entwickler -Tools, indem Sie f12 drücken und zur Registerkarte Lighthouse gehen und ein neues Audit erstellen. Sie sollten jetzt eine "installierbare" Punktzahl im PWA -Bereich erhalten. Dies bedeutet, dass Sie Ihre Website erfolgreich in ein WebApp konvertiert haben und sie jetzt installieren können, indem Sie auf die Schaltfläche in der Adressleiste klicken.
Bevor wir Push -Benachrichtigungen senden können, müssen wir vom Benutzer die Berechtigung erhalten. Sie können die Benachrichtigung verwenden. Diese Methode ist asynchrones und gibt eine String zurück, die dem Standard gleich sein, verweigert und gewährt werden kann. Diese werden zurückgegeben, wenn der Benutzer entweder das X drückt, Leugnung drückt oder die Benachrichtigungsaufforderung zulässt. Wir werden den Onmount -Hook in app.svelte verwenden, um diese Funktion aufzurufen:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Sie sollten jetzt ein Popup bekommen, in dem Sie aufgefordert werden, Benachrichtigungen in der App zu ermöglichen. Nachdem wir nun die Erlaubnis haben, Benachrichtigungen zu senden, verwenden wir den Servicearbeiter, um Push -Ereignisse zu abonnieren. Dies kann mit der Funktion von pushManager.Subscribe () des Service Workers erfolgen. Sie können dies entweder im Servicearbeiter selbst oder nach der Registrierung des Servicemitarbeiters in App.svelte tun. Ich werde mit letzterem gehen. Wenn Sie also dasselbe tun möchten, ersetzen Sie einfach den Navigator.Serviceworker
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Erstellen eines Push -Nachrichtenservers
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
Um Push -Benachrichtigungen zu senden, müssen Sie ein öffentliches und privates Vapid -Schlüsselpaar generieren. Öffnen Sie dazu den Knoten -Repl mit dem Befehl node und führen Sie die folgenden Befehle aus:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
Jetzt können wir mit der Arbeit an der Cloud -Funktion beginnen. Erstellen Sie Datei -API/vapidkeys.js. Diese Datei ist dafür verantwortlich, die öffentliche Vapid -Schlüssel an den Kunden zu senden. Sie sollten niemals den privaten Vapid -Schlüssel teilen. In api/vapidkeys.js müssen wir zunächst das Web-Push initialisieren:
<span>npm init vite </span>
In diesem Fall können Sie jetzt die Onmount -Funktion in app.svelte aktualisieren, um zuerst die Cloud -Funktion zu holen, um den öffentlichen Schlüssel zu erhalten, und dann den öffentlichen Schlüssel in der Funktion abonnieren:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Beachten Sie, wie wir nur die Vapid -Tasten
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
wir nicht abonniert haben, um Benachrichtigungen zu überschreiten. Wenn Sie die Konsole öffnen, sollten Sie das an der Konsole angemeldete Abonnement sehen.
Der Endpunkt, der bereitgestellt wird, ist für uns sehr wichtig. Dieser Endpunkt ermöglicht es uns, diesen Benutzer mithilfe von Web-Push zu benachrichtigen. Erstellen wir eine Cloud -Funktion, um diesen Endpunkt in der Datenbank zu speichern. Erstellen Sie Datei -API/storeendpoint.js:
Nehmen wir uns das Abonnement und den Benutzernamen aus dem Körper:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
und fügen wir sie der Datenbank hinzu:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
Und hier ist, wie die endgültige Cloud -Funktion aussehen sollte:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>
Diese Funktion sollte jedes Mal aufgerufen werden, wenn wir Push -Benachrichtigungen abonnieren. Verwenden wir einen Sufle Reactive -Block, um diese Wolkenfunktion jedes Mal aufzurufen, wenn die Subvariable einen Wert
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
Die isloggedin -Variable hat wahr. Fügen Sie diesen Code kurz vor dem Ende des <script> -Tags in app.svelte: <em> hinzu </script>
Aktualisieren Sie die Seite und Sie sollten sehen, dass der Push -Endpunkt und die Schlüssel des aktuellen Browsers in der MongoDB -Datenbank im Abonnementobjekt gespeichert sind.<span>{ </span> <span>"type": "commonjs" </span><span>} </span>
Alles, was Sie tun müssen, ist das Push -Event im Service Worker zu bewältigen und eine Cloud -Funktion zu erstellen, um GitHub auf neue Probleme und PRs zu überprüfen.
Lassen Sie uns zuerst den letzteren tun. Erstellen Sie eine neue Cloud -Funktion API/fetchgh.js. Diese Funktion ist für das Überprüfen von Github und das Senden von Push -Benachrichtigungen verantwortlich:
Lassen Sie uns alle Benutzer aus der Datenbank holen, damit wir wissen, welche Repos abrufen sollen:
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
Erstellen Sie als nächstes zwei Variablen, um die derzeit abgerufenen Repositories und die Repositorys mit neuen Problemen oder PRs zu speichern:
<span>const mongoPromise = require("../src/lib/mongo"); </span><span>// All cloud functions must export a function that takes a req and res object. </span><span>// These objects are similar to their express counterparts. </span>module<span>.exports = async (req<span>, res</span>) => { </span> <span>// TODO </span><span>}; </span>
<span>npm init vite </span>
Suchen wir für jeden Benutzer seine nachverfolgten Repositorys auf neue Probleme. Um sicherzustellen, dass ein Repository nur einmal überprüft wird, fügen wir das Repository bereits abgerufen und werden Repositories mit neuen Problemen zu Reposwithissues hinzufügen. Dazu müssen wir jeden Benutzer im Benutzer -Array überschreiten und eine Liste von Repositorys zum Abrufen erhalten. Dies erfolgt durch die Überprüfung ihrer TrackedRepos für alle Duplikate. Sobald dies erledigt ist, werden wir die Fetchrepo -Funktion für jedes Repository aufrufen. Fetchrepo gibt einen Booleschen zurück - wahr, wenn es neue Probleme gibt, sonst falsch:
npx svelte-add tailwindcss <span># Install packages </span><span>yarn install # or npm install </span>
Da Fetchrepo asynchron sein wird, habe ich jedes Mal MAP zur Rückgabe von Versprechen verwendet und sie alle mit Versprechen erwartet. Dies funktioniert, weil die für die Schleife asynchron ist. Wenn Versprechungen nicht erwartet werden, können Variablen undefiniert sein. Warten Sie also unbedingt Versprechen!
jetzt für die Fetchrepo -Funktion. Diese Funktion wird das letzte Mal erhalten, dass wir die GitHub -API aus der Datenbank überprüft haben. Dies soll nur die neuesten Ausgaben von GitHub erhalten. Anschließend holt es die Github -API für neue Probleme und gibt einen booleschen Wert zurück, wenn es welche gibt:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let username = ""; </span></span></span><span><span> <span>async function submit() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>="{submit}"</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>Enter a username<span><span></h1</span>></span> </span> <span><span><span><p</span> class<span>="text-center text-xl m-4"</span>></span>Enter a username to use this tracker<span><span></p</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Username"</span> </span></span><span> <span>aria-label<span>="Username"</span> </span></span><span> <span><span>bind:value</span><span>="{username}"</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-4 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span> </span> Submit <span><span><span></button</span>></span> </span><span><span><span></form</span>></span> </span>
Sobald dies erledigt ist, müssen wir Push -Benachrichtigungen an einen Benutzer senden, der ein Repository mit neuen Problemen verfolgt hat. Dies kann mit Web-Push erfolgen. Fügen Sie diese Codezeilen zum Ende der exportierten Funktion hinzu:
<span><span><span><script</span>></span><span> </span></span><span><span> <span>import <span>UsernamePrompt</span> from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><UsernamePrompt</span> /></span> </span>
Erstens müssen wir überprüfen, ob einer der nachverfolgten Repos des Benutzers neue Probleme hat. Dies kann mit der Methode Array.EME erfolgen. Array.some () bestimmt, ob die angegebene Rückruffunktion für jedes Element eines Arrays true zurückgibt
<span><span><span><script</span>></span><span> </span></span><span><span> <span>let repo = ""; </span></span></span><span><span> <span>function track() { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span> </span></span><span><span> <span>function untrack(repo) { </span></span></span><span><span> <span>// TODO </span></span></span><span><span> <span>} </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><span><span><form</span> </span></span><span> <span><span>on:submit|preventDefault</span><span>={track}</span> </span></span><span> <span>class<span>="mx-auto min-w-[350px] max-w-[1100px] w-[50%] border border-gray-500 rounded my-4 px-6 py-4"</span> </span></span><span><span>></span> </span> <span><span><span><h1</span> class<span>="text-center text-3xl m-4"</span>></span>GitHub tracker<span><span></h1</span>></span> </span> <span><span><span><input</span> </span></span><span> <span>type<span>="text"</span> </span></span><span> <span>class<span>="rounded px-4 py-2 border border-gray-300 w-full outline-none"</span> </span></span><span> <span>placeholder<span>="Enter the repository's URL"</span> </span></span><span> <span>aria-label<span>="Repository URL"</span> </span></span><span> <span><span>bind:value</span><span>={repo}</span> </span></span><span> <span>/></span> </span> <span><span><span><button</span> </span></span><span> <span>class<span>="mt-2 border border-transparent bg-blue-500 text-white rounded px-4 py-2 w-full"</span> </span></span><span> <span>></span>Track repository<span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span><h2</span> class<span>="mt-4 text-2xl"</span>></span>Tracked repositories<span><span></h2</span>></span> </span> <span><span><span><ul</span> class<span>="m-2 list-decimal"</span>></span> </span> <span><!-- We'll use a loop to automatically add repositories here later on. --> </span> <span><span><span><li</span> class<span>="py-1 flex items-center justify-between"</span>></span> </span> <span><span><span><a</span> class<span>="text-gray-500 hover:underline"</span> href<span>="https://github.com/test/test"</span> </span></span><span> <span>></span>https://github.com/test/test<span><span></a</span> </span></span><span> <span>></span> </span> <button on:click={() => untrack("")} >Untrack<span><span><span></button</span> </span></span><span> <span>></span> </span> <span><span><span></li</span>></span> </span> <span><span><span></ul</span>></span> </span><span><span><span></form</span>></span> </span>
<span><span><span><script</span>></span><span> </span></span><span><span> <span>// import UsernamePrompt from "./lib/UsernamePrompt.svelte"; </span></span></span><span><span> <span>import <span>Tracker</span> from "./lib/Tracker.svelte"; </span></span></span><span><span></span><span><span></script</span>></span> </span> <span><!-- <UsernamePrompt /> --> </span><span><span><span><Tracker</span> /></span> </span>
<span>const { MongoClient } = require("mongodb"); </span> <span>const mongo = new MongoClient(process.env.MONGODB_URL); </span> <span>// Export the connection promise </span><span>export default mongo.connect(); </span>
<span>{ </span> <span>"type": "commonjs" </span><span>} </span>
<span># Don't forget to CD! </span><span>cd api </span><span>npm i mongodb # or use yarn </span>
Wenn Sie die Benachrichtigung nicht erhalten oder einen 410 -Fehler vom Web -Push erhalten, lassen Sie die Benachrichtigungen für immer in der Eingabeaufforderung zu, wenn Sie gefragt werden.
Der Tracker ist nicht wirklich ein Tracker, wenn wir die Cloud -Funktion manuell aufrufen müssen, oder? Verwenden wir EasyCron, um die Cloud -Funktion automatisch jede Stunde aufzurufen.
Gehen Sie zu Ihrem EasyCron -Dashboard und erstellen Sie einen neuen Cron -Job. Geben Sie für die URL https: // your_vercel_domain/api/fetchgh ein und wählen Sie ein Intervall. Ich werde mit jeder Stunde gehen, aber ich kann es gerne anpassen, wie Sie möchten.
und damit sollten Sie jedes Mal Benachrichtigungen erhalten, wenn es in einem Ihrer verfolgten Repositorys ein neues Problem/PR gibt. Schauen Sie sich den Quellcode oder die Live -Version an, wenn Sie irgendwo festgefahren sind.
Das obige ist der detaillierte Inhalt vonErstellen Sie einen Github -Tracker mit Push -Benachrichtigungen in Sufle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!