12 ימים של DigitalOcean (יום 4) – פריסת התראות יום הולדת עם פונקציות של DigitalOcean

ברוכים הבאים ליום 4 של 12 ימי DigitalOcean! אתמול, הוספנו התראות SMS של Twilio לשירות תזכורת יום ההולדת שלנו, מה שהופך אותו ליכול לשלוח הודעות טקסט ליום ההולדת של היום. 🎂

היום, נעביר את הדברים לשלב הבא על ידי פריסת הסקריפט שלנו לפונקציות DigitalOcean. זה מאפשר לשירות שלנו לפעול בענן מבלי צורך בשרת ייעודי, מה שהופך את האפליקציה שלנו לקלה, ניתנת להרחבה ומוכנה לאוטומציה.

עם הגדרה זו, תקבלו תזכורות ליום ההולדת גם כאשר המחשב שלכם כבוי או לא מחובר לאינטרנט—אין צורך להריץ את הסקריפט ידנית על המחשב שלכם יותר. 🎉

למה פונקציות DigitalOcean?

לפעמים, כל מה שאתה צריך זה סקריפט פשוט שמריץ מדי פעם. ניהול תשתיות עבור דבר כזה יכול להיות מיותר. כאן נכנסות לתמונה הפונקציות. זו פלטפורמה ללא שרתים, כלומר אתה יכול לפרוס קוד שמופעל רק כאשר יש צורך, ואתה משלם רק עבור מה שאתה משתמש. מושלם עבור המקרה השימוש שלנו—בדיקת ימי הולדת ושליחת תזכורות מדי יום.

🚀 מה תלמד

בסוף היום, תדע איך:

  1. להגדיר את doctl כלי ה-CLI של DigitalOcean.
  2. ליצור ולחבר לnamespace ללא שרתים (הדרך של DigitalOcean לשמור על הפונקציות מאורגנות).
  3. לארוז ולפרוס את שירות תזכורת יום ההולדת שלך לפונקציות DigitalOcean.
  4. לבדוק את הפונקציה שהופעלה בענן.

🛠 מה תצטרך

לפני שתתחיל, ודא שיש לך:

🧑‍🍳 מתכון ליום 4: פריסה לפונקציות של DigitalOcean

שלב 1: התקנת CLI של doctl

אם כבר הגדרת את doctl במכונה שלך, תוכל לדלג על שלב זה. עבור אלה שצריכים להגדיר אותו, עקוב אחרי ההנחיות הללו:

לפני שנתחיל, בואו נדבר במהירות על doctl. זהו הכלי הרשמי של DigitalOcean לממשק שורת הפקודה המאפשר לך לנהל את המשאבים בענן שלך ישירות מהטרמינל שלך. נשתמש בו כדי ליצור מרחב שם (תיקייה לפונקציות השרת שלנו), לפרוס את הסקריפט של Python שלנו, ולבדוק את הפונקציה.

ההגדרה שלו היא פשוטה:

  1. התקן doctl: עקוב אחרי מדריך ההתקנה עבור מערכת ההפעלה שלך.

  2. אמת את doctl: חבר אותו לחשבון DigitalOcean שלך על ידי הרצת:

    doctl auth init
    
  3. אמת את ההתקנה: ודא שהכל עובד על ידי הרצת:

    doctl account get
    

אם ההתקנה הצליחה, פקודה זו תחזיר פרטים על חשבון ה-DigitalOcean שלך, כמו כתובת האימייל ומספר הזיהוי של החשבון.

שלב 2: התקן את התוכנה ללא שרת

פונקציות DigitalOcean דורשות תוכנה תומכת ללא שרת, שתצטרך להתקין. זו התקנה חד פעמית, אז ברגע שתתקין אותה, לא תצטרך לעשות זאת שוב עבור פרויקטים עתידיים.

הרץ את הפקודה הבאה:

doctl serverless install

תוכל לבדוק את מצב ההתקנה עם:

doctl serverless status

אם אתה רואה שגיאה כמו:

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

אל תדאג—זה רק אומר שלא יצרנו או התחברנו לשם תחום עדיין. נטפל בזה בשלב הבא.

שלב 3: צור והתחבר לשם תחום

מרחבים הם כמו תיקיות עבור ארגון פונקציות ללא שרת. בואו ניצור אחד עבור שירות תזכורת היומולדת שלנו:

  1. צור מרחב חדש:

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

  2. התחבר למרחב:

    doctl serverless connect my-birthday-reminder-namespace
    

  3. ודא את החיבור:

    doctl serverless status
    

כעת אתה צריך לראות אישור שאתה מחובר למרחב.

טיפ מקצועי: כדי לראות רשימה של כל השמות המרחביים הזמינים, השתמש בפקודה הבאה:

doctl serverless namespaces list

זה יכול להיות מועיל אם אתה מנהל מספר פרויקטים או רוצה לאמת את שם המרחב שיצרת זה עתה.

שלב 4: אתחול והגדרת מבנה הפרויקט

