12 Tage von DigitalOcean (Tag 4) – Bereitstellung von Geburtstagsbenachrichtigungen mit DigitalOcean-Funktionen

Willkommen zu Tag 4 von 12 Tagen von DigitalOcean! Gestern haben wir Twilio SMS-Benachrichtigungen zu unserem Geburtstags-Erinnerungsdienst hinzugefügt, sodass er in der Lage ist, Textnachrichten für die Geburtstage von heute zu senden. 🎂

Heute werden wir die Dinge auf die nächste Stufe heben, indem wir unser Skript auf DigitalOcean Functions bereitstellen. Damit kann unser Dienst in der Cloud laufen, ohne dass ein dedizierter Server benötigt wird, wodurch unsere App leichtgewichtig, skalierbar und bereit für Automatisierung wird.

Mit diesem Setup erhalten Sie Geburtstags-Erinnerungen, selbst wenn Ihr Computer ausgeschaltet oder nicht mit dem Internet verbunden ist—keine Notwendigkeit mehr, das Skript manuell auf Ihrem Gerät auszuführen. 🎉

Warum DigitalOcean Functions?

Manchmal benötigt man nur ein einfaches Skript, das gelegentlich ausgeführt wird. Die Verwaltung der Infrastruktur für so etwas kann übertrieben sein. Hier kommt Functions ins Spiel. Es ist eine serverlose Plattform, was bedeutet, dass Sie Code bereitstellen können, der nur bei Bedarf ausgeführt wird, und Sie zahlen nur für das, was Sie nutzen. Perfekt für unseren Anwendungsfall—das Überprüfen von Geburtstagen und das tägliche Versenden von Erinnerungen.

🚀 Was Sie Lernen Werden

Am Ende des Tages werden Sie wissen, wie Sie:

  1. Das doctl CLI-Tool von DigitalOcean einrichten.
  2. Eine serverlose Namespace (DigitalOceans Art, Funktionen organisiert zu halten) erstellen und verbinden.
  3. Ihren Geburtstags-Erinnerungsdienst in DigitalOcean Functions paketieren und bereitstellen.
  4. Ihre bereitgestellte Funktion in der Cloud testen.

🛠 Was Sie Benötigen

Bevor Sie beginnen, stellen Sie sicher, dass Sie:

🧑‍🍳 Rezept für Tag 4: Bereitstellung auf DigitalOcean Functions

Schritt 1: Richten Sie die doctl CLI ein

Wenn du doctl bereits auf deinem Computer eingerichtet hast, kannst du diesen Schritt überspringen. Für diejenigen, die es einrichten müssen, befolge diese Anweisungen:

Bevor wir beginnen, lass uns kurz über doctl sprechen. Es ist das offizielle Befehlszeilenwerkzeug von DigitalOcean, mit dem du deine Cloud-Ressourcen direkt von deinem Terminal aus verwalten kannst. Wir werden es verwenden, um einen Namespace (einen Ordner für unsere serverlosen Funktionen) zu erstellen, unser Python-Skript bereitzustellen und die Funktion zu testen.

Die Einrichtung ist einfach:

  1. Installiere doctl: Befolge die Installationsanleitung für dein Betriebssystem.

  2. Authentifiziere doctl: Verbinde es mit deinem DigitalOcean-Konto, indem du Folgendes ausführst:

    doctl auth init
    
  3. Überprüfe die Installation: Stelle sicher, dass alles funktioniert, indem du Folgendes ausführst:

    doctl account get
    

Wenn erfolgreich, gibt dieser Befehl Details zu Ihrem DigitalOcean-Konto zurück, wie Ihre E-Mail-Adresse und Ihre Kontonummer.

Schritt 2: Installieren Sie die Serverless-Software

DigitalOcean Functions benötigt serverless unterstützende Software, die Sie installieren müssen. Dies ist eine einmalige Einrichtung, sodass Sie es nach der Installation für zukünftige Projekte nicht erneut tun müssen.

Führen Sie den folgenden Befehl aus:

