אירוח יעדים של webhooks

במדריך הזה מוסבר איך לארח יעד של webhook בשירות Cloud Run.

‫Cloud Run מספק פתרונות טובים לאירוח של יעדי ה-webhook. ‫Cloud Run מספק גמישות רבה יותר ויכול להתמודד עם נפחים גדולים יותר של נתונים במקביל.

אירוח יעדי webhook בשירות Cloud Run מתאים במיוחד לתרחישים הבאים:

  • אתם רוצים פסק זמן ארוך יותר לבקשות (עד 60 דקות)
  • אתם צופים נפח גדול של בקשות וצריכים תמיכה בבקשות מקבילות (עד 1,000 בקשות מקבילות לכל מופע)

יצירת יעד של webhook ב-Cloud Run

באמצעות Cloud Run, אתם יכולים להגדיר יעד של webhook בכל שפה שתבחרו. צריך רק ליצור נקודת קצה (endpoint) של HTTP שיכולה לקבל את הנתונים. בדרך כלל עושים את זה עם POST, לדוגמה:

from flask import Flask, request
app = Flask(__name__)

@app.route('/', methods=['POST'])
def index():
    data = request.get_json()
    return ('', 200)

בדוגמה הזו, דף האינדקס של כתובת ה-URL מוגדר לקבל רק בקשות POST, והמערכת מצפה שהנתונים יועברו דרך מטען ייעודי (payload) של JSON.

שילוב עם ספק ה-webhook

ברוב השירותים שמספקים קריאות חוזרות (callback) של HTTP, נדרש אימות של הבעלות על כתובת ה-URL. בדרך כלל עושים את זה על ידי שליחת סוג מסוים של טוקן, הודעה או סוד, ומצפים לתשובה תקפה. תצטרכו לקבל את הדרישות האלה מספק השירות. אם משתמשים ביעד ה-webhook שבדוגמה הקודמת, זה יכול להיראות כך:

@app.route('/', methods=['POST'])
def index():
    data = request.get_json()
    return data['challenge']

אחרי שהספק יאמת את הבעלות שלכם, תצטרכו להוסיף הרשאה גם בצד שלכם.

אישור בקשות

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

כדי לאמת את הבקשה, אפשר להגדיר סודות או לשמור את העותק של הסוד כמשתנה סביבה או באמצעות מערכת לניהול מפתחות.

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

import os
from flask import request

@app.route('/', methods=['POST'])
def index():
    request_secret = request.headers.get('Secret')
    if request_secret != os.environ.get('SECRET'):
        return ('Unauthorized', 401)
    return ('', 200)

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

מענה לבקשות

ברוב השירותים, צריך להגיב לבקשה תוך פרק זמן מוגדר, כפי שמצוין בשירות. חלק מה-webhook כוללים שיטות מובנות לניסיון חוזר אם יש תגובת שגיאה, כמו קוד סטטוס של HTTP של 4xx או 5xx. לכן, צריך להחזיר קוד סטטוס של הצלחה (2xx) כדי שהשירות יידע שהאירוע עובד כמו שצריך.

@app.route('/', methods=['POST'])
def index():
    data = request.get_json()
    return ('', 200)

חסימות זמניות

גם ל-Cloud Run וגם לספק ה-webhook יש פסק זמן. התקופה הקצרה מבין השתיים תחול על הבקשה שלכם. אם עיבוד הנתונים חורג מהזמן שהוקצה על ידי Cloud Run או ספק ה-webhook, תצטרכו להשתמש במוצר שמאפשר לכם להשלים את העיבוד באופן אסינכרוני, כמו Pub/Sub או Cloud Tasks. המוצרים האלה מאפשרים להעביר את הנתונים במהירות, להחזיר מיד תגובת הצלחה לספק ה-webhook ולהמשיך את העיבוד בלי לדאוג לגבי פסק זמן. האפשרויות האלה טובות גם לטיפול בכשלים ובניסיונות חוזרים.

תבניות נפוצות של תגובות לפעולות מאתרים אחרים (webhooks)

סוג דוגמאות
העברת נתונים שליחת הודעה באמצעות העברת הודעות בענן ב-Firebase בכל פעם שמתבצעת קריאה ל-webhook.
אחסון נתונים אחסון הנתונים ב-BigQuery לצורך ניתוח מאוחר יותר.
הפעלת פעולות ביצוע פעולות ב-Dialogflow, פרסום תשובות בטוויטר או שליחה לסביבת הבדיקה בכל פעם שמתבצעת התחייבות לקוד חדש ב-GitHub.

המאמרים הבאים