Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Фронтенд
  4. React
  5. Форма обратного звонка на React + Express + Яндекс SMTP / Отправка форм обратных связей через SMTP

Форма обратного звонка на React + Express + Яндекс SMTP / Отправка форм обратных связей через SMTP

Запланировано Прикреплена Закрыта Перенесена React
2 Сообщения 1 Постеры 11 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • kirilljsxK Не в сети
    kirilljsxK Не в сети
    kirilljsx
    js
    написал отредактировано
    #1

    Схема работы

    React-форма → POST /api/callback → Express → SMTP Яндекса → письмо на почту
    

    React отправляет POST-запрос. Express принимает данные и отправляет письмо через nodemailer. Логин и пароль хранятся только на сервере.


    Важно: IMAP ≠ SMTP

    • IMAP - для чтения почты.
    • SMTP - для отправки писем.

    Включенный IMAP в настройках Яндекса не дает возможности отправлять письма. Нужен SMTP + пароль приложения.


    Установка

    npm install express nodemailer cors dotenv
    

    Переменные окружения

    Создайте файл .env и добавьте его в .gitignore:

    YANDEX_EMAIL=your@yandex.ru
    YANDEX_APP_PASSWORD=пароль_приложения
    PORT=3001
    

    Пароль приложения создаётся в Яндекс ID → Безопасность → Пароли приложений → Почта. Основной пароль от аккаунта использовать нельзя.


    Модуль отправки

    // lib/mailer.js
    import nodemailer from 'nodemailer';
    
    const transporter = nodemailer.createTransport({
      host: 'smtp.yandex.ru',
      port: 465,
      secure: true,
      auth: {
        user: process.env.YANDEX_EMAIL,
        pass: process.env.YANDEX_APP_PASSWORD,
      },
    });
    
    export async function sendCallbackEmail({ name, phone, message }) {
      await transporter.sendMail({
        from: `"Сайт" <${process.env.YANDEX_EMAIL}>`,
        to: process.env.YANDEX_EMAIL,
        subject: `Обратный звонок: ${name}`,
        html: `
          <p><b>Имя:</b> ${name}</p>
          <p><b>Телефон:</b> ${phone}</p>
          <p><b>Сообщение:</b> ${message || 'не указано'}</p>
        `,
      });
    }
    

    Express-сервер

    // server.js
    import 'dotenv/config';
    import express from 'express';
    import cors from 'cors';
    import { sendCallbackEmail } from './lib/mailer.js';
    
    const app = express();
    
    app.use(cors({ origin: 'http://localhost:3000' }));
    app.use(express.json());
    
    app.post('/api/callback', async (req, res) => {
      const { name, phone, message } = req.body;
    
      if (!name || !phone) {
        return res.status(400).json({ error: 'Имя и телефон обязательны' });
      }
    
      try {
        await sendCallbackEmail({ name, phone, message });
        res.json({ success: true });
      } catch (err) {
        console.error(err);
        res.status(500).json({ error: 'Ошибка отправки письма' });
      }
    });
    
    app.listen(process.env.PORT, () => {
      console.log(`Server running on port ${process.env.PORT}`);
    });
    

    React-форма

    // components/CallbackForm.jsx
    import { useState } from 'react';
    
    const INITIAL = { name: '', phone: '', message: '' };
    
    export function CallbackForm() {
      const [form, setForm] = useState(INITIAL);
      const [status, setStatus] = useState('idle'); // idle | loading | success | error
    
      const onChange = (e) =>
        setForm((p) => ({ ...p, [e.target.name]: e.target.value }));
    
      const onSubmit = async (e) => {
        e.preventDefault();
        setStatus('loading');
    
        try {
          const res = await fetch('http://localhost:3001/api/callback', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(form),
          });
    
          if (!res.ok) throw new Error();
          setStatus('success');
          setForm(INITIAL);
        } catch {
          setStatus('error');
        }
      };
    
      return (
        <form onSubmit={onSubmit}>
          <input name="name"    value={form.name}    onChange={onChange} placeholder="Имя"     required />
          <input name="phone"   value={form.phone}   onChange={onChange} placeholder="Телефон" required />
          <textarea name="message" value={form.message} onChange={onChange} placeholder="Сообщение" />
    
          <button type="submit" disabled={status === 'loading'}>
            {status === 'loading' ? 'Отправка...' : 'Заказать звонок'}
          </button>
    
          {status === 'success' && <p>✅ Заявка отправлена</p>}
          {status === 'error'   && <p>❌ Ошибка. Попробуйте позже</p>}
        </form>
      );
    }
    

    Структура проекта

    project/
    ├── server.js
    ├── lib/
    │   └── mailer.js
    ├── .env              ← не коммитить
    ├── .gitignore
    └── client/           ← React-приложение
        └── src/
            └── components/
                └── CallbackForm.jsx
    

    Запуск

    # Сервер
    node server.js
    
    # React (отдельный терминал)
    npm start
    

    Частые ошибки

    Ошибка Причина Решение
    Invalid login Основной пароль вместо пароля приложения Создать пароль приложения в Яндекс ID
    Connection refused Сервер не запущен или неверный порт Проверить PORT в .env
    CORS-ошибка Неверный origin в cors() Указать адрес React-приложения
    Письмо не приходит SMTP не разрешён в настройках Яндекса Включить SMTP в настройках почты

    Что добавить в продакшене

    • Rate limiting - express-rate-limit, чтобы ограничить спам.
    • Валидация - zod или joi для проверки данных на сервере.
    • Переменные окружения на сервере - не .env файл, а переменные хостинга.
    • HTTPS - обязательно при развёртывании.

    Порт использовать для Яндекс SMTP
    465 (SSL). Можно 587 с secure: false и STARTTLS.

    Как проверить, что письмо уходит, до подключения React?
    Протестировать маршрут через Postman или curl:

    curl -X POST http://localhost:3001/api/callback \
      -H "Content-Type: application/json" \
      -d '{"name":"Тест","phone":"+79001234567"}'
    
    1 ответ Последний ответ
    0
    • kirilljsxK Не в сети
      kirilljsxK Не в сети
      kirilljsx
      js
      написал отредактировано
      #2

      Как получить пароль приложения для Яндекс почты

      Заходим в настройки почты

      0c693338-e460-4eb1-9bd7-876cf010ef69-image.jpeg

      Далее проваливаемся в почтовые программы

      99e36ddc-39c3-474d-aa52-ae8dd5b90448-image.jpeg

      Видим разрашения доступов

      f1ad9bea-dff3-4129-a698-659fa057c06f-image.jpeg

      Тыкаем на пароли приложения

      2a2fa9f4-054a-4477-ae5f-e9c22268b998-image.jpeg

      Яндекс опять показывает кучу всего не нужного, тыкаем на “Безопасность”

      617348df-dc05-4357-a5b6-3dbb9c9c0830-image.jpeg

      И вот тут наконец-то мы видим наши долгожданные пароли приложений если прокрутить вниз

      0d2a66b2-fcf8-4e80-ad2a-c5cd7d415b4e-image.jpeg

      Далее создаем пароль приложения, кстати важно! Пароль показывается один раз, так что запишите его.

      61868799-8d86-4cd8-8ef5-ed64a7a6377d-image.jpeg

      Ну, а кому лень тыкать и понимать где находятся пароли приложения, вот ссылка - https://id.yandex.ru/security/app-passwords по ней сразу перейдете в нужный раздел, только убедитесь что вы залогинены в нужной вам почте.

      1 ответ Последний ответ
      0

      Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.

      Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

      С вашими комментариями этот пост мог бы стать ещё лучше 💗

      Зарегистрироваться Войти

      Категории

      • Главная
      • Новости
      • Фронтенд
      • Бекенд
      • Языки программирования

      Контакты

      • Сотрудничество
      • info@exlends.com

      © 2024 - 2026 ExLends, Inc. Все права защищены.

      Политика конфиденциальности
      • Войти

      • Нет учётной записи? Зарегистрироваться

      • Войдите или зарегистрируйтесь для поиска.
      • Первое сообщение
        Последнее сообщение
      0
      • Лента
      • Категории
      • Последние
      • Метки
      • Популярные
      • Пользователи
      • Группы