doctl serverless install

Sie können den Installationsstatus mit folgendem Befehl überprüfen:

doctl serverless status

Wenn Sie einen Fehler wie diesen sehen:

Error: serverless support is installed but not connected to a functions namespace

Keine Sorge – das bedeutet nur, dass wir noch keinen Namespace erstellt oder verbunden haben. Das werden wir im nächsten Schritt erledigen.

Schritt 3: Erstellen und Verbinden Sie sich mit einem Namespace

Namespaces sind wie Ordner zum Organisieren von serverlosen Funktionen. Lassen Sie uns einen für unseren Geburtstags-Erinnerungsdienst erstellen:

  1. Erstellen Sie einen neuen Namespace:

    doctl serverless namespaces create --label "my-birthday-reminder-namespace" --region "nyc1"
    

  2. Verbinden Sie sich mit dem Namespace:

    doctl serverless connect my-birthday-reminder-namespace
    

  3. Überprüfen Sie die Verbindung:

    doctl serverless status
    

Sie sollten jetzt eine Bestätigung sehen, dass Sie mit dem Namespace verbunden sind.

Pro Tipp: Um eine Liste aller verfügbaren Namensräume zu sehen, verwenden Sie den folgenden Befehl:

doctl serverless namespaces list

Das kann nützlich sein, wenn Sie mehrere Projekte verwalten oder den Namensraum überprüfen möchten, den Sie gerade erstellt haben.

Schritt 4: Projektstruktur initialisieren und einrichten

DigitalOcean Functions erwartet eine spezifische Projektstruktur für serverlose Bereitstellungen. Sie können diese Struktur mit doctl serverless init starten, sie manuell erstellen oder sogar ein Starter-Repo klonen. Um es einfach zu halten, richten wir es mit doctl serverless init ein:

  1. Führen Sie den folgenden Befehl aus, um das Projekt zu initialisieren:

    doctl serverless init --language python birthday-reminder-service
    

    Dies erstellt ein lokales Projektverzeichnis mit dem Namen my-birthday-reminder-service und der folgenden Standardstruktur:

    my-birthday-reminder-service/
    ├── pakete
    │   └── beispiel
    │       └── hallo
    │           └── hallo.py
    └── projekt.yml
    

  2. Navigiere in das Projektverzeichnis:

    cd mein-geburtstags-erinnerungs-dienst
    
  3. Benenne die Ordner um, um unserem Anwendungsfall zu entsprechen:

    mv pakete/beispiel pakete/erinnerungen
    mv pakete/erinnerungen/hallo pakete/erinnerungen/geburtstage
    mv pakete/erinnerungen/geburtstage/hallo.py pakete/erinnerungen/geburtstage/__main__.py
    
  4. Erstellen Sie die erforderlichen Dateien:

    • Erstellen Sie eine leere .env-Datei im Stammverzeichnis des Projekts:
    touch .env
    

    Diese Datei enthält Ihre Datenbank- und Twilio-Anmeldeinformationen. Die Datei befindet sich im Stammverzeichnis des my-birthday-reminder-service-Ordners.

    • Erstellen Sie eine requirements.txt-Datei im birthdays-Ordner:
    touch packages/reminders/birthdays/requirements.txt
    

    Diese Datei listet die benötigten Python-Abhängigkeiten für Ihre Funktion auf. Sie befindet sich unter packages/reminders/birthdays.

    • Erstellen Sie eine build.sh-Datei im birthdays-Ordner:
    touch packages/reminders/birthdays/build.sh
    chmod +x packages/reminders/birthdays/build.sh
    

    Das build.sh-Skript ist notwendig für die Bereitstellung von Funktionen mit externen Abhängigkeiten. Der chmod-Befehl stellt sicher, dass das Skript auf Mac-/Linux-Systemen ausführbar ist.

Aktualisierte Struktur: Nach Abschluss dieser Schritte sollte Ihre Projektstruktur folgendermaßen aussehen:

