Files
backPRO/docs/CRON.md
Jacek Pyziak b2aead1fbe feat: Integrate DataForSEO for indexed pages tracking
- Updated CRON documentation to include DataForSEO metrics synchronization.
- Enhanced SettingsController to manage DataForSEO API credentials and settings.
- Modified SiteController to handle DataForSEO domain input.
- Updated Site model to accommodate DataForSEO data handling.
- Added methods in SiteSeoMetric model for DataForSEO data retrieval and validation.
- Implemented SiteSeoSyncService to synchronize SEO metrics from both SEMSTORM and DataForSEO.
- Enhanced dashboard templates to display indexed pages data.
- Updated settings and site creation/edit templates to include DataForSEO fields.
- Created migration for adding DataForSEO related columns in the database.
- Developed DataForSeoService to fetch indexed pages count from DataForSEO API.
2026-02-21 11:41:17 +01:00

134 lines
4.8 KiB
Markdown

# BackPRO - Konfiguracja CRON
## Opis
Skrypt `cron/publish.php` jest uruchamiany automatycznie co godzinę przez CRON serwera. Odpowiada za sprawdzenie, czy któraś ze stron wymaga nowej publikacji, i jeśli tak - generuje artykuł z obrazkiem i publikuje go na WordPressie.
## Algorytm działania
```
1. Załaduj konfigurację (.env) i autoloader (vendor/autoload.php)
2. Pobierz wszystkie aktywne strony (is_active = 1)
3. Filtruj: zostaw strony, gdzie:
- last_published_at IS NULL (nigdy nie publikowano)
- LUB NOW() - last_published_at >= publish_interval_days dni
4. Sortuj po last_published_at ASC (NULL first = najwyższy priorytet)
5. Weź PIERWSZĄ stronę z listy (tylko jedna publikacja na uruchomienie)
6. TopicBalancer → wybierz temat z najmniejszą liczbą artykułów
7. Pobierz ostatnie 20 tytułów artykułów z tego tematu
8. OpenAIService → wygeneruj artykuł (prompt zawiera istniejące tytuły)
9. ImageService → wygeneruj/pobierz obrazek
10. WordPressService → upload obrazka jako media
11. WordPressService → utwórz post z featured image i kategorią
12. Zapisz artykuł w bazie (tabela articles, status=published)
13. Zaktualizuj topics.article_count (+1)
14. Zaktualizuj sites.last_published_at = NOW()
15. Zaloguj wynik do storage/logs/publish_YYYY-MM-DD.log
```
**Ważne:** Skrypt publikuje MAKSYMALNIE 1 artykuł na uruchomienie. Dzięki temu:
- Nie obciążamy API zbyt wieloma zapytaniami naraz
- Mamy lepszą kontrolę nad tempem publikacji
- W razie błędu tracimy tylko 1 artykuł, nie całą partię
## Konfiguracja CRON na Hostido
### Panel DirectAdmin / cPanel
W panelu hostingu dodaj zadanie CRON:
```
# Co godzinę (minuta 0 każdej godziny)
0 * * * * /usr/bin/php /home/username/public_html/cron/publish.php >> /home/username/public_html/storage/logs/cron.log 2>&1
```
Lub jeśli dostępny jest `php` w PATH:
```
0 * * * * php /home/username/public_html/cron/publish.php >> /home/username/public_html/storage/logs/cron.log 2>&1
```
### Alternatywne interwały
```
# Co 2 godziny
0 */2 * * * php /path/to/cron/publish.php
# Co 6 godzin
0 */6 * * * php /path/to/cron/publish.php
# Raz dziennie o 8:00
0 8 * * * php /path/to/cron/publish.php
# Dwa razy dziennie (8:00 i 20:00)
0 8,20 * * * php /path/to/cron/publish.php
```
## Zabezpieczenia
### Blokada dostępu HTTP
Plik `cron/.htaccess`:
```apache
Deny from all
```
Skrypty CRON są uruchamiane z linii komend (CLI), nie przez HTTP.
### Blokada wielokrotnego uruchomienia
Skrypt używa pliku lockfile (`storage/logs/publish.lock`):
- Na początku sprawdza czy lockfile istnieje
- Jeśli tak i nie jest starszy niż 30 minut → kończy działanie (inny proces w toku)
- Jeśli nie → tworzy lockfile
- Na końcu (lub w razie błędu) → usuwa lockfile
## Logowanie
Logi zapisywane w `storage/logs/publish_YYYY-MM-DD.log`:
```
[2026-02-15 10:00:01] INFO: Rozpoczynam publikację
[2026-02-15 10:00:01] INFO: Wybrano stronę: example.com (ID: 3)
[2026-02-15 10:00:01] INFO: Wybrany temat: Ogrodnictwo (ID: 7)
[2026-02-15 10:00:05] INFO: Wygenerowano artykuł: "10 roślin idealnych na balkon"
[2026-02-15 10:00:08] INFO: Wygenerowano obrazek (Freepik)
[2026-02-15 10:00:10] INFO: Upload mediów na WP: media_id=142
[2026-02-15 10:00:12] INFO: Opublikowano post: wp_post_id=523
[2026-02-15 10:00:12] INFO: Zakończono pomyślnie
```
## Ręczne uruchomienie
### Z linii komend
```bash
php /path/to/cron/publish.php
```
### Z panelu BackPRO
Przycisk "Opublikuj teraz" na dashboardzie wywołuje `PublishController@run`, który uruchamia ten sam proces co CRON, ale synchronicznie z poziomu przeglądarki.
## Monitoring
### Sprawdzanie statusu
- Dashboard BackPRO pokazuje datę ostatniej publikacji dla każdej strony
- Lista artykułów z filtrem po statusie (published/failed)
- Logi w `storage/logs/`
### Typowe problemy
| Problem | Przyczyna | Rozwiązanie |
|---------|-----------|-------------|
| Brak publikacji | CRON nie uruchomiony | Sprawdź konfigurację CRON w panelu |
| Status: failed | Błąd API | Sprawdź error_message w artykule i logi |
| Lockfile blokuje | Poprzedni proces nie zakończył się | Usuń `storage/logs/publish.lock` |
| 401 z WordPress | Złe dane API | Sprawdź api_user/api_token w konfiguracji strony |
| 429 z OpenAI | Rate limit | Zwiększ interwał CRON lub poczekaj |
## Miesieczna synchronizacja metryk SEO (SEMSTORM + DataForSEO)
Dodaj osobne zadanie CRON uruchamiane raz w miesiacu:
```bash
0 3 1 * * php /path/to/cron/semstorm.php >> /path/to/storage/logs/cron_semstorm.log 2>&1
```
Skrypt:
- pobiera aktywne strony (`sites.is_active = 1`),
- pobiera metryki z SEMSTORM dla domeny strony,
- pobiera liczbe zaindeksowanych stron (zapytanie `site:domena`) z DataForSEO,
- zapisuje dane do `site_seo_metrics` dla biezacego miesiaca,
- pomija rekord, jesli miesiac jest juz zapisany (idempotencja).