228 lines
9.4 KiB
PHP
228 lines
9.4 KiB
PHP
<?php
|
|
include __DIR__ . "/../config/connect.php";
|
|
include __DIR__ . "/send_to_app2.php";
|
|
|
|
// --- CONFIG LOGGING ---
|
|
$enableLogging = false;
|
|
$logFile = __DIR__ . '/webhook_log.jsonl';
|
|
|
|
function writeLog($data) {
|
|
global $enableLogging, $logFile;
|
|
if ($enableLogging) {
|
|
$logEntry = [
|
|
'timestamp' => 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);
|