my-birthday-reminder-service/
├── project.yml
├── .env
├── packages
│   └── reminders
│       └── birthdays
│           ├── __main__.py
│           ├── requirements.txt
│           ├── build.sh
├── .gitignore

Pro-Tipp: Wenn Sie versehentlich einen Ordner falsch benennen, können Sie den Befehl erneut ausführen oder ihn manuell in Ihrem Datei-Explorer umbenennen.

Schritt 5: Dateien aktualisieren

Jetzt, da die Struktur vorhanden ist, lassen Sie uns diese mit den erforderlichen Dateien füllen. Öffnen Sie das Verzeichnis my-birthday-reminder-service in Ihrem bevorzugten Code-Editor.

1. Aktualisieren Sie project.yml

Die Datei project.yml ist eine Konfigurationsdatei, die die Struktur Ihres serverlosen Projekts, Umgebungsvariablen und Funktionen definiert. Ersetzen Sie den Inhalt durch:

packages:
  - name: reminders
    shared: false
    environment:
      DO_DB_NAME: "${DB_NAME}"
      DO_DB_USER: "${DB_USER}"
      DO_DB_PASSWORD: "${DB_PASSWORD}"
      DO_DB_HOST: "${DB_HOST}"
      DO_DB_PORT: "${DB_PORT}"
      TWILIO_ACCOUNT_SID: "${TWILIO_ACCOUNT_SID}"
      TWILIO_AUTH_TOKEN: "${TWILIO_AUTH_TOKEN}"
      TWILIO_PHONE_FROM: "${TWILIO_PHONE_FROM}"
      TWILIO_PHONE_TO: "${TWILIO_PHONE_TO}"
    functions:
      - name: birthdays
        runtime: python:default

Diese Datei richtet das Erinnerungs-Paket ein und ordnet Umgebungsvariablen den DigitalOcean-Funktionen zu. Jede Variable entspricht den Anmeldeinformationen, die für Ihre Datenbank und die Twilio-Integration benötigt werden.

2. Aktualisieren Sie Ihre .env-Datei

Referenzieren Sie Tag 1: Einrichtung einer PostgreSQL-Datenbank für Geburtstags-Erinnerungen für die Datenbank-Anmeldeinformationen und Tag 3: Überprüfen von Geburtstagen und Senden von SMS-Benachrichtigungen für die Twilio-Anmeldeinformationen, um die folgenden Werte auszufüllen:

# Datenbank-Anmeldeinformationen (von Tag 1)
DB_HOST=<your-database-hostname>
DB_NAME=<your-database-name>
DB_USER=<your-database-username>
DB_PASSWORD=<your-database-password>
DB_PORT=5432  # Standard-PostgreSQL-Port

# Twilio-Anmeldeinformationen (von Tag 3)
TWILIO_ACCOUNT_SID=<your-twilio-account-sid>
TWILIO_AUTH_TOKEN=<your-twilio-auth-token>
TWILIO_PHONE_FROM=<your-twilio-phone-number>
TWILIO_PHONE_TO=<your-personal-phone-number>

Hinweis: Die .env Datei wird verwendet, um sensible Zugangsdaten sicher zu speichern. Diese Werte werden von Ihrer project.yml Datei gelesen und während der Bereitstellung der serverlosen Umgebung zugeordnet, wodurch sie für Ihre Funktion in der Cloud zugänglich sind.

3. Abhängigkeiten hinzufügen

Aktualisieren Sie die requirements.txt Datei mit den folgenden Abhängigkeiten:

pg8000  
python-dotenv  
twilio  

pg8000: Eine reine Python PostgreSQL-Clientbibliothek.

python-dotenv: Wird verwendet, um Umgebungsvariablen aus der .env Datei zu laden.

twilio: Die Twilio Python-Bibliothek zum Senden von SMS-Nachrichten.

4. Aktualisieren Sie build.sh

Fügen Sie das folgende Skript zur build.sh Datei hinzu:

#!/bin/bash
set -e

