From cc8fbe2487db7ee3b4a6cf4b93b220a243604c86 Mon Sep 17 00:00:00 2001 From: t1amak Date: Fri, 30 May 2025 21:21:35 +0000 Subject: [PATCH] improved user recognition, commands handler fix --- salvium_tipbot.php | 17 +++++- src/salvium_tipbot_commands.php | 98 +++++++++------------------------ src/salvium_tipbot_db.php | 63 +++++++++++++++++++++ 3 files changed, 105 insertions(+), 73 deletions(-) diff --git a/salvium_tipbot.php b/salvium_tipbot.php index 2407c3d..f142b1b 100755 --- a/salvium_tipbot.php +++ b/salvium_tipbot.php @@ -21,8 +21,21 @@ $update = json_decode(file_get_contents("php://input"), true); if (!$update || !isset($update['message'])) exit; $message = $update['message']; -$args = explode(' ', trim($message['text'] ?? '')); -$command = strtolower($args[0] ?? ''); +//$args = explode(' ', trim($message['text'] ?? '')); +//$command = strtolower($args[0] ?? ''); + + +$text = trim($message['text'] ?? ''); +if (!str_starts_with($text, '/')) exit; // Only react to messages that start with '/' + +$args = explode(' ', $text); +$command = strtolower($args[0]); + +// Strip optional @BotUsername (Telegram adds this in groups) +if (str_contains($command, '@')) { + $command = explode('@', $command)[0]; +} + $context = [ 'chat_id' => $message['chat']['id'], diff --git a/src/salvium_tipbot_commands.php b/src/salvium_tipbot_commands.php index 0885944..b6a4227 100644 --- a/src/salvium_tipbot_commands.php +++ b/src/salvium_tipbot_commands.php @@ -45,18 +45,12 @@ class SalviumTipBotCommands { } private function cmd_start(array $args, array $ctx): string { - $user = $this->db->getUserByTelegramId($ctx['user_id']); - - if (!$user) { - $sub = $this->wallet->getNewSubaddress(); - if ($sub) { - $this->db->createUser($ctx['user_id'], $sub); - - if (!empty($ctx['username'])) { - $this->db->updateUsername($ctx['user_id'], $ctx['username']); - } - } - } + $this->db->ensureUserExists( + $ctx['user_id'], + $ctx['username'] ?? null, + fn() => $this->wallet->getNewSubaddress(), + false + ); return "👋 Welcome to the Salvium Tip Bot!\n\n" . "You can use the following commands:\n" @@ -69,33 +63,12 @@ class SalviumTipBotCommands { } private function cmd_deposit(array $args, array $ctx): string { - $user = $this->db->getUserByTelegramId($ctx['user_id']); - - // If no exact match, attempt upgrade by matching username with placeholder - if (!$user && !empty($ctx['username'])) { - $user = $this->db->getUserByUsername($ctx['username']); - - // Check if it's a placeholder user (telegram_user_id is synthetic) - if ($user && $user['telegram_user_id'] < 1000000) { - // Upgrade the telegram_user_id to the real one - $this->db->upgradeTelegramUserId($user['telegram_user_id'], $ctx['user_id']); - // Refresh user - $user = $this->db->getUserByTelegramId($ctx['user_id']); - } - } - - // If still not found, create new user - if (!$user) { - $sub = $this->wallet->getNewSubaddress(); - if (!$sub) return "Error generating subaddress."; - $this->db->createUser($ctx['user_id'], $sub); - - if (!empty($ctx['username'])) { - $this->db->updateUsername($ctx['user_id'], $ctx['username']); - } - - return "Your deposit address: $sub"; - } + $user = $this->db->ensureUserExists( + $ctx['user_id'], + $ctx['username'] ?? null, + fn() => $this->wallet->getNewSubaddress(), + false + ); return "Your deposit address: {$user['salvium_subaddress']}"; } @@ -143,32 +116,24 @@ class SalviumTipBotCommands { } $cleanUsername = ltrim($targetUsername, '@'); - $recipient = $this->db->getUserByUsername($cleanUsername); - // If recipient not known, create placeholder + $recipient = $this->db->ensureUserExists( + 0, + $cleanUsername, + fn() => $this->wallet->getNewSubaddress(), + true + ); if (!$recipient) { - $syntheticId = 100000 + (crc32($cleanUsername) % 900000); - $subaddress = $this->wallet->getNewSubaddress(); - if (!$subaddress) { - return "Failed to create deposit address for {$cleanUsername}."; - } + return "Failed to ensure recipient exists."; + } - $existing = $this->db->getUserByTelegramId($syntheticId); + $this->db->updateUserTipBalance($sender['id'], $amount, 'subtract'); + $this->db->addTip($sender['id'], $recipient['id'], $amount, $ctx['chat_id']); - if (!$existing) { - if (!$this->db->createUser($syntheticId, $subaddress)) { - return "Failed to create recipient account for {$cleanUsername}."; - } - } - - // Ensure username is correct (could be NULL in DB even if user exists) - $this->db->updateUsername($syntheticId, $cleanUsername); - - // Now safely fetch the recipient - $recipient = $this->db->getUserByUsername($cleanUsername); - - // Notify group + if (!empty($recipient['telegram_user_id']) && $recipient['telegram_user_id'] > 0 && $recipient['telegram_user_id'] !== (100_000 + (crc32($cleanUsername) % 900_000))) { + sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} SAL! Use /balance to check."); + } else { sendMessage($ctx['chat_id'], "Hey @$cleanUsername, you just got a tip from @$ctx[username]!"); sendGif( $ctx['chat_id'], @@ -177,30 +142,21 @@ class SalviumTipBotCommands { ); } - - $this->db->updateUserTipBalance($sender['id'], $amount, 'subtract'); - $this->db->addTip($sender['id'], $recipient['id'], $amount, $ctx['chat_id']); - - if (!empty($recipient['telegram_user_id']) && $recipient['telegram_user_id'] > 0 && $recipient['telegram_user_id'] != crc32($cleanUsername)) { - sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} SAL! Use /balance to check."); - } - return "Tipped {$targetUsername} {$amount} SAL successfully!"; } + private function cmd_claim(array $args, array $ctx): string { $user = $this->db->getUserByUsername($ctx['username']); - if (!$user || $user['telegram_user_id'] > 1000000) { + if (!$user || $user['telegram_user_id'] > 1_000_000) { return "Nothing to claim or already claimed."; } - // Upgrade placeholder to real user ID $this->db->upgradeTelegramUserId($user['telegram_user_id'], $ctx['user_id']); return "Welcome @{$ctx['username']}, your account has been activated. You can now check your balance and receive tips!"; } - } ?> diff --git a/src/salvium_tipbot_db.php b/src/salvium_tipbot_db.php index fbbaff9..9b6f1ba 100755 --- a/src/salvium_tipbot_db.php +++ b/src/salvium_tipbot_db.php @@ -89,10 +89,22 @@ class SalviumTipBotDB { } public function updateUsername(int $telegramUserId, string $username): void { + // First, check if the username is already used by a different user + $stmt = $this->pdo->prepare("SELECT telegram_user_id FROM users WHERE username = ?"); + $stmt->execute([$username]); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($row && (int)$row['telegram_user_id'] !== $telegramUserId) { + // Username is used by another user, don't overwrite + return; + } + + // Safe to update $stmt = $this->pdo->prepare("UPDATE users SET username = ? WHERE telegram_user_id = ?"); $stmt->execute([$username, $telegramUserId]); } + public function upgradeTelegramUserId(int $oldId, int $newId): bool { $stmt = $this->pdo->prepare("UPDATE users SET telegram_user_id = ? WHERE telegram_user_id = ?"); return $stmt->execute([$newId, $oldId]); @@ -109,6 +121,57 @@ class SalviumTipBotDB { return $stmt->execute([$telegramUserId, $subaddress]); } + public function ensureUserExists( + int $telegramId, + ?string $username, + callable $subaddressGenerator, + bool $allowSynthetic = false + ): array { + // 1. Try exact match by Telegram ID + $user = $this->getUserByTelegramId($telegramId); + + // 2. Try upgrade from placeholder if matching username + if (!$user && $username) { + $placeholder = $this->getUserByUsername($username); + + if ($placeholder && $placeholder['telegram_user_id'] < 1_000_000 && $telegramId !== 0) { + $this->upgradeTelegramUserId($placeholder['telegram_user_id'], $telegramId); + $user = $this->getUserByTelegramId($telegramId); + } + else if ($placeholder && $placeholder['telegram_user_id'] >= 1_000_000 && $telegramId === 0) { + $user = $this->getUserByTelegramId($placeholder['telegram_user_id']); + } + + } + + + // 3. Still not found? Possibly create new user + if (!$user) { + $idToUse = $telegramId; + + if ($telegramId === 0 && $username && $allowSynthetic) { + // Create synthetic ID + $clean = ltrim($username, '@'); + $idToUse = 100_000 + (crc32($clean) % 900_000); + } + + $existing = $this->getUserByTelegramId($idToUse); + if (!$existing) { + $sub = $subaddressGenerator(); + if (!$sub) throw new RuntimeException("Failed to generate subaddress"); + $this->createUser($idToUse, $sub); + } + + if ($username) { + $this->updateUsername($idToUse, $username); + } + + $user = $this->getUserByTelegramId($idToUse); + } + + return $user; + } + public function updateUserTipBalance(int $userId, float $amount, string $operation = 'add'): bool { $sql = $operation === 'add' ? "UPDATE users SET tip_balance = tip_balance + ? WHERE id = ?" : "UPDATE users SET tip_balance = tip_balance - ? WHERE id = ?"; $stmt = $this->pdo->prepare($sql);