פונקציות של DigitalOcean מצפות למבנה פרויקט ספציפי לפריסות ללא שרת. אתה יכול להתחיל את המבנה הזה באמצעות doctl serverless init, ליצור אותו ידנית, או אפילו להקליט מאגר התחלה. כדי לשמור על הדברים פשוטים, נקים אותו באמצעות doctl serverless init:

  1. הרץ את הפקודה הבאה כדי להפעיל את הפרויקט:

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

    זה יוצר ספריית פרויקט מקומית בשם my-birthday-reminder-service עם המבנה ברירת המחדל הבא:

    my-birthday-reminder-service/
    ├── packages
    │   └── sample
    │       └── hello
    │           └── hello.py
    └── project.yml
    

  2. נווט לתוך תיקיית הפרויקט:

    cd my-birthday-reminder-service
    
  3. שנה את שמות התיקיות כדי להתאים למקרה השימוש שלנו:

    mv packages/sample packages/reminders
    mv packages/reminders/hello packages/reminders/birthdays
    mv packages/reminders/birthdays/hello.py packages/reminders/birthdays/__main__.py
    
  4. צור את הקבצים הנדרשים:

    • צור קובץ .env ריק בשורש הפרויקט:
    touch .env
    

    זה יחזיק את פרטי הגישה שלך למסד הנתונים ול-Twilio. הקובץ יימצא בשורש תיקיית my-birthday-reminder-service.

    • צור קובץ requirements.txt בתיקיית birthdays:
    touch packages/reminders/birthdays/requirements.txt
    

    קובץ זה יפרט את התלותות של Python הנדרשות לפונקציה שלך. הוא יימצא תחת packages/reminders/birthdays.

    • צור קובץ build.sh בתיקיית birthdays:
    touch packages/reminders/birthdays/build.sh
    chmod +x packages/reminders/birthdays/build.sh
    

    הסקריפט build.sh נחוץ לפריסה של פונקציות עם תלותות חיצוניות. הפקודה chmod מבטיחה שהסקריפט יהיה ניתן להרצה במערכות Mac/Linux.

מבנה מעודכן: לאחר סיום צעדים אלו, מבנה הפרויקט שלך אמור להיראות כך:

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

טיפ מקצועי: אם טעות בשמות תיקיות, תוכל להריץ את הפקודה שוב או לשנות את השם ידנית בסייר הקבצים שלך.

שלב 5: עדכן קבצים

עכשיו שהמבנה מוכן, בואו נמלא אותו בקבצים הנדרשים. פתח את תיקיית my-birthday-reminder-service בעורך הקוד האהוב עליך

1. עדכון project.yml

קובץ project.yml הוא קובץ הגדרות שמגדיר את מבנה הפרויקט שלך ללא שרת, משתני סביבה ופונקציות. החלף את התוכן שלו ב:

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

קובץ זה מגדיר את חבילת התזכורות וממפה את משתני הסביבה לפונקציות של DigitalOcean. כל משתנה מתייחס לאישורים הנדרשים עבור מסד הנתונים שלך ואינטגרציית Twilio.

2. עדכן את קובץ .env שלך

עיין ביום 1: הגדרת מסד נתונים PostgreSQL לתזכורות יומולדת עבור אישורי מסד הנתונים וביום 3: בדיקת יומולדת ושליחת הודעות SMS עבור אישורי Twilio כדי למלא את הערכים הבאים:

# אישורי מסד נתונים (מיום 1)
DB_HOST=<your-database-hostname>
DB_NAME=<your-database-name>
DB_USER=<your-database-username>
DB_PASSWORD=<your-database-password>
DB_PORT=5432  # פורט ברירת המחדל של PostgreSQL

# אישורי Twilio (מיום 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>

הערה: קובץ .env משמש לאחסון מאובטח של אישורים רגישים. ערכים אלו יקראו על ידי קובץ project.yml וימופו לסביבת השרת ללא שרת במהלך הפריסה, מה שיגרום להם להיות נגישים לפונקציה שלך בענן.

3. הוסף תלותים

עדכן את קובץ requirements.txt עם התלותים הבאות:

pg8000  
python-dotenv  
twilio  

pg8000: ספריית לקוח PostgreSQL טהורה ב-Python.

python-dotenv: משמש לטעינת משתני סביבה מקובץ .env.

twilio: ספריית Twilio ב-Python לשליחת הודעות SMS.

4. עדכן build.sh

הוסף את הסקריפט הבא לקובץ build.sh:

#!/bin/bash
set -e

# הדפסת תיק העבודה הנוכחי לצורך ניפוי שגיאות
echo "Current working directory: $(pwd)"

# בדוק אם קובץ requirements.txt קיים
if [[ -f "requirements.txt" ]]; then
  echo "Found requirements.txt in $(pwd)"
else
  echo "Error: requirements.txt not found in $(pwd)"
  exit 1
fi

# צור סביבה וירטואלית
virtualenv --without-pip virtualenv

# התקן תלותים מקובץ requirements.txt
pip install -r requirements.txt --target virtualenv/lib/python3.9/site-packages

סקריפט זה מבטיח שכל התלותות נארזות כראוי עם הפונקציה שלך. הפקודה chmod +x משלב 4 מבטיחה שהיא ניתנת להרצה.

