Наконец-то в жизни произошло что-то достойное статьи на Хабре хотя бы отчасти.

Zapier появился на рынке интеграции всего со всем давным давно — 10 лет назад. С тех пор они выросли с 25 до 4000 интеграций.

С его помощью вы можете связать что угодно с чем угодно и потратить на это 10 минут.

Так поступил и я когда меня попросили создавать задачи в ClickUp когда кто‑то отправляет форму в Webflow.

Поначалу Zapier не умел привязываться к Webflow, а может я просто пошёл неправильным путём. Но так или иначе я наткнулся на сервис parser.zapier.com. Гениальная вещь, я вам скажу. В некоторых случаях незаменимая.

У Zapier только одна беда — цена. Бесплатный план подходит только для очень простых случаев в основном из за возможности сделать только 2 шага. За 20 баксов в месяц вы получаете многоходовые «зап»ы и 750 шагов в месяц. Вроде бы 750 это много, но каждый «зап» (задача) требует как минимум 2 шага. А если вам нужно отформатировать какое нибудь поле, например телефон, то это отдельный шаг. Причём для каждого поля в отдельности. Дорого, в общем.

Интеграцию я, конечно настроил, но потом потребовалось разбирать емейл из другого источника. И чтобы обработать этот емейл Zapier потребовалось бы уже невероятное количество шагов.

К счастью в это время я много читал о граничных вычислениях и в определённый момент наткнулся на информацию об EmailWorkers от Cloudflare.

Webworkers они предоставляли уже давно, у них есть потрясающие пример применения. Например сервер Mastodon развёрнутый прямо в инфраструктуре Cloudflare — то есть прямо вообще без своего сервера.

EmailWorkers появились в 2022 и все еще отмечены как бета. Проблемы, конечно, есть но мы же программисты!

Идея всего это проста — вы пишите код на Javascript или на чём‑то еще и компилируете в WASM, а потом загружаете свое творение на Cloudflare. Вызвать воркер можно по урлу (сабдомен на worker.dev) или.... — при получении емейла.

Теперь, чтобы емейл пришел на Cloudflare вам потребуется домен. Нормальный, а не третьего уровня.

Я решился потратить $2 и у Namecheap купил домен в зоне.site. Привязал его к учётке на Cloudflare и приключение началось.

Я, вообще, раньше думал, что Javascript хорошо знаю. Но это... Если бы не жаба о разбазаренный 2 долларах бросил бы уже в 2 ночи.

К счастью на следующий день был выходной и я бросил в 3, а на следующее утро допилил решение за несколько часов.

Как же оно работает

  • Устанавливаем wrangler и создаём воркер. Для начала самый простой. Код можно взять из примеров. Деплоим его:

    wrangler deploy

  • На Cloudflare создаём адрес эл.почты на вашем домене и связываем его с нашим воркером. И можно уже посылать емейлы на наш воркер.

  • К сожалению wrangler не умеет запускать емейл воркеры локально. Поэтому приходится всякий раз:

    wrangler deploy --keep-vars && wrangler tail

Код воркера выглядит просто:

export default {
async email(message, env, ctx) {
// здесь вся логика обработки емейла
}
}

Всё просто. Но нет.

Message приходит в виде незнакомого мне ReadableStream. Пока нашёл как его перевести в строку потратил все кредиты на ЧатГПТ. В конечном итоге скопипастил это:

async function streamToArrayBuffer(stream, streamSize) {
  let result = new Uint8Array(streamSize);
  let bytesRead = 0;
  const reader = stream.getReader();
  while (true) {
    const { done, value } = await reader.read();
    if (done) {
      break;
    }
    result.set(value, bytesRead);
    bytesRead += value.length;
  }
  return result;
}

Итак теперь у нас есть массив байт. Не строка. Причём этот массив байт представляет MimeEmail. Чтобы получить собственно сообщение используем библиотеку Postal-mime.

      const PostalMime = require('postal-mime/dist/node').postalMime.default;
      const parser = new PostalMime();
      const parsedEmail = await parser.parse(rawEmail)

Ну и наконец, когда мы получили наш емейл, можно заняться его разбором.

Сообщение приходит как HTML. К счастью очень простой поэтому получилось разобрать его регулярками.

Некоторые скажут: «надо было брать cheerio‑jsdom!». Но нет — оно тяжёлое и загрузить его в воркер бесплатно не получится.

Кроме того, у бесплатного Cloudflare есть ограничение в 10мс на обработку запроса воркером, что, на поверку оказывается очень мало (но достаточно чтобы послать запрос в ClickUp).

Есть и другие ограничения в бесплатной версии, например:

  • Размер вокера не больше 1Мб — так что jsdom не пройдёт

  • Воркер ограницен 50 подзапросами и всего 6 параллельных. Так что сканировать интернет не получится.

  • Время старта воркера не должно превышать 200мс что тоже ограничивает его размер.

  • Размер запроса — 100Мб — фильм не закачаешь

  • Время исполнения — 10мс. МИЛЛИсекунд! Да на что это вообще может хватить!?
    В платном плане — 50мс, что тоже не очень много

Вот, в общем и все значимые ограничения. Есть и другие — читайте


Что ж, это было интересно и захватывающе.
Что то новое и светлое.
И бесплатное.
И быстрое.

И, главное, работает.

Комментарии (2)


  1. dsrk_dev
    03.06.2023 08:13

    Не 10мс, а 10мс процессорного времени. Это кстати две большие разницы. У меня функции без проблем выполняются сотни мс. Да, по большей части это тупо ожидание ответа от бека


  1. martovsky
    03.06.2023 08:13

    Я, вообще, раньше думал, что Javascript хорошо знаю.

    Но нет. Message приходит в виде незнакомого мне ReadableStream