# Модуль: Внешние интеграции

[← К оглавлению](../README.md)

## DeepSeek (модерация + классификация)

- Все обращения идут через единый **`app/Services/DeepSeekClient.php`** (`chat()`): один HTTP-запрос к chat-completions, разбор ответа и **учёт расхода** (см. ниже). Поверх него работают три сервиса: `ModerationService`, `Import/CategoryClassifier` (категория при импорте), `AttributeSchemaService` (генерация характеристик, офлайн-команда).
- `ModerationService` возвращает JSON `{allowed, reason?}`. Проверяемые сущности:
  - **Объявления** (`check`, асинхронно через `ModerateAd`): запрещённый контент **+ соответствие категории** (путь хлебных крошек в промпте; авто в «Недвижимости» → отказ). Поток: подача/правка → `pending` → очередь → `active`/`blocked`. Подробнее — [ads.md](ads.md).
  - **Профиль** (`checkProfile`, **синхронно** при сохранении): имя, компания, описание на мат, оскорбления, ссылки, контакты в обход площадки, спам. При нарушении профиль не сохраняется. Подробнее — [cabinet.md](cabinet.md).
  - **Сообщения чата** (`checkMessage`) и **отзывы** (`checkReview`) — синхронно перед сохранением.
- Включение и ключ — в `/admin → Настройки` (`Setting`: `moderation_enabled`, `deepseek_api_key`, `deepseek_model`); fallback — `config/services.php` (`deepseek`).
- Fail-open: при ошибке/выключенной модерации всё пропускается.

### Учёт расходов (токены и деньги)

- После каждого ответа `DeepSeekClient` пишет строку в таблицу **`ai_usages`**: тип операции (`ad`/`profile`/`message`/`review`/`classify`/`attributes`), `user_id`, `ad_id`, модель, токены (prompt/completion + разбивка кэша) и **стоимость в USD**.
- Цена берётся из `config/services.php → deepseek.pricing` (за 1 млн токенов: `cache_hit`, `cache_miss`, `output`; дефолты — стандартный прайс `deepseek-chat`, переопределяются в `.env`: `DEEPSEEK_PRICE_CACHE_HIT/CACHE_MISS/OUTPUT`).
- Отчёт — в админке **Система → «Расходы ИИ»** (`/admin/ai-usages`): суммы за сегодня/7/30 дней/всего, разбивка по пользователям и объявлениям. Подробнее — [admin.md](admin.md).

### Защита от накрутки расхода

Эндпоинты, каждый вызов которых уходит в модерацию DeepSeek, ограничены по частоте на пользователя (лимитеры в `app/Providers/AppServiceProvider.php`): отзывы и сохранение профиля — `throttle:moderated` (10/мин), сообщение в чат — `throttle:chat-send` (30/мин).

## Telegram (бот администратора)

- `app/Services/TelegramService.php` — `sendMessage` через Bot API; алерты идут асинхронно через `SendTelegramAlert`.
- Настройка — `/admin → Настройки`: **bot token** + **admin chat ID**, кнопка «Тест Telegram».

### Как узнать Admin chat ID
1. Создайте бота у **@BotFather** → получите token.
2. **Откройте своего бота и нажмите Start** (бот не может писать первым).
3. Самый простой способ узнать ID — написать боту **@userinfobot** (вернёт ваш numeric Id).
4. Точный способ: открыть `https://api.telegram.org/bot<TOKEN>/getUpdates` и найти `"chat":{"id":...}`.
5. Для группы: добавить бота в группу, написать сообщение, тот же `getUpdates` → `chat.id` будет **отрицательным**.

## Яндекс OAuth

- Портал: `config/services.php` (`yandex`), Redirect URI `http://placeo.ru/auth/yandex/callback`.
- Виджет: дополнительный Redirect URI `http://placeo.ru/widget/oauth/yandex/callback`.
- Scope задаётся **доступами в самом OAuth-приложении** (не в коде). Подробнее — [auth.md](auth.md), [widget.md](widget.md).

## Карты (Leaflet + OpenStreetMap)

- Тайлы OSM, reverse-geocoding **Nominatim** (бесплатно, без ключа). Настройки — `config/placeo.php` (`nominatim_url`, `nominatim_email`).
- Используется: выбор адреса при подаче/правке (`addressMap`, с автоопределением города из адреса), режим «на карте» в листинге (`feedMap`), карта на карточке объявления (zoom колесом — только после клика).