5. עדכן את __main__.py

זהו הסקריפט הראשי עבור שירות תזכורת יום ההולדת שלך. אנחנו essentially משתמשים בסקריפט שבנינו ביום 3 לשליחת התראות יום הולדת. עם זאת, כדי להפוך אותו תואם לפונקציות של DigitalOcean, אנו צריכים לבצע כמה התאמות קטנות.

עדכן את הקובץ __main__.py עם התוכן הבא:

# שירות_תזכורת_יום_הולדת/__main__.py

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

# טוען משתני סביבה
load_dotenv()

def main(params):
    """DigitalOcean Functions entry point."""
    try:
        # מתחבר למסד הנתונים
        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()

        # מקבל את החודש והיום של היום
        today = datetime.now()
        today_month = today.month
        today_day = today.day

        # שאילתה לשליפת אנשי קשר שיום ההולדת שלהם תואם לתאריך של היום
        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()

        # מודיע על כל איש קשר תואם
        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.")

        # סוגר את הקורסור והחיבור
        cursor.close()
        connection.close()

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

הנה מה ששינינו:

  1. הוספנו פונקציה main(params): DigitalOcean Functions מצפה לפונקציית נקודת כניסה בשם main, שלוקחת ארגומנט params. כאן הפונקציה מתחילה לפעול.

  2. העברנו את הלוגיקה של הסקריפט לתוך הפונקציה main:
    הקוד מיום 3 הוכנס לתוך הפונקציה main כדי להתאים לדרישה זו.

  3. כל השאר נשאר כמו שהוא:
    לוגיקת חיבור מסד הנתונים, בדיקות יום ההולדת ולוגיקת ההודעה ב-SMS לא השתנו.

שלב 5: ארוז ופרוס

עם הכל במקום, פרוס את הפרויקט שלך ל-DigitalOcean Functions:

  1. פרוס את הפרויקט:
doctl serverless deploy my-birthday-reminder-service

כדי לאמת שהפונקציה שלך פרוסה בהצלחה למרחב השמות:

  1. בקר בלוח הבקרה של DigitalOcean, ועבור ל-Functions בסרגל הצד השמאלי.
  2. מצא את מרחב השמות שלך (למשל, my-birthday-reminder-namespace).
  3. בדוק שהפונקציה שלך מופיעה תחת מרחב השמות, בדרך כלל מופיעה כ-reminders/birthdays.
  4. לחץ על שם הפונקציה כדי לראות פרטים, כולל יומנים, הגדרות והיסטוריית קריאות.

שלב 6: בדוק את הפונקציה שהופצה

ברגע שהפונקציה שלך הופצה, הגיע הזמן לבדוק אותה. אתה יכול לקרוא לפונקציה באופן ידני כדי לוודא שהיא פועלת כפי שצפוי. ישנן שתי דרכים לעשות זאת:

אפשרות 1: שימוש ב-CLI של DigitalOcean

doctl serverless functions invoke reminders/birthdays

אם הכל מוגדר כראוי, הפונקציה שלך תרוץ בענן, תבדוק מי חוגג יום הולדת היום ותשלח הודעות SMS.

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

אפשרות 2: שימוש בלוח הבקרה של DigitalOcean

  1. עבור אל לוח הבקרה של DigitalOcean.
  2. נווט אל פונקציות ומצא את הפונקציה שלך להזכרת/ימי הולדת.
  3. לחץ על הרץ כדי להריץ אותה ידנית.
  4. צפה בפלט וביומנים ישירות בקונסולה.

שיטה זו מועילה במיוחד אם אתה מעדיף ממשק חזותי או רוצה לבדוק את היומנים בפורמט נקי וקל לקריאה.

טיפים לבדיקה

כשאתה מפעיל את הפונקציה, היא תבדוק עבור ימי הולדת התואמים לתאריך של היום. אם יש התאמה, תקבל הודעת טקסט עם הפרטים. כדי לבדוק את הפונקציה בצורה יעילה:

  • הוסף יום הולדת אחד או יותר למסד הנתונים שלך התואם לתאריך הנוכחי.
  • בדוק את הקונסולה או את יומני ה-CLI כדי לאשר שהפונקציה הוצגה בהצלחה.

🎁 סיכום

הנה מה שהשגנו היום:

✅ התקנו את doctl ויצרנו מרחב שמות עבור הפרויקט שלנו.
✅ שיפרנו את הסקריפט של פייתון לפרסום.
✅ ארזנו והפצנו את שירות תזכורת ימי ההולדת לפונקציות של DigitalOcean.
✅ בדקנו את הפונקציה בענן באמצעות CLI ודשבורד של DigitalOcean.

בהמשך: אמנם זהו צעד גדול קדימה, אך אנחנו עדיין מריצים את הפונקציה ידנית. בפוסט הבא, נאוטומט את התהליך הזה כך ששירות תזכורת ימי ההולדת ירוץ אוטומטית כל יום בשעה ספציפית. דמיין לקום להזכיר טקסט מבלי להזיז אצבע—בואו נגרום לזה לקרות מחר! 🚀

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