112 lines
4.7 KiB
PHP
Executable File
112 lines
4.7 KiB
PHP
Executable File
<?php
|
|
namespace App\Services\Catalog;
|
|
|
|
use App\Models\ProductOffer;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
use RuntimeException;
|
|
|
|
class TelegramOffersPublisher
|
|
{
|
|
/** @return array<string, mixed> */
|
|
public function publishOffer(ProductOffer $offer, ?string $chatId = null, bool $dryRun = false): array
|
|
{
|
|
$token = trim((string) config('services.telegram.offers_bot_token', ''));
|
|
$chatId = trim((string) ($chatId ?: config('services.telegram.offers_chat_id', '')));
|
|
$channelName = trim((string) config('services.telegram.offers_channel_name', ''));
|
|
$message = $this->buildMessage($offer);
|
|
$imageUrl = $this->resolveImageUrl($offer);
|
|
|
|
if ($dryRun) {
|
|
return [
|
|
'ok' => true,
|
|
'dry_run' => true,
|
|
'chat_id' => $chatId,
|
|
'channel_name' => $channelName,
|
|
'image_url' => $imageUrl,
|
|
'message' => $message,
|
|
'offer_id' => (int) $offer->id,
|
|
];
|
|
}
|
|
|
|
if ($token === '') {
|
|
throw new RuntimeException('TELEGRAM_OFFERS_BOT_TOKEN non configurato.');
|
|
}
|
|
|
|
if ($chatId === '') {
|
|
throw new RuntimeException('TELEGRAM_OFFERS_CHAT_ID non configurato.');
|
|
}
|
|
|
|
$baseUrl = 'https://api.telegram.org/bot' . $token;
|
|
$response = null;
|
|
$usedMethod = 'sendMessage';
|
|
|
|
if ($imageUrl !== null) {
|
|
$response = Http::asForm()->post($baseUrl . '/sendPhoto', [
|
|
'chat_id' => $chatId,
|
|
'photo' => $imageUrl,
|
|
'caption' => Str::limit($message, 1024, ''),
|
|
]);
|
|
$usedMethod = 'sendPhoto';
|
|
}
|
|
|
|
if (! $response || ! $response->ok()) {
|
|
$response = Http::asForm()->post($baseUrl . '/sendMessage', [
|
|
'chat_id' => $chatId,
|
|
'text' => $message,
|
|
'disable_web_page_preview' => false,
|
|
]);
|
|
$usedMethod = 'sendMessage';
|
|
}
|
|
|
|
return [
|
|
'ok' => $response->ok(),
|
|
'dry_run' => false,
|
|
'chat_id' => $chatId,
|
|
'channel_name' => $channelName,
|
|
'method' => $usedMethod,
|
|
'image_url' => $imageUrl,
|
|
'offer_id' => (int) $offer->id,
|
|
'status' => $response->status(),
|
|
'response' => $response->json(),
|
|
'message' => $message,
|
|
];
|
|
}
|
|
|
|
private function buildMessage(ProductOffer $offer): string
|
|
{
|
|
$payload = is_array($offer->meta['payload'] ?? null) ? $offer->meta['payload'] : [];
|
|
$product = $offer->product;
|
|
|
|
$lines = array_values(array_filter([
|
|
'Offerta Amazon NetGescon',
|
|
trim((string) ($offer->title ?: $product?->name ?: 'Prodotto Amazon')),
|
|
trim((string) ($product?->internal_code ?? '')) !== '' ? 'Catalogo: ' . trim((string) $product?->internal_code) : null,
|
|
$this->formatMoney($offer->price_amount, (string) ($offer->currency ?: data_get($payload, 'currency', 'EUR')), 'Prezzo'),
|
|
$this->formatMoney($offer->price_compare_at, (string) ($offer->currency ?: data_get($payload, 'currency', 'EUR')), 'Listino'),
|
|
trim((string) ($offer->availability ?: data_get($payload, 'availability', ''))) !== '' ? 'Disponibilita: ' . trim((string) ($offer->availability ?: data_get($payload, 'availability', ''))): null,
|
|
trim((string) data_get($payload, 'asin', $offer->external_product_id)) !== '' ? 'ASIN: ' . trim((string) data_get($payload, 'asin', $offer->external_product_id)) : null,
|
|
trim((string) ($offer->referral_url ?: data_get($payload, 'referral_url', ''))) !== '' ? 'Apri offerta: ' . trim((string) ($offer->referral_url ?: data_get($payload, 'referral_url', ''))): null,
|
|
], static fn(?string $line): bool => is_string($line) && trim($line) !== ''));
|
|
|
|
return implode(PHP_EOL, $lines);
|
|
}
|
|
|
|
private function resolveImageUrl(ProductOffer $offer): ?string
|
|
{
|
|
$payload = is_array($offer->meta['payload'] ?? null) ? $offer->meta['payload'] : [];
|
|
$imageUrl = trim((string) data_get($payload, 'image_url', ''));
|
|
|
|
return $imageUrl !== '' && str_starts_with($imageUrl, 'http') ? $imageUrl : null;
|
|
}
|
|
|
|
private function formatMoney(mixed $amount, string $currency, string $label): ?string
|
|
{
|
|
if (! is_numeric($amount)) {
|
|
return null;
|
|
}
|
|
|
|
return $label . ': ' . number_format((float) $amount, 2, ',', '.') . ' ' . strtoupper(trim($currency) !== '' ? $currency : 'EUR');
|
|
}
|
|
}
|