Если ваша CMS или CRM умеет отправлять email-копию о новом заказе на произвольный адрес — этот гайд для вас. InSales, RetailCRM, МойСклад, WooCommerce, Битрикс, самописная система — без разницы. Инфраструктура одна и та же. Ссылка на гитхаб с полный мануалом по установке на русском в конце статьи.
Поводом написать стало то, что неделю назад приложение InSales было удалено из App Store и пуши о заказах пропали сразу. Таким образом мы пропустили несколько заказов, но благо они не сорвались полностью, хотя небольшой неприятный осадок остался.
Первая мысль при поиске решения — n8n или Make. Но зарубежные no‑code платформы сейчас работают в России нестабильно из‑за замедлений и блокировок трафика. Строить критическую бизнес‑инфраструктуру на том, что может лечь в любой момент — плохая идея.
Задача: автономная система, работающая внутри РФ, без постоянного сервера, с доставкой уведомлений в Telegram за секунды. Решение — Yandex Cloud Serverless: он не боится блокировок, имеет очень щедрые лимиты, благодаря чему функция работает полностью бесплатно. К тому же, сервис очень гибок в настройке и улучшении.
Расскажу, что получилось, и дам полный гайд по настройке.

Архитектура: как это работает
Ключевой инсайт: InSales (и большинство других CMS/CRM) умеет отправлять email-копию о каждом новом заказе на указанный адрес. Этот email и стал источником данных. Ищите в настройках своей платформы что‑то вроде «отправлять копию заказа на email».
У Yandex Cloud есть Email Trigger — сервис, который создаёт технический почтовый адрес вида xxxx@serverless.yandexcloud.net. Когда на него приходит письмо, автоматически запускается Cloud Function с телом письма в payload.
Дальше всё просто:
InSales ↓ email-уведомление о заказе Yandex Cloud Email Trigger ↓ Cloud Function (Node.js) ↓ Telegram Bot API
Уведомление приходит в Telegram через 5–10 секунд после оформления заказа.
Две версии: Lite и Pro
Я сделал два варианта под разные сценарии.
Lite — для тех, кто работает в одиночку или просто хочет видеть заказы без лишних усложнений:
InSales email → Email Trigger → Cloud Function → Telegram
Никаких баз данных, никаких очередей. Настраивается за 20–40 минут.
Pro — скорее для команды менеджеров, где важно контролировать, кто и когда взял заказ в работу. Если заказ никто не взял в течение 10 минут (можно настроить время), то придёт повторное напоминание.
InSales email ↓ Email Trigger ↓ Cloud Function ├─ отправляет заказ в Telegram (с кнопкой «Принять заказ») ├─ сохраняет заказ в YDB (статус: pending) └─ кладёт request_id в YMQ с задержкой 10 минут ↓ если заказ не принят - отправляет напоминание в Telegram
Почему YDB + YMQ
Можно было обойтись простым setTimeout или внешним cron — но оба варианта ненадёжны в serverless‑среде, где функция живёт ровно столько, сколько нужно для выполнения запроса.
YDB Serverless хранит статус каждого заказа (pending / accepted). При нажатии кнопки статус меняется — и когда YMQ через 10 минут снова вызывает функцию, она проверяет базу и молчит, если заказ уже принят.
YMQ (Yandex Message Queue) — это совместимый с AWS SQS брокер очередей. Он позволяет положить сообщение с задержкой (DelaySeconds: 600) и гарантировать его доставку. Функция не висит в памяти, а просто просыпается, когда пришло время.
Это классическая Event‑Driven Architecture: одна Cloud Function обрабатывает три типа событий, определяя источник по структуре входящего event:
Что пришло в event |
Что делает функция |
|---|---|
|
Парсит заказ, пишет в YDB, отправляет в Telegram, кладёт в YMQ |
|
Меняет статус в YDB, редактирует кнопку в Telegram |
|
Проверяет статус в YDB, при необходимости шлёт напоминание |
Ни одного постоянно работающего сервера. Платим только за фактические вызовы.
Сравнительная таблица версий
Возможность |
Lite |
Pro |
|---|---|---|
Уведомление о заказе в Telegram |
✅ |
✅ |
Парсинг email-письма InSales |
✅ |
✅ |
Кнопка «Принять заказ» |
❌ |
✅ |
Статус заказа в YDB |
❌ |
✅ |
Кто принял заказ |
❌ |
✅ |
Напоминание, если заказ не принят |
❌ |
✅ |
Время настройки |
20-40 мин |
60-120 мин |
Экономика: почему это почти бесплатно
Проект работает полностью на serverless, отдельный сервер не нужен. Оплата идёт только за фактическое использование.
На момент написания статьи Yandex Cloud даёт каждый месяц бесплатно:
Cloud Functions: 1 000 000 вызовов + 10 GB×hour выполнения
Yandex Message Queue: 100 000 запросов
YDB Serverless: 1 000 000 Request Units + 1 ГБ хранения
Триггеры (Email Trigger, YMQ Trigger) тарифицируются отдельно по числу вызовов функции, то есть дополнительных расходов за сами триггеры нет.
Посчитаем реальную нагрузку для Pro-версии. Один заказ создаёт примерно 2–3 вызова функции:
1. Email Trigger → функция получает заказ, пишет в YDB, шлёт в Telegram, кладёт в YMQ 2. Менеджер нажимает кнопку → webhook → функция обновляет YDB и Telegram 3. YMQ Trigger → функция проверяет статус (и молчит, если уже принят)
Заказов в день |
В месяц |
Вызовов функции в месяц |
Укладываемся в бесплатный лимит? |
|---|---|---|---|
10 |
~300 |
~600–900 |
✅ с запасом |
100 |
~3 000 |
~6 000–9 000 |
✅ всё ещё с запасом |
500 |
~15 000 |
~30 000–45 000 |
✅ |
1 000 |
~30 000 |
~60 000–90 000 |
✅ |
Для магазина с тысячей заказов в день нагрузка — это примерно 9% от бесплатного лимита вызовов Cloud Functions. YDB и YMQ тоже остаются в пределах бесплатной квоты.
Расчёт приблизительный. Точную стоимость лучше проверять в калькуляторе Yandex Cloud - тарифы, регион и объём логов влияют на итоговую сумму.
Пошаговый гайд по развёртыванию
Шаг 0. Создаём Telegram-бота и чат
Создаём бота:
Открываем @BotFather в Telegram, отправляем /newbot, задаём имя и username (должен заканчиваться на bot). BotFather выдаст токен — сохраняем:
TELEGRAM_BOT_TOKEN=1234567890:AAHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Создаём чат и добавляем бота:
Создаём отдельную группу или канал для уведомлений о заказах. Добавляем бота как участника (в группу) или администратора (в канал). Для Pro-версии бот должен уметь редактировать сообщения.
Получаем chat_id:
Проще всего через @UserInfoBot — запускаем, выбираем нужный чат, копируем ID. Сохраняем:
TELEGRAM_CHAT_ID=-1001234567890
Проверяем, что всё работает:
https://api.telegram.org/bot<TOKEN>/sendMessage?chat\_id=<CHAT\_ID>&text=Проверка
Шаг 1. Подготавливаем Yandex Cloud
Заходим на console.yandex.cloud, создаём аккаунт и привязываем платёжный аккаунт (нужен для активации сервисов, даже если будем укладываться в бесплатный лимит).
Создаём сервисный аккаунт:
IAM → Сервисные аккаунты → Создать
Имя: order-alerts-functions-sa
Для Lite достаточно роли serverless.functions.invoker. Для Pro добавляем ещё:
ydb.editor ymq.writer ymq.reader serverless.functions.invoker
Для Pro — создаём статический ключ доступа:
Сервисный аккаунт → Создать новый ключ → Статический ключ доступа
⚠️
Secret access keyпоказывается только один раз. Сохраните сразу.
AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY=
Шаг 2. Создаём YDB и YMQ (только для Pro)
YDB:
YDB → Создать базу данных → Serverless
Из строки подключения формата grpcs://.../?database=/ru-central1/xxxx/yyyy выделяем два значения:
YDB_ENDPOINT=grpcs://ydb.serverless.yandexcloud.net:2135 YDB_DATABASE=/ru-central1/xxxx/yyyy
Создаём таблицу в Query editor:
CREATE TABLE `insales_order_alerts` ( request_id Utf8 NOT NULL, status Utf8, order_number Utf8, phone Utf8, name Utf8, customer_email Utf8, products_text Utf8, total_price Utf8, comment Utf8, delivery_text Utf8, payment_text Utf8, payment_status Utf8, order_url Utf8, message_id Utf8, created_at Utf8, accepted_by Utf8, accepted_at Utf8, raw_subject Utf8, raw_email_text Utf8, PRIMARY KEY (request_id) );
YMQ:
Message Queue → Создать очередь → Standard
Название: insales-order-reminders. Задержку доставки оставляем 0 задержка будет задаваться в коде (DelaySeconds: 600). После создания копируем URL очереди:
YMQ_QUEUE_URL=https://message-queue.api.cloud.yandex.net/xxxx/yyyy/insales-order-reminders
Шаг 3. Создаём Cloud Function
Cloud Functions → Создать функцию
Имя: order-mail-to-telegram. Runtime: Node.js. Точка входа: index.handler. Сервисный аккаунт: order-alerts-functions-sa.
Загружаем код:
Берём lite/index.js или pro/index.js из репозитория. Добавляем package.json:
Для Lite:
{ "dependencies": { "html-to-text": "^9.0.5" } }
Для Pro:
{ "dependencies": { "ydb-sdk": "^5.11.1", "@yandex-cloud/nodejs-sdk": "latest", "@aws-sdk/client-sqs": "^3.600.0", "html-to-text": "^9.0.5" } }
Переменные окружения для Pro:
TELEGRAM_BOT_TOKEN= TELEGRAM_CHAT_ID= YDB_ENDPOINT=grpcs://ydb.serverless.yandexcloud.net:2135 YDB_DATABASE= ORDERS_TABLE=insales_order_alerts YMQ_QUEUE_URL= AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION=ru-central1 REMINDER_DELAY_SECONDS=600
После деплоя у функции появится URL - сохраняем его, он понадобится для webhook.
Для Pro делаем функцию публичной (Telegram будет стучаться в неё при нажатии кнопки).
Шаг 4. Подключаем Email Trigger
Cloud Functions → Триггеры → Создать триггер → Почта
Привязываем к нашей функции, выбираем сервисный аккаунт, размер группы = 1, количество попыток = 1 на старте.
Если при сохранении триггера появляется ошибка прав — временно выдайте сервисному аккаунту роль
editor, создайте триггер, затем отзовите обратно.
После создания триггер выдаст технический email-адрес:
xxxxxxxxxxxxxxxxxxxx@serverless.yandexcloud.net
Добавляем его в InSales:
Настройки → Карточка магазина → Email для уведомлений
Шаг 5. Настраиваем Telegram Webhook (только для Pro)
Устанавливаем webhook. Делается одним GET-запросом в браузере:
https://api.telegram.org/bot<TOKEN>/setWebhook?url=<FUNCTION\_URL>&allowed\_updates=%5B%22message%22%2C%22callback\_query%22%5D
Проверяем:
https://api.telegram.org/bot<TOKEN>/getWebhookInfo
В ответе должны быть:
url- URL нашей Cloud Functionallowed_updates- содержитcallback_query
Без
callback_queryкнопка «Принять заказ» работать не будет.
Шаг 6. Создаём YMQ Trigger (только для Pro)
Cloud Functions → Триггеры → Создать триггер → Message Queue
Выбираем очередь insales-order-reminders, привязываем к той же функции. Размер группы = 1.
На этом настройка завершена. Создаём тестовый заказ и через 5–10 секунд в Telegram придёт уведомление.
Как это работает под капотом
Самое интересное — как один handler разбирается с тремя совершенно разными типами входящих событий.
module.exports.handler = async function (event) { try { console.log('Incoming event keys:', Object.keys(event || {})); // 1. Telegram webhook: менеджер нажал кнопку «Принять заказ» const callback = getTelegramCallback(event); if (callback) { console.log('Route: telegram callback'); return await handleTelegramCallback(callback); } // 2. YMQ Trigger: пришло отложенное напоминание из очереди const requestIds = extractRequestIdsFromQueueEvent(event); if (requestIds.length > 0) { console.log('Route: reminder queue', requestIds); return await handleReminderEvent(requestIds); } // 3. Email Trigger: новый заказ из InSales if (event.httpMethod && event.httpMethod !== 'POST') { return jsonResponse(405, { ok: false, error: 'Method not allowed' }); } console.log('Route: email order'); return await handleEmailOrder(event); } catch (error) { console.error('insales-order-handler failed:', error); return jsonResponse(500, { ok: false, error: 'Internal server error', message: error.message }); } };
Логика роутинга проста:
Если в
eventестьcallback_query— это Telegram webhook. Достаёмrequest_idизcallback_data, находим заказ в YDB, меняем статус наaccepted, редактируем кнопку и уведомляем чат.Если в
event.messages[]есть JSON сrequest_id— это сообщение из YMQ. Смотрим статус заказа в YDB: еслиpending— шлём напоминание, еслиaccepted— молчим.Всё остальное Email Trigger с письмом о заказе. Парсим, пишем в YDB, шлём в Telegram, кладём
request_idв YMQ.
Парсер письма
Это самая хрупкая часть. Письма от разных магазинов приходят в разном формате, поэтому парсер построен на массиве регулярных выражений с приоритетом — matchFirst берёт первое совпадение:
const orderNumber = matchFirst(sourceText, [ /Поступил заказ\s*№\s*([^\s\n]+)/i, /заказ\s*№\s*([^\s\n!]+)/i, /Благодарим Вас за заказ\s*№\s*([^\s\n!]+)/i, /Новый заказ\s*№\s*([^\s\n]+)/i, ]);
Аналогично работает извлечение телефона, email, состава заказа, доставки и ссылки на админку. HTML из письма преобразуется в текст через html-to-text, после чего regex-ами вырезаются нужные блоки.
Ссылка на заказ в админке вытаскивается отдельно InSales часто оборачивает её в tracking URL. Функция extractRealUrlFromInsalesTracker декодирует base64url-параметр url, чтобы получить реальный адрес:
function extractRealUrlFromInsalesTracker(url) { const parsed = new URL(rawUrl); const encodedTarget = parsed.searchParams.get('url'); const decodedTarget = decodeBase64Url(encodedTarget); return decodedTarget || rawUrl; }
Как выглядит уведомление
Обычное уведомление о заказе:
? Новый заказ! Заказ: №6004 Клиент: Иван Телефон: 8(999)123-45-67 E-mail: client@example.com Состав заказа: Массажный пистолет Booster M2 Комплектация: Набор для дома Сумма: 9 990 ₽ Оплата: Оплата при получении Открыть заказ в админке [кнопка] [✅ Принять заказ]
Напоминание через 10 минут (если заказ не взяли):
? Заказ не принят 10 минут Заказ: №6004 Клиент: Иван Телефон: 8(999)123-45-67 Открыть заказ в админке
Адаптация под другие системы
К InSales привязан только парсер письма, и то его легко переписать. Сама инфраструктура (Email Trigger → Cloud Function → YDB/YMQ → Telegram) работает с любой системой, которая умеет слать email-копию о заказе.
Единственное условие: в настройках вашей платформы должна быть возможность добавить дополнительный email-адрес для уведомлений о заказах. В большинстве CMS и CRM это есть.
Очевидно совместимо:
RetailCRM - есть настройка уведомлений на email
МойСклад - есть триггеры по событиям с email-уведомлением
Любая самописная CRM - если умеет слать письма
Другие CMS - Битрикс, OpenCart, WooCommerce
Для адаптации под другой формат письма достаточно поправить регулярки в parseOrderEmail, extractProductsText и extractDeliveryText. Подробный разбор каждой функции — в docs/code-overview.md в репозитории.
Итог
Система работает, менеджеры не пропускают заказы. Весь функционал обходится абсолютно бесплатно. В будущем можно расширяться — добавить полезные кнопки, разнообразить статусы заказа.
Что получилось:
Serverless — нет постоянного сервера, платить не за что
Работает внутри РФ — никаких зависимостей от зарубежных сервисов, максимальная скорость
Event‑Driven — одна функция обрабатывает email, webhook и очередь
Open source — можно форкнуть и адаптировать под свой стек
Сервис для отправки заказов из email-уведомлений интернет-магазина в Telegram через Yandex Cloud. Есть Lite-версия для простых уведомлений и Pro-версия с кнопкой принятия, статусом заказа и напоминанием, если заказ не принят в течение некоторого времени. Функционал бесплатный или совсем дешёвый при огромных объёмах, не боится блокировок.
Код в репозитории DmitriiDmallSick/order-mail-to-telegram: полная документация с пошаговыми скриншотами, два варианта кода (Lite и Pro), примеры .env файлов и разбор каждой функции в docs/code-overview.md.
egranty
У меня - разрыв шаблона. Или Телеграм в РФ больше не блокируют?
Dimazzina Автор
Си, корректо
Только в посте про саму доставку. К сожалению, если выбирать инструмент для мгновенных уведомлений в карман менеджерам, альтернатив Телеграму с такой же простой интеграцией сейчас практически нет.
Запрос в Telegram API улетает из бэкенда (облачной функции Yandex Cloud), так что на этапе отправки внутри РФ всё происходит быстро. А дальше - да, идеальных каналов связи сейчас нет, но ТГ из доступного остается самым отзывчивым.
Для крупных команд, конечно, правильнее настраивать приём в корпоративных мини-приложениях или чатах, но для малого e-commerce это быстрый и простой выход.