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