מדריך קלאודפלייר בעברית

תיעוד 209

התראות SMS מ-GitHub באמצעות Twilio

במדריך זה תלמדו לבנות מערכת התראות SMS על Workers כדי לקבל עדכונים על מאגר GitHub. ה-Worker ישלח לכם עדכון בהודעת טקסט באמצעות Twilio כשיש פעילות חדשה במאגר.

תלמדו איך:

  • לבנות webhooks באמצעות Workers.
  • לשלב את Workers עם GitHub ועם Twilio.
  • להשתמש ב-secrets של Worker עם Wrangler.

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


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

כל המדריכים מניחים שכבר השלמתם את מדריך תחילת העבודה, שמגדיר לכם חשבון Cloudflare Workers, את C3 ↗︎ ואת Wrangler.

#יצירת פרויקט Worker

התחילו עם npm create cloudflare@latest כדי ליצור פרויקט Worker בשורת הפקודה. אפשר להשתמש גם ב-yarn או ב-pnpm:

npm

npm create cloudflare@latest -- github-twilio-notifications

yarn

yarn create cloudflare github-twilio-notifications

pnpm

pnpm create cloudflare@latest github-twilio-notifications

להגדרה, בחרו באפשרויות הבאות:

  • בשאלה What would you like to start with?, בחרו ב-Hello World example.
  • בשאלה Which template would you like to use?, בחרו ב-Worker only.
  • בשאלה Which language do you want to use?, בחרו ב-JavaScript.
  • בשאלה Do you want to use git for version control?, בחרו ב-Yes.
  • בשאלה Do you want to add an AGENTS.md file to help AI coding tools understand Cloudflare APIs?, בחרו ב-Yes.
  • בשאלה Do you want to deploy your application?, בחרו ב-No (נבצע כמה שינויים לפני הפריסה).

רשמו את כתובת ה-URL שאליה נפרסה האפליקציה. תשתמשו בה כשתגדירו את ה-webhook של GitHub.

cd github-twilio-notifications

בתוך התיקייה החדשה github-sms-notifications, הקובץ src/index.js הוא נקודת הכניסה לאפליקציית Cloudflare Workers. תגדירו את הקובץ הזה ברוב המדריך.

תצטרכו גם חשבון GitHub ומאגר למדריך זה. אם אין לכם אחד מהם, צרו חשבון GitHub חדש ↗︎ וצרו מאגר חדש ↗︎ כדי להמשיך במדריך.

קודם יוצרים webhook למאגר, כדי שיפרסם עדכונים אל ה-Worker. בתוך ה-Worker מפענחים את העדכונים. בסוף שולחים בקשת POST אל Twilio כדי לשלוח אליכם הודעת טקסט.

אפשר להיעזר בקוד המוגמר במאגר GitHub הזה ↗︎.


#הגדרת GitHub

כדי להתחיל, הגדירו webhook של GitHub שיפרסם אל ה-Worker כשיש עדכון במאגר:

  1. עברו אל Settings > Webhooks > Add webhook במאגר GitHub.
  2. הגדירו את ה-Payload URL לנתיב /webhook בכתובת ה-URL של ה-Worker שרשמתם כשהאפליקציה נפרסה בפעם הראשונה.
  3. בתפריט הנפתח Content type, בחרו ב-application/json.
  4. בשדה Secret, הזינו מפתח סודי לבחירתכם.
  5. בשאלה Which events would you like to trigger this webhook?, בחרו ב-Let me select individual events. בחרו את האירועים שעבורם אתם רוצים לקבל התראות (למשל Pull requests, Pushes ו-Branch or tag creation).
  6. בחרו ב-Add webhook כדי לסיים את ההגדרה.

מעקב אחרי ההוראות להגדרת ה-webhook בלוח ההגדרות של webhooks ב-GitHub


#פענוח התגובה

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

בהתחלה, קובץ index.js שנוצר אמור להיראות כך:

export default {
	async fetch(request, env, ctx) {
		return new Response("Hello World!");
	},
};

השתמשו במאפיין request.method של Request כדי לבדוק אם הבקשה שמגיעה לאפליקציה היא בקשת POST, ושלחו תגובת שגיאה אם הבקשה אינה בקשת POST.

export default {
	async fetch(request, env, ctx) {
		if (request.method !== "POST") {
			return new Response("Please send a POST request!");
		}
	},
};

אחר כך, אמתו שהבקשה נשלחת עם המפתח הסודי הנכון. GitHub מצרף חתימת hash לכל מטען באמצעות המפתח הסודי ↗︎. השתמשו בפונקציית עזר בשם checkSignature על הבקשה כדי לוודא שה-hash נכון. אחר כך אפשר לגשת לנתונים מה-webhook על ידי פענוח הבקשה כ-JSON.

async fetch(request, env, ctx) {
  if(request.method !== 'POST') {
    return new Response('Please send a POST request!');
  }
  try {
    const rawBody = await request.text();

    if (!checkSignature(rawBody, request.headers, env.GITHUB_SECRET_TOKEN)) {
      return new Response("Wrong password, try again", {status: 403});
    }
  } catch (e) {
    return new Response(`Error:  ${e}`);
  }
},

