Initial commit - Last War messaging system
This commit is contained in:
220
process_queue.php
Executable file
220
process_queue.php
Executable file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/includes/db.php';
|
||||
require_once __DIR__ . '/common/helpers/sender_factory.php';
|
||||
require_once __DIR__ . '/common/helpers/converter_factory.php';
|
||||
require_once __DIR__ . '/includes/schedule_helpers.php';
|
||||
|
||||
use Common\Helpers\SenderFactory;
|
||||
use Common\Helpers\ConverterFactory;
|
||||
|
||||
define('DAEMON_MODE', php_sapi_name() === 'cli' && !isset($_GET['run']));
|
||||
define('SLEEP_INTERVAL', 5);
|
||||
|
||||
function getTranslationButtons(PDO $pdo, string $text): array
|
||||
{
|
||||
$stmt = $pdo->query("SELECT language_code, flag_emoji FROM supported_languages WHERE is_active = 1");
|
||||
$languages = $stmt->fetchAll();
|
||||
|
||||
if (count($languages) <= 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'telegram' => buildTelegramTranslationButtons($pdo, $languages, $text),
|
||||
'discord' => buildDiscordTranslationButtons($languages, $text)
|
||||
];
|
||||
}
|
||||
|
||||
function buildTelegramTranslationButtons(PDO $pdo, array $languages, string $text): array
|
||||
{
|
||||
if (count($languages) <= 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Guardar texto en la base de datos con hash consistente
|
||||
$textHash = md5($text);
|
||||
$stmt = $pdo->prepare("INSERT INTO translation_cache (text_hash, original_text) VALUES (?, ?) ON DUPLICATE KEY UPDATE original_text = VALUES(original_text)");
|
||||
$stmt->execute([$textHash, $text]);
|
||||
|
||||
$buttons = [];
|
||||
|
||||
foreach ($languages as $lang) {
|
||||
$buttons[] = [
|
||||
'text' => $lang['flag_emoji'] . ' ' . strtoupper($lang['language_code']),
|
||||
'callback_data' => 'translate:' . $lang['language_code'] . ':' . $textHash
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'inline_keyboard' => array_chunk($buttons, 3)
|
||||
];
|
||||
}
|
||||
|
||||
function buildDiscordTranslationButtons(array $languages, string $text): array
|
||||
{
|
||||
$buttons = [];
|
||||
|
||||
$textHash = md5($text);
|
||||
|
||||
foreach ($languages as $lang) {
|
||||
$buttons[] = [
|
||||
'label' => $lang['flag_emoji'] . ' ' . strtoupper($lang['language_code']),
|
||||
'custom_id' => 'translate_' . $lang['language_code'] . ':' . $textHash,
|
||||
'style' => 1
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
[
|
||||
'type' => 1,
|
||||
'components' => array_slice($buttons, 0, 5)
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
function processScheduledMessages(): array
|
||||
{
|
||||
$pdo = getDbConnection();
|
||||
|
||||
$stmt = $pdo->query("SELECT NOW() as now");
|
||||
$now = $stmt->fetch()['now'];
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT s.*, m.content, r.platform_id, r.platform, r.name as recipient_name
|
||||
FROM schedules s
|
||||
JOIN messages m ON s.message_id = m.id
|
||||
JOIN recipients r ON s.recipient_id = r.id
|
||||
WHERE s.status = 'pending'
|
||||
AND s.send_time <= ?
|
||||
ORDER BY s.send_time ASC
|
||||
LIMIT 50
|
||||
");
|
||||
$stmt->execute([$now]);
|
||||
$schedules = $stmt->fetchAll();
|
||||
|
||||
$results = ['processed' => 0, 'sent' => 0, 'failed' => 0];
|
||||
|
||||
foreach ($schedules as $schedule) {
|
||||
$stmt = $pdo->prepare("UPDATE schedules SET status = 'processing' WHERE id = ?");
|
||||
$stmt->execute([$schedule['id']]);
|
||||
|
||||
try {
|
||||
$sender = SenderFactory::create($schedule['platform']);
|
||||
|
||||
// Obtener botones de traducción (convertir HTML a texto plano)
|
||||
$plainText = html_entity_decode(strip_tags($schedule['content']), ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
$plainText = preg_replace('/\s+/', ' ', $plainText);
|
||||
$translationButtons = getTranslationButtons($pdo, $plainText);
|
||||
|
||||
// Parsear el contenido HTML en segmentos manteniendo el orden
|
||||
$segments = $sender->parseContent($schedule['content']);
|
||||
|
||||
$messageCount = 0;
|
||||
|
||||
// Enviar cada segmento en el orden correcto
|
||||
foreach ($segments as $segment) {
|
||||
if ($segment['type'] === 'text') {
|
||||
// Convertir el texto al formato de la plataforma
|
||||
$textContent = ConverterFactory::convert($schedule['platform'], $segment['content']);
|
||||
|
||||
if (!empty(trim($textContent))) {
|
||||
// Agregar botones de traducción al último segmento de texto
|
||||
$buttons = null;
|
||||
if ($segment === end($segments)) {
|
||||
$buttons = $schedule['platform'] === 'telegram'
|
||||
? $translationButtons['telegram']
|
||||
: $translationButtons['discord'];
|
||||
}
|
||||
|
||||
if ($schedule['platform'] === 'telegram') {
|
||||
$sender->sendMessage($schedule['platform_id'], $textContent, $buttons);
|
||||
} else {
|
||||
$sender->sendMessage($schedule['platform_id'], $textContent, null, $buttons);
|
||||
}
|
||||
$messageCount++;
|
||||
}
|
||||
} elseif ($segment['type'] === 'image') {
|
||||
$imagePath = $segment['src'];
|
||||
|
||||
// Quitar parámetros de URL si los hay
|
||||
$imgPath = parse_url($imagePath, PHP_URL_PATH) ?: $imagePath;
|
||||
|
||||
if (file_exists($imgPath)) {
|
||||
// Es un archivo local
|
||||
$sender->sendMessageWithAttachments($schedule['platform_id'], '', [$imgPath]);
|
||||
$messageCount++;
|
||||
} elseif (strpos($imagePath, 'http') === 0) {
|
||||
// Es una URL remota
|
||||
$embed = ['image' => ['url' => $imagePath]];
|
||||
$sender->sendMessage($schedule['platform_id'], '', $embed);
|
||||
$messageCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO sent_messages (schedule_id, recipient_id, platform_message_id, message_count, sent_at)
|
||||
VALUES (?, ?, ?, ?, NOW())
|
||||
");
|
||||
$stmt->execute([$schedule['id'], $schedule['recipient_id'], '', $messageCount]);
|
||||
|
||||
if ($schedule['is_recurring']) {
|
||||
$nextTime = calculateNextSendTime($schedule['recurring_days'], $schedule['recurring_time']);
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO schedules (message_id, recipient_id, send_time, status, is_recurring, recurring_days, recurring_time, created_at)
|
||||
VALUES (?, ?, ?, 'pending', 1, ?, ?, NOW())
|
||||
");
|
||||
$stmt->execute([
|
||||
$schedule['message_id'],
|
||||
$schedule['recipient_id'],
|
||||
$nextTime,
|
||||
$schedule['recurring_days'],
|
||||
$schedule['recurring_time']
|
||||
]);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE schedules SET status = 'sent', sent_at = NOW() WHERE id = ?");
|
||||
$stmt->execute([$schedule['id']]);
|
||||
|
||||
$results['sent']++;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$stmt = $pdo->prepare("UPDATE schedules SET status = 'failed', error_message = ? WHERE id = ?");
|
||||
$stmt->execute([$e->getMessage(), $schedule['id']]);
|
||||
|
||||
$results['failed'];
|
||||
}
|
||||
|
||||
$results['processed']++;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function logMessage(string $message): void
|
||||
{
|
||||
echo "[" . date('Y-m-d H:i:s') . "] " . $message . PHP_EOL;
|
||||
}
|
||||
|
||||
if (DAEMON_MODE) {
|
||||
logMessage("Process Queue Worker started");
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
$results = processScheduledMessages();
|
||||
|
||||
if ($results['processed'] > 0) {
|
||||
logMessage("Processed: {$results['processed']}, Sent: {$results['sent']}, Failed: {$results['failed']}");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
logMessage("Error: " . $e->getMessage());
|
||||
}
|
||||
|
||||
sleep(SLEEP_INTERVAL);
|
||||
}
|
||||
} else {
|
||||
$results = processScheduledMessages();
|
||||
echo "Processed: {$results['processed']}, Sent: {$results['sent']}, Failed: {$results['failed']}\n";
|
||||
}
|
||||
Reference in New Issue
Block a user