226 lines
9.1 KiB
Markdown
226 lines
9.1 KiB
Markdown
# 📧 Email News Fetching
|
||
|
||
Автоматическое получение новостей из Email и создание черновиков в системе.
|
||
|
||
## 📋 Описание
|
||
|
||
Функция позволяет автоматически:
|
||
- Подключаться к IMAP-серверу
|
||
- Получать непрочитанные письма от редактора
|
||
- Скачивать вложения (DOC, DOCX, изображения)
|
||
- Создавать новости через существующий `ProcessMixedFilesAction`
|
||
- Помечать обработанные письма как прочитанные
|
||
|
||
## 🏗 Архитектура (Porto)
|
||
|
||
```
|
||
app/Containers/Dashboard/
|
||
├── Actions/
|
||
│ └── FetchEmailNewsAction.php # Оркестрация процесса
|
||
├── Tasks/
|
||
│ ├── ConnectToImapTask.php # IMAP подключение
|
||
│ ├── FetchUnreadEmailsTask.php # Получение писем
|
||
│ ├── FilterBySenderTask.php # Фильтрация по отправителю
|
||
│ ├── DownloadAttachmentsTask.php # Загрузка вложений
|
||
│ └── MarkEmailAsReadTask.php # Пометка как прочитанное
|
||
├── Data/
|
||
│ └── EmailAttachmentData.php # DTO для вложений
|
||
├── Exceptions/
|
||
│ └── EmailFetchException.php # Исключения
|
||
├── Commands/
|
||
│ └── FetchEmailNewsCommand.php # Artisan команда
|
||
└── Configs/
|
||
└── email-news.php # Конфигурация
|
||
```
|
||
|
||
## 🔧 Установка
|
||
|
||
### 1. Пересобрать PHP-контейнер (требуется расширение IMAP)
|
||
|
||
```bash
|
||
docker-compose down
|
||
docker-compose build --no-cache ntspi-php
|
||
docker-compose up -d
|
||
```
|
||
|
||
### 2. Настроить переменные окружения
|
||
|
||
Скопируйте `.env.email-news.example` в `.env` и заполните:
|
||
|
||
```env
|
||
EMAIL_NEWS_ENABLED=true
|
||
EMAIL_NEWS_IMAP_HOST=imap.yandex.ru
|
||
EMAIL_NEWS_IMAP_PORT=993
|
||
EMAIL_NEWS_ENCRYPTION=ssl
|
||
EMAIL_NEWS_IMAP_USER=news@ntspi.ru
|
||
EMAIL_NEWS_IMAP_PASS=app_password
|
||
EMAIL_NEWS_SENDER_EMAIL=editor@example.com
|
||
EMAIL_NEWS_FOLDER=INBOX
|
||
```
|
||
|
||
### 3. Протестировать подключение
|
||
|
||
Запустите команду вручную:
|
||
|
||
```bash
|
||
docker exec -it ntspi-php php artisan email:fetch-news --log
|
||
```
|
||
|
||
## 📝 Использование
|
||
|
||
### Ручной запуск
|
||
|
||
```bash
|
||
# Обычный запуск
|
||
docker exec -it ntspi-php php artisan email:fetch-news
|
||
|
||
# С подробным логом
|
||
docker exec -it ntspi-php php artisan email:fetch-news --log
|
||
|
||
# Принудительный запуск (если отключено в конфиге)
|
||
docker exec -it ntspi-php php artisan email:fetch-news --force
|
||
```
|
||
|
||
### Автоматический запуск (Cron)
|
||
|
||
Команда автоматически добавлена в расписание Laravel Scheduler:
|
||
- **Частота:** каждые 5 минут
|
||
- **Защита от перекрытий:** `withoutOverlapping()`
|
||
- **Один сервер:** `onOneServer()`
|
||
|
||
Scheduler уже настроен в `app/Ship/Kernels/ConsoleKernel.php`.
|
||
|
||
Убедитесь, что Cron запущен в контейнере:
|
||
|
||
```bash
|
||
# Проверьте crontab
|
||
docker exec -it ntspi-php crontab -l
|
||
|
||
# Должно быть:
|
||
# * * * * * php /var/www/artisan schedule:run >> /dev/null 2>&1
|
||
```
|
||
|
||
## 🔐 Безопасность
|
||
|
||
### Фильтрация отправителей
|
||
|
||
Обрабатываются **только письма от редактора**, указанного в `EMAIL_NEWS_SENDER_EMAIL`.
|
||
|
||
Письма от других отправителей:
|
||
- ❌ Не обрабатываются
|
||
- ❌ Не скачиваются
|
||
- ✅ Логируются (если `EMAIL_NEWS_LOG_SKIPPED=true`)
|
||
- ✅ Остаются в папке (не помечаются прочитанными)
|
||
|
||
### Whitelist нескольких отправителей
|
||
|
||
В конфиге `app/Containers/Dashboard/Configs/email-news.php` можно указать несколько email:
|
||
|
||
```php
|
||
'allowed_senders' => [
|
||
env('EMAIL_NEWS_SENDER_EMAIL'),
|
||
env('EMAIL_NEWS_SENDER_EMAIL_2'),
|
||
env('EMAIL_NEWS_SENDER_EMAIL_3'),
|
||
],
|
||
```
|
||
|
||
### App-Specific Password
|
||
|
||
**Рекомендуется** использовать специальный пароль приложения вместо основного пароля:
|
||
|
||
- **Yandex:** https://passport.yandex.ru/profile/passwords
|
||
- **Google:** https://myaccount.google.com/apppasswords
|
||
- **Mail.ru:** https://account.mail.ru/security
|
||
|
||
## 📊 Логирование
|
||
|
||
Логи доступны в `storage/logs/laravel.log`:
|
||
|
||
```log
|
||
[2024-01-15 10:30:00] local.INFO: [FetchEmailNewsAction] Начало получения новостей из Email
|
||
[2024-01-15 10:30:01] local.INFO: [ConnectToImapTask] Успешное подключение к IMAP
|
||
[2024-01-15 10:30:02] local.INFO: [FetchUnreadEmailsTask] Получены письма: count=3
|
||
[2024-01-15 10:30:02] local.INFO: [FilterBySenderTask] Фильтрация писем: total=3, filtered=2, skipped=1
|
||
[2024-01-15 10:30:05] local.INFO: [FetchEmailNewsAction:processEmail] Письмо успешно обработано: post_id=123
|
||
```
|
||
|
||
## ⚠️ Обработка ошибок
|
||
|
||
### Типичные ошибки
|
||
|
||
| Ошибка | Причина | Решение |
|
||
|--------|---------|---------|
|
||
| `Не удалось подключиться к IMAP-серверу` | Неправильный хост/порт/пароль | Проверьте `.env` настройки |
|
||
| `IMAP-папка не найдена` | Папка не существует | Проверьте имя папки в `EMAIL_NEWS_FOLDER` |
|
||
| `Письмо получено от неразрешённого отправителя` | Отправитель не в whitelist | Добавьте email в `allowed_senders` |
|
||
| `Нет DOC/DOCX файла для извлечения текста` | Во вложениях нет документа | Редактор должен прикрепить DOC/DOCX |
|
||
|
||
### Отладка
|
||
|
||
```bash
|
||
# Запуск с подробным выводом
|
||
docker exec -it ntspi-php php artisan email:fetch-news --log
|
||
|
||
# Просмотр последних логов
|
||
docker exec -it ntspi-php tail -f storage/logs/laravel.log
|
||
|
||
# Проверка расширения IMAP
|
||
docker exec -it ntspi-php php -m | grep imap
|
||
```
|
||
|
||
## 🔄 Поток данных
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Cron (каждые 5 мин) → php artisan email:fetch-news │
|
||
│ ↓ │
|
||
│ FetchEmailNewsCommand │
|
||
│ ↓ │
|
||
│ FetchEmailNewsAction │
|
||
│ ├─ ConnectToImapTask (IMAP-соединение) │
|
||
│ ├─ FetchUnreadEmailsTask (получение писем) │
|
||
│ ├─ FilterBySenderTask (проверка отправителя) │
|
||
│ ├─ DownloadAttachmentsTask (скачивание вложений) │
|
||
│ └─ ProcessMixedFilesAction (создание поста) ←───┐ │
|
||
│ ↓ │ │
|
||
│ MarkEmailAsReadTask (пометка как прочитанное) │ │
|
||
└───────────────────────────────────────────────────┼────┘
|
||
│
|
||
┌───────────────────────────────┘
|
||
↓
|
||
Существующий процесс создания новости
|
||
(AI-распознавание, сжатие изображений, и т.д.)
|
||
```
|
||
|
||
## 🧪 Тестирование
|
||
|
||
### Отправка тестового письма
|
||
|
||
1. Отправьте письмо с `EMAIL_NEWS_SENDER_EMAIL` на `EMAIL_NEWS_IMAP_USER`
|
||
2. Прикрепите DOC/DOCX файл (текст новости)
|
||
3. Прикрепите изображения (опционально)
|
||
4. Запустите команду:
|
||
|
||
```bash
|
||
docker exec -it ntspi-php php artisan email:fetch-news --log
|
||
```
|
||
|
||
5. Проверьте создание новости в Dashboard
|
||
|
||
### Мок-тестирование (для разработчиков)
|
||
|
||
```php
|
||
// В Unit-тестах можно моковать IMAP
|
||
$this->mock(ClientManager::class, function ($mock) {
|
||
$mock->shouldReceive('account')
|
||
->with('email_news')
|
||
->andReturn($client);
|
||
});
|
||
```
|
||
|
||
## 📚 Ссылки
|
||
|
||
- [Webklex PHP-IMAP Documentation](https://github.com/Webklex/php-imap)
|
||
- [Laravel Scheduler](https://laravel.com/docs/10.x/scheduling)
|
||
- [Porto Architecture](https://github.com/AlxDorosenco/Porto)
|