PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); function telegramWebhookRespond(array $payload, int $statusCode = 200): never { http_response_code($statusCode); header('Content-Type: application/json; charset=utf-8'); echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } function telegramSendBotMessage(array $telegramConfig, string $chatId, string $messageText): void { $botToken = trim((string) ($telegramConfig['bot_token'] ?? '')); if ($botToken === '' || $chatId === '' || $messageText === '') { return; } telegramHttpPostJson( 'https://api.telegram.org/bot' . $botToken . '/sendMessage', [ 'chat_id' => $chatId, 'text' => appendTelegramServiceFooter($messageText), ] ); } $expectedSecret = trim((string) ($telegramConfig['webhook_secret'] ?? '')); if ($expectedSecret !== '') { $providedSecret = (string) ($_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] ?? ''); if (!hash_equals($expectedSecret, $providedSecret)) { telegramWebhookRespond(['ok' => false, 'error' => 'invalid_secret'], 403); } } $rawBody = file_get_contents('php://input'); $update = json_decode((string) $rawBody, true); if (!is_array($update)) { telegramWebhookRespond(['ok' => false, 'error' => 'invalid_json'], 400); } $message = $update['message'] ?? $update['edited_message'] ?? null; if (!is_array($message)) { telegramWebhookRespond(['ok' => true, 'status' => 'ignored_no_message']); } $chatId = isset($message['chat']['id']) ? (string) $message['chat']['id'] : ''; $telegramUsername = trim((string) ($message['from']['username'] ?? '')); $text = trim((string) ($message['text'] ?? '')); if ($chatId === '' || $text === '') { telegramWebhookRespond(['ok' => true, 'status' => 'ignored_missing_data']); } $token = null; if (preg_match('/^\/start\s+connect_([A-Fa-f0-9]{32,128})$/', $text, $matches)) { $token = strtolower($matches[1]); } elseif (preg_match('/^connect_([A-Fa-f0-9]{32,128})$/', $text, $matches)) { $token = strtolower($matches[1]); } if ($token === null) { telegramWebhookRespond(['ok' => true, 'status' => 'ignored_no_connect_token']); } $stmtUser = $pdo->prepare(" SELECT `id` FROM `app_users` WHERE `telegram_link_token` = :token AND `telegram_link_token_expires_at` IS NOT NULL AND `telegram_link_token_expires_at` > NOW() LIMIT 1 "); $stmtUser->execute([':token' => $token]); $user = $stmtUser->fetch(); if (!$user) { telegramWebhookRespond(['ok' => true, 'status' => 'token_not_found_or_expired']); } $stmtUpdate = $pdo->prepare(" UPDATE `app_users` SET `telegram_username` = :telegram_username, `telegram_chat_id` = :telegram_chat_id, `telegram_connected_at` = NOW(), `telegram_link_token` = NULL, `telegram_link_token_expires_at` = NULL, `updated_at` = NOW() WHERE `id` = :id "); $stmtUpdate->execute([ ':telegram_username' => $telegramUsername !== '' ? $telegramUsername : null, ':telegram_chat_id' => $chatId, ':id' => (int) $user['id'], ]); $welcomeName = $telegramUsername !== '' ? '@' . ltrim($telegramUsername, '@') : 'bei Telegram'; $welcomeMessage = implode("\n", [ 'Willkommen bei SkyView.', '', 'Dein Telegram-Konto wurde erfolgreich mit deinem SkyView-Benutzer verbunden.', 'Du kannst jetzt spaeter Hinweise und Inhalte direkt vom Bot erhalten.', '', 'Verbunden als: ' . $welcomeName, ]); telegramSendBotMessage($telegramConfig, $chatId, $welcomeMessage); telegramWebhookRespond([ 'ok' => true, 'status' => 'connected', 'user_id' => (int) $user['id'], ]);