netgescon-day0/app/Console/Commands/PublishTelegramOfferCommand.php

94 lines
3.1 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use App\Models\ProductOffer;
use App\Services\Catalog\TelegramOffersPublisher;
use Illuminate\Console\Command;
use RuntimeException;
class PublishTelegramOfferCommand extends Command
{
protected $signature = 'offers:publish-telegram
{offer : ID offerta oppure internal_code prodotto oppure ASIN}
{--chat= : Chat ID o @channel alternativo}
{--dry-run : Costruisce il payload senza inviare a Telegram}';
protected $description = 'Pubblica una offerta Amazon del catalogo NetGescon sul canale Telegram configurato.';
public function handle(TelegramOffersPublisher $publisher): int
{
$offer = $this->resolveOffer((string) $this->argument('offer'));
if (! $offer instanceof ProductOffer) {
$this->error('Offerta Amazon non trovata.');
return self::FAILURE;
}
try {
$result = $publisher->publishOffer(
$offer->loadMissing('product'),
trim((string) $this->option('chat')),
(bool) $this->option('dry-run')
);
} catch (RuntimeException $e) {
$this->error($e->getMessage());
return self::FAILURE;
}
$this->table(
['Campo', 'Valore'],
[
['Offer ID', (string) $offer->id],
['Prodotto', trim((string) ($offer->product?->internal_code ?? '')) . ' · ' . trim((string) ($offer->title ?: $offer->product?->name ?: 'Prodotto Amazon'))],
['Dry run', ! empty($result['dry_run']) ? 'si' : 'no'],
['Chat', (string) ($result['chat_id'] ?? '')],
['Canale', (string) ($result['channel_name'] ?? '')],
['Metodo', (string) ($result['method'] ?? 'preview')],
['Esito', ! empty($result['ok']) ? 'ok' : 'errore'],
['Immagine', (string) ($result['image_url'] ?? '')],
]
);
$this->line('');
$this->line((string) ($result['message'] ?? ''));
if (empty($result['ok'])) {
$this->line('');
$this->line(json_encode($result['response'] ?? [], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) ?: '{}');
return self::FAILURE;
}
return self::SUCCESS;
}
private function resolveOffer(string $value): ?ProductOffer
{
$value = trim($value);
if ($value === '') {
return null;
}
$query = ProductOffer::query()
->with('product')
->where('source_type', 'amazon_creators_api')
->latest('last_seen_at')
->latest('id');
if (is_numeric($value)) {
$offer = (clone $query)->find((int) $value);
if ($offer instanceof ProductOffer) {
return $offer;
}
}
return (clone $query)
->where('external_product_id', $value)
->orWhereHas('product', static function ($productQuery) use ($value): void {
$productQuery->where('internal_code', $value);
})
->first();
}
}