הפונקציה checkSignature תשתמש בספריית ה-crypto של Node.js כדי לחשב hash למטען שהתקבל עם המפתח הסודי הידוע לכם, ולוודא שהוא תואם ל-hash של הבקשה. GitHub משתמש ב-HMAC hexdigest כדי לחשב את ה-hash בפורמט SHA-256. מקמו את הפונקציה הזו בראש הקובץ index.js, לפני ה-export.

import { createHmac, timingSafeEqual } from "node:crypto";
import { Buffer } from "node:buffer";

function checkSignature(text, headers, githubSecretToken) {
	const hmac = createHmac("sha256", githubSecretToken);
	hmac.update(text);
	const expectedSignature = hmac.digest("hex");
	const actualSignature = headers.get("x-hub-signature-256");

	const trusted = Buffer.from(`sha256=${expectedSignature}`, "ascii");
	const untrusted = Buffer.from(actualSignature, "ascii");

	return (
		trusted.byteLength == untrusted.byteLength &&
		timingSafeEqual(trusted, untrusted)
	);
}

כדי שזה יעבוד, צריך להשתמש ב-wrangler secret put כדי להגדיר את GITHUB_SECRET_TOKEN. ה-token הזה הוא הסוד שבחרתם קודם כשהגדרתם את ה-webhook של GitHub:

npx wrangler secret put GITHUB_SECRET_TOKEN

הוסיפו את הדגל nodejs_compat לקובץ Wrangler:

{
	"compatibility_flags": [
		"nodejs_compat"
	]
}
compatibility_flags = [ "nodejs_compat" ]

#שליחת הודעת טקסט עם Twilio

תשלחו לעצמכם הודעת טקסט על פעילות המאגר באמצעות Twilio. צריך חשבון Twilio ומספר טלפון שיכול לקבל הודעות טקסט. עיינו במדריך של Twilio כדי להתארגן ↗︎. (אם אתם חדשים ב-Twilio, יש להם משחק אינטראקטיבי ↗︎ שבו אפשר ללמוד איך להשתמש בפלטפורמה ולקבל כמה קרדיטים בחינם למתחילים בשירות.)

אחר כך אפשר ליצור פונקציית עזר לשליחת הודעות טקסט על ידי שליחת בקשת POST אל נקודת הקצה של ה-API של Twilio. עיינו בתיעוד העזר של Twilio ↗︎ כדי ללמוד עוד על נקודת הקצה הזו.

צרו פונקציה חדשה בשם sendText() שתטפל בביצוע הבקשה אל Twilio:

async function sendText(accountSid, authToken, message) {
	const endpoint = `https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Messages.json`;

	const encoded = new URLSearchParams({
		To: "%YOUR_PHONE_NUMBER%",
		From: "%YOUR_TWILIO_NUMBER%",
		Body: message,
	});

	const token = btoa(`${accountSid}:${authToken}`);

	const request = {
		body: encoded,
		method: "POST",
		headers: {
			Authorization: `Basic ${token}`,
			"Content-Type": "application/x-www-form-urlencoded",
		},
	};

	const response = await fetch(endpoint, request);
	const result = await response.json();

	return Response.json(result);
}

כדי שזה יעבוד, צריך להגדיר כמה secrets כדי להסתיר את ACCOUNT_SID ואת AUTH_TOKEN מקוד המקור. אפשר להגדיר secrets עם wrangler secret put בשורת הפקודה.

npx wrangler secret put TWILIO_ACCOUNT_SID
npx wrangler secret put TWILIO_AUTH_TOKEN

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

async fetch(request, env, ctx) {
  if(request.method !== 'POST') {
    return new Response('Please send a POST request!');
  }
  try {
    const rawBody = await request.text();
    if (!checkSignature(rawBody, request.headers, env.GITHUB_SECRET_TOKEN)) {
      return new Response('Wrong password, try again', {status: 403});
    }

    const action = request.headers.get('X-GitHub-Event');
    const json = JSON.parse(rawBody);
    const repoName = json.repository.full_name;
    const senderName = json.sender.login;

    return await sendText(
      env.TWILIO_ACCOUNT_SID,
      env.TWILIO_AUTH_TOKEN,
      `${senderName} completed ${action} onto your repo ${repoName}`
    );
  } catch (e) {
    return new Response(`Error:  ${e}`);
  }
};

הריצו את הפקודה npx wrangler deploy כדי לפרוס מחדש את פרויקט ה-Worker:

npx wrangler deploy

סרטון של קבלת הודעת טקסט אחרי דחיפה למאגר

מעכשיו, כשתבצעו עדכון למאגר (עדכון שהגדרתם בהגדרות Webhook של GitHub), תקבלו הודעת טקסט זמן קצר אחר כך. אם מעולם לא השתמשתם ב-Git, עיינו במדריך GIT Push and Pull ↗︎ לדחיפה אל המאגר.

היעזרו בקוד המוגמר ב-GitHub ↗︎.

עם השלמת המדריך הזה למדתם איך לבנות webhooks באמצעות Workers, לשלב את Workers עם GitHub ועם Twilio, ולהשתמש ב-secrets של Worker עם Wrangler.

#משאבים קשורים