הפעלת פונקציות Cloud Run באמצעות Cloud Tasks

במדריך הזה נסביר איך להשתמש ב-Cloud Tasks באפליקציית App Engine כדי להפעיל פונקציה ב-Cloud Run ולשלוח הודעת אימייל מתוזמנת.

מטרות

  • להבין את הקוד בכל אחד מהרכיבים.
  • יוצרים חשבון SendGrid.
  • מורידים את קוד המקור.
  • פורסים פונקציית Cloud Run כדי לקבל בקשות Cloud Tasks ולשלוח אימייל באמצעות SendGrid API.
  • יוצרים תור של Cloud Tasks.
  • יוצרים חשבון שירות כדי לאמת את הבקשות של Cloud Tasks.
  • פורסים את קוד הלקוח שמאפשר למשתמש לשלוח אימייל.

עלויות

ל-Cloud Tasks, לפונקציות Cloud Run ול-App Engine יש תוכנית בחינם, כך שאם תפעילו את ההדרכה במסגרת התוכנית בחינם של המוצרים האלה, לא תהיה לכם עלות נוספת. מידע נוסף על תמחור

לפני שמתחילים

  1. בוחרים או יוצרים Google Cloud פרויקט.

    כניסה לדף App Engine

  2. מאתחלים אפליקציית App Engine בפרויקט:

    1. בדף Welcome to App Engine, לוחצים על Create Application.

    2. בוחרים אזור בשביל הבקשה. המיקום הזה ישמש כפרמטר LOCATION_ID בבקשות שלכם ל-Cloud Tasks, לכן חשוב לשים לב אליו. שימו לב ששני מיקומים, שנקראים europe-west ו-us-central בפקודות של App Engine, נקראים europe-west1 ו-us-central1 בפקודות של Cloud Tasks.

    3. בוחרים באפשרות Node.js בשדה Language (שפה) ובאפשרות Standard בשדה Environment (סביבה).

    4. אם מופיע חלון קופץ עם האפשרות הפעלת החיוב, בוחרים את החשבון לחיוב. אם אין לכם חשבון לחיוב, לוחצים על יצירת חשבון לחיוב ופועלים לפי ההוראות באשף.

    5. בדף Get started (תחילת העבודה), לוחצים על Next (הבא). תטפל בזה אחר כך.

  3. מפעילים את ממשקי ה-API של פונקציות Cloud Run ו-Cloud Tasks.

    הפעלת ממשקי ה-API

  4. מתקינים ומפעילים את ה-CLI של gcloud.

הסבר על הקוד

בקטע הזה נסביר איך הקוד של האפליקציה פועל.

יצירת המשימה

דף האינדקס מוצג באמצעות רכיבי handler ב-app.yaml. המשתנים שנדרשים ליצירת המשימה מועברים כמשתני סביבה.

runtime: nodejs16

env_variables:
  QUEUE_NAME: "my-queue"
  QUEUE_LOCATION: "us-central1"
  FUNCTION_URL: "https://<region>-<project_id>.cloudfunctions.net/sendEmail"
  SERVICE_ACCOUNT_EMAIL: "<member>@<project_id>.iam.gserviceaccount.com"

# Handlers for serving the index page.
handlers:
  - url: /static
    static_dir: static
  - url: /
    static_files: index.html
    upload: index.html

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

app.post('/send-email', (req, res) => {
  // Set the task payload to the form submission.
  const {to_name, from_name, to_email, date} = req.body;
  const payload = {to_name, from_name, to_email};

  createHttpTaskWithToken(
    process.env.GOOGLE_CLOUD_PROJECT,
    QUEUE_NAME,
    QUEUE_LOCATION,
    FUNCTION_URL,
    SERVICE_ACCOUNT_EMAIL,
    payload,
    date
  );

  res.status(202).send('📫 Your postcard is in the mail! 💌');
});

הקוד הזה יוצר את המשימה ושולח אותה לתור של Cloud Tasks. הקוד יוצר את המשימה על ידי:

  • ההגדרה של סוג היעד היא HTTP Request.

  • ציון HTTP method לשימוש וURL היעד.

  • הגדרת הכותרת Content-Type לערך application/json כדי שאפליקציות במורד הזרם יוכלו לנתח את מטען הייעודי המובנה.

  • הוספת כתובת האימייל בחשבון שירות כדי ש-Cloud Tasks יוכל לספק פרטי כניסה ליעד הבקשה, שנדרש לאימות. חשבון השירות נוצר בנפרד.

  • בודקים שהתאריך שהמשתמש הזין לא חורג מהמקסימום של 30 ימים ומוסיפים אותו לבקשה כשדה scheduleTime.

const MAX_SCHEDULE_LIMIT = 30 * 60 * 60 * 24; // Represents 30 days in seconds.

const createHttpTaskWithToken = async function (
  project = 'my-project-id', // Your GCP Project id
  queue = 'my-queue', // Name of your Queue
  location = 'us-central1', // The GCP region of your queue
  url = 'https://example.com/taskhandler', // The full url path that the request will be sent to
  email = '<member>@<project-id>.iam.gserviceaccount.com', // Cloud IAM service account
  payload = 'Hello, World!', // The task HTTP request body
  date = new Date() // Intended date to schedule task
) {
  // Imports the Google Cloud Tasks library.
  const {v2beta3} = require('@google-cloud/tasks');

  // Instantiates a client.
  const client = new v2beta3.CloudTasksClient();

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  // Convert message to buffer.
  const convertedPayload = JSON.stringify(payload);
  const body = Buffer.from(convertedPayload).toString('base64');

  const task = {
    httpRequest: {
      httpMethod: