Документация Запланировать пилот

SMS-уведомления GitHub через Twilio

В этом руководстве вы научитесь создавать на Workers систему SMS-уведомлений об обновлениях репозитория GitHub. Ваш Worker будет отправлять вам текстовое сообщение через Twilio при появлении новой активности в репозитории.

Вы узнаете, как:

Анимированный gif с получением текстового сообщения на телефон после отправки изменений в репозиторий

Прежде чем начать

Во всех руководствах предполагается, что вы уже выполнили Руководство по началу работы, который поможет вам настроить аккаунт Cloudflare Workers, C3 ↗, а также Wrangler.

Создайте проект Worker

Для начала используйте npm create cloudflare@latest чтобы создать проект Worker в командной строке:

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

Для настройки выберите следующие параметры:

Запишите URL, по которому было развёрнуто ваше приложение. Он понадобится вам при настройке вебхука GitHub.

cd github-twilio-notifications

Внутри вашего нового github-sms-notifications каталог, src/index.js представляет собой точку входа в ваше приложение Cloudflare Workers. Вы будете настраивать этот файл на протяжении большей части руководства.

Для этого руководства вам также понадобятся аккаунт GitHub и репозиторий. Если у вас их ещё нет, создать новую учётную запись GitHub ↗ и создать новый репозиторий ↗ чтобы продолжить это руководство.

Сначала создайте вебхук для своего репозитория, чтобы он отправлял обновления вашему Worker. Затем внутри Worker вы разберёте эти обновления. Наконец, вы отправите POST запрос к Twilio, чтобы отправить вам текстовое сообщение.

Готовый код можно посмотреть по этой репозиторий GitHub ↗.


Настройте GitHub

Для начала настройте вебхук GitHub, который будет отправлять запрос в ваш Worker при обновлении репозитория:

  1. В репозитории GitHub перейдите на страницу Настройки > Webhooks > Добавить webhook.

  2. Укажите в качестве Payload URL значение /webhook путь по URL Worker, который вы записали при первом развёртывании приложения.

  3. В Тип контента раскрывающемся списке выберите application/json.

  4. В Секрет поле, введите секретный ключ по вашему выбору.

  5. В Какие события должны запускать этот webhook?, выберите Выбрать события по отдельности. Выберите события, о которых хотите получать уведомления (например, Pull requests, Отправки, а также Создание ветки или тега).

  6. Выберите Добавить webhook чтобы завершить настройку.

Инструкции по настройке вебхука в панели настроек вебхуков 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 добавляет хеш-подпись для каждую полезную нагрузку с помощью секретного ключа ↗. Используйте вспомогательную функцию с именем checkSignature к запросу, чтобы убедиться в корректности хеша. После этого вы можете получить данные из вебхука, разобрав запрос как 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, чтобы хешировать полученное тело запроса (payload) с помощью известного вам секретного ключа и убедиться, что оно совпадает с хешем запроса. GitHub использует HMAC hexdigest для вычисления хеша в формате 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. Этот токен является секретом, который вы указали ранее при настройке вебхука 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 запрос к конечной точке Twilio API. См. справочник 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);
}

Чтобы это заработало, нужно задать несколько секретов, скрывающих ваш ACCOUNT_SID и AUTH_TOKEN из исходного кода. Секреты можно задать с помощью 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
Видео о получении текстового сообщения после push в репозиторий

Теперь, когда вы вносите обновление (настроенное в GitHub Вебхук настройки) в ваш репозиторий, вскоре после этого вы получите текстовое сообщение. Если вы никогда раньше не использовали Git, обратитесь к Учебник по Git push и pull ↗ для отправки в ваш репозиторий.

См. готовый код на GitHub ↗.

Пройдя это руководство, вы узнали, как создавать вебхуки с помощью Workers, интегрировать Workers с GitHub и Twilio, а также использовать секреты Worker в Wrangler.

Запросите бесплатный пилот

Запланировать пилот