Zapier для бедных

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

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, а на следующее утро допилил решение за несколько часов.

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

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

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).

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

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


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

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

@copyhold
03.06.2023 11:38 UTC
Первоисточник

Комментарии

@dsrk_dev
03.06.2023 08:13 UTC
0

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

@martovsky
04.06.2023 09:15 UTC
0

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

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