Перейти к содержанию
Innovialabs

Как настроить отправку писем с формы обратной связи на сайте

Практика3 мин

Коротко

Надёжная форма сначала сохраняет заявку (в базу, CRM или Telegram), а уже потом отправляет письмо через транзакционный сервис с домена, настроенного по SPF, DKIM и DMARC; спам отсекают honeypot и лимит запросов.

Короткий ответ

Форма обратной связи не должна полагаться только на почту. Рабочая схема выглядит так:

  1. Браузер отправляет данные на ваш серверный обработчик (API-маршрут или serverless-функцию).
  2. Обработчик проверяет данные и отсекает спам.
  3. Заявка сохраняется: база данных, CRM, таблица или сообщение в Telegram.
  4. Только после этого отправляется письмо через SMTP или транзакционный сервис.
  5. Пользователь видит «Спасибо», когда заявка сохранена, даже если письмо задержалось.

Функция mail() на хостинге и отправка «от имени» Gmail без настроек — частые причины, по которым письма уходят в спам или теряются.

Способы отправки

СпособПлюсыМинусы
SMTP вашей почты (Google Workspace, Яндекс 360 и др.)просто, уже есть ящиклимиты на отправку, пароль приложения в настройках сервера
Транзакционный сервис (SendGrid, Mailgun, Postmark, Amazon SES, Resend)хорошая доставляемость, логи, вебхуки о недоставкенужна настройка DNS, платные тарифы при росте
Serverless-обработчик (Vercel, Netlify, Cloudflare)не нужен свой сервервнутри всё равно нужен SMTP или API почтового сервиса
Готовые сервисы формноль кодаданные у третьей стороны, меньше контроля

Для большинства сайтов разумный выбор — транзакционный сервис через API, вызываемый из серверного обработчика. Ключ API хранится в переменных окружения сервера и никогда не попадает в браузер.

Пример обработчика

Пример маршрута на Node.js с Nodemailer. Логика одинакова для любого фреймворка.

import nodemailer from "nodemailer";

const transport = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: 587,
  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }
});

export async function handleLead(body, ip) {
  if (body.website) return { ok: true };          // honeypot: бот заполнил скрытое поле
  if (!body.name || !body.contact) return { ok: false, error: "invalid" };
  if (await tooManyRequests(ip)) return { ok: false, error: "rate_limit" };

  const lead = await saveLead(body);               // сначала сохраняем

  try {
    await transport.sendMail({
      from: "Сайт <no-reply@example.com>",
      to: "sales@example.com",
      replyTo: body.email,
      subject: `Новая заявка: ${body.name}`,
      text: `${body.name}\n${body.contact}\n\n${body.message ?? ""}`
    });
  } catch (err) {
    await markForRetry(lead.id, err);              // письмо не ушло, заявка цела
  }
  return { ok: true };
}

Обратите внимание: From — адрес вашего домена, а email посетителя ставится в Reply-To. Если подставить адрес посетителя в From, почтовые системы почти наверняка отклонят письмо как подделку.

Защита от спама

  • Honeypot. Скрытое поле (например, website), невидимое человеку. Боты его заполняют — такие запросы молча игнорируйте.
  • Лимит запросов. Ограничьте число отправок с одного IP за промежуток времени.
  • Проверка времени. Форма, отправленная через секунду после загрузки страницы, скорее всего от бота.
  • Капча (Cloudflare Turnstile, reCAPTCHA) — когда honeypot и лимиты уже не справляются.
  • Валидация на сервере. Проверки в браузере легко обойти, повторяйте их на сервере.

Доставляемость

  • Отправляйте с собственного домена, а не с бесплатного ящика.
  • Настройте SPF (кто имеет право слать с домена), DKIM (подпись писем) и DMARC (что делать с письмами, не прошедшими проверку). Транзакционный сервис даёт готовые DNS-записи.
  • Пишите простые письма: понятная тема, текстовая версия, без сокращённых ссылок.
  • Следите за вебхуками о недоставке, если сервис их поддерживает.

Как не терять заявки

  • Сохраняйте заявку до отправки письма. Почта — уведомление, а не хранилище.
  • Дублируйте канал: письмо плюс сообщение в Telegram-чат или запись в CRM.
  • Повторы: неудачные отправки ставьте в очередь и пробуйте снова.
  • Мониторинг: раз в неделю отправляйте тестовую заявку или настройте алерт на ошибки обработчика.
  • Честный ответ пользователю: если сохранить не удалось, покажите ошибку и альтернативный контакт, а не «Спасибо».

Частые вопросы

Чаще всего из-за отправки с чужого или бесплатного адреса в поле From и отсутствия SPF, DKIM и DMARC у домена. Настройте записи DNS и отправляйте через сервис, который их поддерживает.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.