# Aktuelles Arbeitsverzeichnis für Debugging ausgeben
echo "Current working directory: $(pwd)"

# Überprüfen, ob requirements.txt existiert
if [[ -f "requirements.txt" ]]; then
  echo "Found requirements.txt in $(pwd)"
else
  echo "Error: requirements.txt not found in $(pwd)"
  exit 1
fi

# Virtuelle Umgebung erstellen
virtualenv --without-pip virtualenv

# Abhängigkeiten aus requirements.txt installieren
pip install -r requirements.txt --target virtualenv/lib/python3.9/site-packages

Dieses Skript stellt sicher, dass alle Abhängigkeiten korrekt mit Ihrer Funktion verpackt sind. Der Befehl chmod +x aus Schritt 4 stellt sicher, dass es ausführbar ist.

5. Update __main__.py

Dies ist das Hauptskript für Ihren Geburtstagsbenachrichtigungsdienst. Wir verwenden im Wesentlichen das Skript, das wir am Tag 3 zum Versenden von Geburtstagsbenachrichtigungen erstellt haben. Um es jedoch mit DigitalOcean Functions kompatibel zu machen, müssen wir einige kleine Anpassungen vornehmen.

Aktualisieren Sie die Datei __main__.py mit folgendem Inhalt:

# geburtstags_erinnerungsdienst/__main__.py

from datetime import datetime
import pg8000
from dotenv import load_dotenv
from twilio.rest import Client
import os

# Umgebungsvariablen laden
load_dotenv()

def main(params):
    """DigitalOcean Functions entry point."""
    try:
        # Mit der Datenbank verbinden
        connection = pg8000.connect(
            host=os.getenv("DO_DB_HOST"),
            database=os.getenv("DO_DB_NAME"),
            user=os.getenv("DO_DB_USER"),
            password=os.getenv("DO_DB_PASSWORD"),
            port=int(os.getenv("DO_DB_PORT"))
        )
        cursor = connection.cursor()

        # Monat und Tag von heute abrufen
        today = datetime.now()
        today_month = today.month
        today_day = today.day

        # Abfrage, um Kontakte zu finden, deren Geburtstag mit dem heutigen Datum übereinstimmt
        cursor.execute(
            """
            SELECT first_name, last_name, birthday
            FROM contacts
            WHERE EXTRACT(MONTH FROM birthday) = %s
              AND EXTRACT(DAY FROM birthday) = %s;
            """,
            (today_month, today_day)
        )
        rows = cursor.fetchall()

        # Für jeden passenden Kontakt benachrichtigen
        if rows:
            account_sid = os.getenv("TWILIO_ACCOUNT_SID")
            auth_token = os.getenv("TWILIO_AUTH_TOKEN")
            client = Client(account_sid, auth_token)

            for row in rows:
                first_name, last_name, _ = row
                message = client.messages.create(
                    body=f"🎉 It's {first_name} {last_name or ''}'s birthday today! 🎂",
                    from_=os.getenv("TWILIO_PHONE_FROM"),
                    to=os.getenv("TWILIO_PHONE_TO")
                )
                print(f"Message sent for {first_name} {last_name}. Message SID: {message.sid}")
        else:
            print("No birthdays today.")

        # Den Cursor und die Verbindung schließen
        cursor.close()
        connection.close()

    except Exception as e:
        print(f"An error occurred: {e}")

Hier ist, was wir geändert haben:

  1. Eine main(params) Funktion hinzugefügt: DigitalOcean Functions erwartet eine Einstiegspunktfunktion namens main, die ein params Argument entgegennimmt. Hier beginnt die Ausführung der Funktion.

  2. Die Skriplogik in die main Funktion verschoben:
    Der Code vom Tag 3 wurde in die main Funktion eingekapselt, um dieser Anforderung gerecht zu werden.

  3. Alles andere bleibt gleich:
    Die Logik der Datenbankverbindung, die Überprüfungen der Geburtstage und die Logik der SMS-Benachrichtigungen sind unverändert.

