'error', 'message' => 'No input received.']); exit; } $update = json_decode($input, true); if (json_last_error() !== JSON_ERROR_NONE) { log_message("Webhook received invalid JSON: ".json_last_error_msg()." | Input: ".$input); http_response_code(400); echo json_encode(['status' => 'error', 'message' => 'Invalid JSON.']); exit; } if (isset($update['message']['message_id'])) { log_message("Update ID: {$update['update_id']}, Message ID: {$update['message']['message_id']}, Chat ID: {$update['message']['chat']['id']}, User ID: {$update['message']['from']['id']}, Text: ".($update['message']['text'] ?? "[no text]")); } elseif (isset($update['callback_query']['id'])) { log_message("Update ID: {$update['update_id']}, Callback Query ID: {$update['callback_query']['id']}, Chat ID: {$update['callback_query']['message']['chat']['id']}, User ID: {$update['callback_query']['from']['id']}, Data: ".($update['callback_query']['data'] ?? "[no data]")); } $telegramService = new TelegramService(); // สร้าง Database connection และ SelfRegistrationHandler $database = Database::getInstance(); $pdo = $database->getConnection(); $selfRegistrationHandler = new SelfRegistrationHandler($pdo, $telegramService); log_message("TelegramService and SelfRegistrationHandler initialized successfully"); /** * @param int $userId * @param int $chatId */ function getUserState(int $userId, int $chatId): ?string { $stateFile = __DIR__."/logs/user_{$userId}_chat_{$chatId}_state.txt"; if (file_exists($stateFile)) { return trim(file_get_contents($stateFile)); } return null; } /** * @param int $userId * @param int $chatId */ function clearUserStateWebhook(int $userId, int $chatId): void { $stateFile = __DIR__."/logs/user_{$userId}_chat_{$chatId}_state.txt"; if (file_exists($stateFile)) { if (unlink($stateFile)) { log_message("State file cleared by webhook_handler for user {$userId} chat {$chatId}: {$stateFile}"); } else { log_message("Failed to clear state file by webhook_handler for user {$userId} chat {$chatId}: {$stateFile}"); } } } if (isset($update['message'])) { $message = $update['message']; $chatId = $message['chat']['id']; $userId = $message['from']['id']; $firstName = $message['from']['first_name'] ?? 'User'; $text = $message['text'] ?? ''; $lowerText = strtolower($text); // ตรวจสอบสิทธิ์การเข้าใช้งาน $canAccess = $selfRegistrationHandler->canUserAccessBot($userId); log_message("Access check for user {$userId}: ".($canAccess ? "ALLOWED" : "DENIED")); if (!$canAccess) { $responseMsg = "❌ ขออภัย คุณยังไม่ได้รับอนุญาตให้ใช้บอทนี้\nการลงทะเบียนด้วยตัวเองถูกปิดใช้งาน กรุณาติดต่อผู้ดูแลระบบ"; $result = $telegramService->sendMessage($chatId, $responseMsg); log_message("Access denied response sent to user {$userId}. Result: ".json_encode($result)); exit; } // ตรวจสอบว่าอยู่ในกระบวนการลงทะเบียนหรือไม่ $registrationHandled = $selfRegistrationHandler->handleUserInput($chatId, $userId, $text); log_message("Registration handler result for user {$userId}: ".($registrationHandled ? "HANDLED" : "NOT_HANDLED")); if ($registrationHandled) { log_message("Registration process handled, exiting for user {$userId}"); exit; // หยุดการประมวลผลเมื่อจัดการกับกระบวนการลงทะเบียน } $userState = getUserState($userId, $chatId); $currentMode = 'leave'; if ($userState) { if (str_starts_with($userState, 'wfh_')) { $currentMode = 'wfh'; } } elseif ($lowerText === '/wfh') { $currentMode = 'wfh'; } if ($userState) { if (str_starts_with($userState, 'cancelReq_confirm_')) { $telegramService->sendMessage($chatId, "น้องลารอการยืนยันการยกเลิกจากปุ่มค่ะ กรุณากดปุ่มที่แสดงผลไปก่อนหน้านี้นะคะ หรือพิมพ์ /cancel เพื่อยกเลิกทั้งหมด"); } elseif (str_starts_with($userState, 'la_') || str_starts_with($userState, 'wfh_')) { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); clearUserStateWebhook($userId, $chatId); exit; } $leaveAppHandler = new LeaveApplicationHandler($telegramService, $chatId, $userId, $currentMode); if (str_starts_with($userState, 'la_expect_startDate_for_') || str_starts_with($userState, 'wfh_expect_startDate_for_')) { $leaveAppHandler->handleStartDateInput($userState, $text); } elseif (str_starts_with($userState, 'la_expect_endDate_for_') || str_starts_with($userState, 'wfh_expect_endDate_for_')) { $leaveAppHandler->handleEndDateInput($userState, $text); } elseif (str_starts_with($userState, 'la_expect_reason_for_') || str_starts_with($userState, 'wfh_expect_reason_for_')) { $leaveAppHandler->handleReasonInput($userState, $text); } elseif (str_starts_with($userState, 'la_confirm_') || str_starts_with($userState, 'wfh_confirm_')) { $telegramService->sendMessage($chatId, "น้องลารอการยืนยันการขอลา/WFH จากปุ่มค่ะ กรุณากดปุ่มที่แสดงผลไปก่อนหน้านี้นะคะ หรือพิมพ์ /cancel เพื่อยกเลิกทั้งหมด"); } else { log_message("Unhandled state '{$userState}' for user {$userId} with text input '{$text}'. No action taken."); } } else { log_message("Unknown state prefix for user {$userId}: '{$userState}'. No action taken."); } } // คำสั่งใหม่เมื่อไม่มี state ที่ active else if ($lowerText === '/ลา' || $lowerText === '/leave') { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); exit; } $leaveAppHandler = new LeaveApplicationHandler($telegramService, $chatId, $userId, 'leave'); $leaveAppHandler->initiateRequest(); } elseif ($lowerText === '/wfh') { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); exit; } $leaveAppHandler = new LeaveApplicationHandler($telegramService, $chatId, $userId, 'wfh'); $leaveAppHandler->initiateRequest(); } elseif ($lowerText === '/เช็คยอด' || $lowerText === '/balance' || $lowerText === '/checkbalance') { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); exit; } $balanceHandler = new BalanceCheckHandler($telegramService, $chatId, $userId); $balanceHandler->showBalances(); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/ยกเลิกคำขอ' || $lowerText === '/cancelrequest') { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); exit; } $cancelHandler = new CancelRequestHandler($telegramService, $chatId, $userId); $cancelHandler->startCancellationProcess(); } elseif ($lowerText === '/สรุปวันนี้' || $lowerText === '/whosout') { // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->sendMessage($chatId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register"); exit; } $hrHandler = new HrSummaryHandler($telegramService, $chatId, $userId); $hrHandler->showTodaysAbsences(); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/start') { log_message("Processing /start command for user {$userId}"); $stmt = $pdo->prepare("SELECT first_name, last_name FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); $employee = $stmt->fetch(); if ($employee) { $employeeName = $employee['first_name'].' '.$employee['last_name']; $responseText = "สวัสดีครับคุณ {$employeeName}! บอทน้องลา (Leave & WFH Bot) พร้อมให้บริการแล้วครับ\nพิมพ์ /help เพื่อดูคำสั่งที่ใช้ได้"; log_message("Found registered employee: {$employeeName}"); } else { $responseText = "สวัสดีครับคุณ {$firstName}! บอทน้องลา (Leave & WFH Bot) พร้อมให้บริการแล้วครับ\n\n"; if (ALLOW_SELF_REGISTRATION) { $responseText .= "🎯 คุณยังไม่ได้ลงทะเบียนในระบบ กรุณาพิมพ์ /register เพื่อเริ่มการลงทะเบียน\n\n"; } else { $responseText .= "❌ การลงทะเบียนด้วยตัวเองถูกปิดใช้งาน กรุณาติดต่อผู้ดูแลระบบ\n\n"; } $responseText .= "พิมพ์ /help เพื่อดูคำสั่งที่ใช้ได้"; log_message("New user, self registration: ".(ALLOW_SELF_REGISTRATION ? "ENABLED" : "DISABLED")); } $result = $telegramService->sendMessage($chatId, $responseText); log_message("Start response sent to user {$userId}. Result: ".json_encode($result)); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/register') { log_message("Processing /register command for user {$userId}"); $result = $selfRegistrationHandler->startRegistration($chatId, $userId); log_message("Registration start result for user {$userId}: ".json_encode($result)); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/ลงทะเบียน') { $selfRegistrationHandler->startRegistration($chatId, $userId); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/สถานะ' || $lowerText === '/status') { $stmt = $pdo->prepare("SELECT employee_code, first_name, last_name, email FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); $employee = $stmt->fetch(); if ($employee) { $responseText = "✅ *สถานะการลงทะเบียน*\n\n". "👤 ชื่อ: {$employee['first_name']} {$employee['last_name']}\n". "📧 อีเมล: {$employee['email']}\n"; if ($employee['employee_code']) { $responseText .= "🏷️ รหัสพนักงาน: {$employee['employee_code']}\n"; } $responseText .= "\n✅ ลงทะเบียนแล้ว สามารถใช้งานได้"; } else { if (ALLOW_SELF_REGISTRATION) { $responseText = "❌ คุณยังไม่ได้ลงทะเบียนในระบบ\nพิมพ์ /register เพื่อเริ่มการลงทะเบียน"; } else { $responseText = "❌ คุณยังไม่ได้ลงทะเบียนในระบบ\nการลงทะเบียนด้วยตัวเองถูกปิดใช้งาน กรุณาติดต่อผู้ดูแลระบบ"; } } $telegramService->sendMessage($chatId, $responseText, null, 'Markdown'); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/help') { $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); $isRegistered = $stmt->fetch(); if ($isRegistered) { $responseText = "คำสั่งที่น้องลาเข้าใจตอนนี้:\n". "/start - เริ่มการสนทนา\n". "/help - แสดงข้อความช่วยเหลือนี้\n". "/สถานะ (หรือ /status) - ตรวจสอบสถานะการลงทะเบียน\n". "/ลา (หรือ /leave) - เริ่มขั้นตอนการขอลา\n". "/wfh - เริ่มขั้นตอนการขอ Work From Home\n". "/เช็คยอด (หรือ /balance) - ตรวจสอบยอดวันลาคงเหลือ\n". "/ยกเลิกคำขอ (หรือ /cancelrequest) - ยกเลิกคำขอที่รออนุมัติ\n". "/สรุปวันนี้ (หรือ /whosout) - (HR) สรุปผู้ที่ไม่อยู่ในออฟฟิศวันนี้\n". "/cancel - ยกเลิกการดำเนินการปัจจุบัน"; } else { $responseText = "คำสั่งที่น้องลาเข้าใจตอนนี้:\n". "/start - เริ่มการสนทนา\n". "/help - แสดงข้อความช่วยเหลือนี้\n"; if (ALLOW_SELF_REGISTRATION) { $responseText .= "/register - ลงทะเบียนเข้าใช้งานระบบ\n"; } $responseText .= "/สถานะ (หรือ /status) - ตรวจสอบสถานะการลงทะเบียน\n\n"; if (ALLOW_SELF_REGISTRATION) { $responseText .= "⚠️ คุณต้องลงทะเบียนก่อนเพื่อใช้งานคำสั่งอื่นๆ"; } else { $responseText .= "⚠️ การลงทะเบียนด้วยตัวเองถูกปิดใช้งาน กรุณาติดต่อผู้ดูแลระบบ"; } } $telegramService->sendMessage($chatId, $responseText); clearUserStateWebhook($userId, $chatId); } elseif ($lowerText === '/cancel') { clearUserStateWebhook($userId, $chatId); $selfRegistrationHandler->cancelRegistration($chatId, $userId); } else if (str_starts_with($lowerText, '/') && !$userState) { $responseText = "ขออภัยครับคุณ {$firstName}, น้องลายังไม่เข้าใจคำสั่ง: '{$text}'. ลองพิมพ์ /help ดูนะครับ"; $telegramService->sendMessage($chatId, $responseText); } } elseif (isset($update['callback_query'])) { $callbackQuery = $update['callback_query']; $chatId = $callbackQuery['message']['chat']['id']; $userId = $callbackQuery['from']['id']; $callbackData = $callbackQuery['data'] ?? ''; $callbackQueryId = $callbackQuery['id']; $originalMessageId = $callbackQuery['message']['message_id']; $telegramService->answerCallbackQuery($callbackQueryId); // ตรวจสอบสิทธิ์การเข้าใช้งาน if (!$selfRegistrationHandler->canUserAccessBot($userId)) { $telegramService->editMessageText($chatId, $originalMessageId, "❌ ขออภัย คุณยังไม่ได้รับอนุญาตให้ใช้บอทนี้" ); exit; } // ตรวจสอบว่าผู้ใช้ลงทะเบียนแล้ว $stmt = $pdo->prepare("SELECT id FROM employees WHERE chat_user_id = ?"); $stmt->execute([$userId]); if (!$stmt->fetch()) { $telegramService->editMessageText($chatId, $originalMessageId, "❌ กรุณาลงทะเบียนก่อนใช้งาน พิมพ์ /register" ); exit; } $userState = getUserState($userId, $chatId); $currentLeaveAppMode = 'leave'; if ($userState) { if (str_starts_with($userState, 'wfh_')) { $currentLeaveAppMode = 'wfh'; } } if (str_starts_with($callbackData, 'req_type_')) { $leaveAppHandler = new LeaveApplicationHandler($telegramService, $chatId, $userId, $currentLeaveAppMode); $leaveAppHandler->handleTypeSelection($callbackData); } elseif (str_starts_with($callbackData, 'req_action_')) { $leaveAppHandler = new LeaveApplicationHandler($telegramService, $chatId, $userId, $currentLeaveAppMode); if ($userState && (str_starts_with($userState, 'la_confirm_') || str_starts_with($userState, 'wfh_confirm_'))) { $leaveAppHandler->handleConfirmationAction($userState, $callbackData); } else { $telegramService->editMessageText($chatId, $originalMessageId, "การดำเนินการนี้อาจหมดอายุหรือไม่ถูกต้องแล้วค่ะ (ไม่พบ state)"); if ($userState) { clearUserStateWebhook($userId, $chatId); } } } elseif (str_starts_with($callbackData, 'cancelReq_select_')) { $cancelHandler = new CancelRequestHandler($telegramService, $chatId, $userId); $cancelHandler->handleCancellationSelection($callbackData); } elseif (str_starts_with($callbackData, 'cancelReq_confirm_') || $callbackData === 'cancelReq_abort') { $cancelHandler = new CancelRequestHandler($telegramService, $chatId, $userId); if ($userState && str_starts_with($userState, 'cancelReq_confirm_')) { $cancelHandler->handleCancellationConfirmation($userState, $callbackData); } else if ($callbackData === 'cancelReq_abort' && $userState && str_starts_with($userState, 'cancelReq_confirm_')) { // Ensure abort also needs the confirm state $cancelHandler->handleCancellationConfirmation($userState, $callbackData); } else { $telegramService->editMessageText($chatId, $originalMessageId, "การดำเนินการยกเลิกนี้อาจหมดอายุหรือไม่ถูกต้องแล้วค่ะ (ไม่พบ state)"); if ($userState) { clearUserStateWebhook($userId, $chatId); } } } elseif (str_starts_with($callbackData, 'mgrAction_')) { $managerHandler = new ManagerActionHandler($telegramService, $chatId, $userId); $managerHandler->handleApprovalAction($callbackData, $originalMessageId); } else { log_message("Unhandled callback_data: {$callbackData} from user {$userId} in chat {$chatId}"); } } else { log_message("Received an update type that is not a message or callback_query: ".json_encode(array_keys($update))); } http_response_code(200); exit;