date("Y-m-d H:i:s"), 'data' => $data ]; file_put_contents($logFile, json_encode($logEntry, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND); } } // --- GET: Verifikasi Webhook --- if ($_SERVER['REQUEST_METHOD'] === 'GET') { $mode = $_GET['hub_mode'] ?? $_GET['hub.mode'] ?? null; $token = $_GET['hub_verify_token'] ?? $_GET['hub.verify_token'] ?? null; $challenge = $_GET['hub_challenge'] ?? $_GET['hub.challenge'] ?? null; $phone_number_id = $_GET['phone_number_id'] ?? null; $verify_token_db = null; if ($phone_number_id) { try { $stmt = $pdo->prepare("SELECT verify_token FROM whatsapp_cloud_api WHERE number_id = :number_id"); $stmt->execute([':number_id' => $phone_number_id]); $waAccount = $stmt->fetch(PDO::FETCH_ASSOC); $verify_token_db = $waAccount['verify_token'] ?? null; } catch (Exception $e) { writeLog(["event"=>"DB_ERROR_VERIFY_TOKEN","number_id"=>$phone_number_id,"error"=>$e->getMessage()]); } } if ($mode === 'subscribe' && $token && $token === ($verify_token_db ?? '')) { writeLog(["event" => "WEBHOOK_VERIFIED", "number_id" => $phone_number_id]); http_response_code(200); echo $challenge; } else { writeLog(["event" => "WEBHOOK_VERIFICATION_FAILED", "number_id" => $phone_number_id, "token" => $token]); http_response_code(403); } exit; } // --- POST: Terima pesan & status --- if ($_SERVER['REQUEST_METHOD'] === 'POST') { $input = file_get_contents('php://input'); $data = json_decode($input, true); if (!$data || !isset($data['entry'])) { writeLog(["event" => "INVALID_JSON_OR_ENTRY"]); http_response_code(400); exit; } foreach ($data['entry'] as $entry) { foreach ($entry['changes'] ?? [] as $change) { $value = $change['value'] ?? []; // --- Pesan masuk --- foreach ($value['messages'] ?? [] as $message) { $from = $message['from'] ?? null; $type = $message['type'] ?? null; $phone_number_id = $value['metadata']['phone_number_id'] ?? null; if (!$phone_number_id || !$from) continue; try { $stmt = $pdo->prepare("SELECT token_access FROM whatsapp_cloud_api WHERE number_id = :number_id"); $stmt->execute([':number_id' => $phone_number_id]); $waAccount = $stmt->fetch(PDO::FETCH_ASSOC); $access_token = $waAccount['token_access'] ?? null; } catch (Exception $e) { writeLog(["event"=>"DB_ERROR_ACCESS_TOKEN","number_id"=>$phone_number_id,"error"=>$e->getMessage()]); continue; } if (!$access_token) continue; $text = ($type === 'text') ? $message['text']['body'] ?? '' : '[Pesan non-teks: ' . $type . ']'; writeLog(["event" => "INCOMING_MESSAGE", "from" => $from, "type" => $type, "text" => $text]); // Cek apakah nomor sudah ada di database $stmt = $pdo->prepare("SELECT * FROM contact_number_api WHERE whatsapp_number = :number_id"); $stmt->execute([':number_id' => $from]); $waNumber = $stmt->fetch(PDO::FETCH_ASSOC); // Tentukan apakah sudah lewat 24 jam $shouldSend = false; if (!$waNumber) { // Nomor baru → tambahkan ke DB dan tandai perlu kirim $shouldSend = true; $pdo->prepare("INSERT INTO contact_number_api (whatsapp_number, updated_at) VALUES (:number_id, NOW())") ->execute([':number_id' => $from]); } else { $lastUpdate = strtotime($waNumber['updated_at']); $now = time(); $hoursPassed = ($now - $lastUpdate) / 3600; if ($hoursPassed >= 24) { $shouldSend = true; } } if ($phone_number_id == '833144686543436') { $tmp = 'customer_service_contact'; } elseif ($phone_number_id == '789423254262077') { $tmp = 'customer_service_phone'; } elseif ($phone_number_id == '790168360853999') { $tmp = ''; } else { $tmp = null; } if ($shouldSend) { // --- Kirim balasan template --- $reply = [ "messaging_product" => "whatsapp", "to" => $from, "type" => "template", "template" => [ "name" => $tmp, "language" => ["code" => "id"], "components" => [] ] ]; $url = "https://graph.facebook.com/v17.0/$phone_number_id/messages"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $access_token", "Content-Type: application/json" ]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($reply)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); // Kirim ke aplikasi 2 forwardToApp2([ "data" => $reply, "phone_id" => $phone_number_id, "respon" => $response ]); // Update waktu eksekusi terakhir $pdo->prepare("UPDATE contact_number_api SET updated_at = NOW() WHERE whatsapp_number = :number_id") ->execute([':number_id' => $from]); } writeLog(["event"=>"REPLY_SENT","to"=>$from,"http_code"=>$http_code]); } // --- Status update --- foreach ($value['statuses'] ?? [] as $statusEvent) { $waMessageId = $statusEvent['id'] ?? null; $status = $statusEvent['status'] ?? null; // PHP 7.4 compatible switch ($status) { case 'sent': $finalStatus = 'PROSES'; break; case 'delivered': $finalStatus = 'TERKIRIM'; break; case 'read': $finalStatus = 'DIBACA'; break; case 'failed': $finalStatus = 'GAGAL'; break; default: $finalStatus = strtoupper($status); break; } if ($waMessageId) { try { $stmtMsg = $pdo->prepare("SELECT id, status FROM master_pesan WHERE wa_message_id = :wa_message_id"); $stmtMsg->execute([':wa_message_id' => $waMessageId]); $pesanDB = $stmtMsg->fetch(PDO::FETCH_ASSOC); } catch (Exception $e) { continue; } if ($pesanDB) { try { $stmtUpdate = $pdo->prepare("UPDATE master_pesan SET status = :status WHERE id = :id"); $stmtUpdate->execute([':status' => $finalStatus, ':id' => $pesanDB['id']]); writeLog(["event"=>"STATUS_UPDATED","wa_message_id"=>$waMessageId,"new_status"=>$finalStatus]); } catch (Exception $e) {} } } } } } // --- Forward ke webhook baru (jika ada) --- $forwardUrl = "http://172.16.254.226/webhook/receive"; try { $ch = curl_init($forwardUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_POSTFIELDS, $input); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); // Jika webhook baru masih HTTP, nonaktifkan verifikasi SSL sementara curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $result = curl_exec($ch); $err = curl_error($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); writeLog([ "event" => "FORWARDED_TO_NEW_WEBHOOK", "url" => $forwardUrl, "http_code" => $httpCode, "error" => $err ?: null ]); } catch (Exception $e) { writeLog(["event" => "FORWARD_FAILED", "error" => $e->getMessage()]); } http_response_code(200); echo "EVENT_RECEIVED"; exit; } http_response_code(404);