Schritt 5: Verpacken und Bereitstellen

Mit allem an seinem Platz, stellen Sie Ihr Projekt auf DigitalOcean Functions bereit:

  1. Projekt bereitstellen:
doctl serverless deploy my-birthday-reminder-service

Um zu überprüfen, dass Ihre Funktion erfolgreich im Namespace bereitgestellt wurde:

  1. Besuchen Sie das DigitalOcean Control Panel und navigieren Sie zu Functions in der linken Seitenleiste.
  2. Finden Sie Ihren Namespace (z. B. my-birthday-reminder-namespace).
  3. Überprüfen Sie, ob Ihre Funktion unter dem Namespace angezeigt wird, typischerweise aufgeführt als reminders/birthdays.
  4. Klicken Sie auf den Funktionsnamen, um Details anzuzeigen, einschließlich Protokollen, Konfiguration und Aufrufhistorie.

Schritt 6: Testen Sie Ihre bereitgestellte Funktion

Sobald Ihre Funktion bereitgestellt ist, ist es Zeit, sie zu testen. Sie können die Funktion manuell aufrufen, um sicherzustellen, dass sie wie erwartet funktioniert. Es gibt zwei Möglichkeiten, dies zu tun:

Option 1: Verwendung der DigitalOcean CLI

doctl serverless functions invoke reminders/birthdays

Wenn alles korrekt eingerichtet ist, wird Ihre Funktion in der Cloud ausgeführt, überprüft die heute Geburtstagskinder und sendet SMS-Benachrichtigungen.

![https://doimages.nyc3.cdn.digitaloceanspaces.com/006Community/12-Days-of-DO/Postgressql-birthday/birthday_reminder_service_text_message.jpeg]

Option 2: Verwendung des DigitalOcean Dashboards

  1. Gehen Sie zum DigitalOcean Control Panel.
  2. Navigieren Sie zu Funktionen und suchen Sie Ihre Erinnerungs-/Geburtstagsfunktion.
  3. Klicken Sie auf Ausführen, um sie manuell auszuführen.
  4. Sehen Sie sich die Ausgaben und Protokolle direkt in der Konsole an.

Diese Methode ist besonders hilfreich, wenn Sie eine visuelle Schnittstelle bevorzugen oder die Protokolle in einem sauberen, leicht lesbaren Format überprüfen möchten.

Testtipps

Wenn Sie die Funktion aufrufen, wird sie nach Geburtstagen suchen, die dem heutigen Datum entsprechen. Wenn es einen Treffer gibt, erhalten Sie eine SMS mit den Details. Um die Funktion effektiv zu testen:

  • Fügen Sie ein oder mehrere Geburtstage in Ihre Datenbank ein, die dem aktuellen Datum entsprechen.
  • Überprüfen Sie die Konsole oder die CLI-Protokolle, um zu bestätigen, dass die Funktion erfolgreich ausgeführt wurde.

🎁 Zusammenfassung

Hier ist, was wir heute erreicht haben:

doctl eingerichtet und einen Namensraum für unser Projekt erstellt.
✅ Das Python-Skript für die Bereitstellung umgestaltet.
✅ Den Geburtstagserinnerungsdienst bei DigitalOcean Functions verpackt und bereitgestellt.
✅ Die Funktion in der Cloud sowohl über die CLI als auch über das DigitalOcean-Dashboard getestet.

Als Nächstes: Obwohl dies ein großer Schritt nach vorne ist, führen wir die Funktion immer noch manuell aus. Im nächsten Beitrag werden wir diesen Prozess automatisieren, damit der Geburtstagserinnerungsdienst jeden Tag zu einer bestimmten Zeit automatisch ausgeführt wird. Stellen Sie sich vor, Sie wachen mit einer Textbenachrichtigung auf, ohne einen Finger zu rühren – lassen Sie uns das morgen Wirklichkeit werden lassen! 🚀

Source:
https://www.digitalocean.com/community/tutorials/deploying-birthday-notifications-with-digitalocean-functions