Update .gitignore and remove

This commit is contained in:
WD - Dev
2025-07-05 16:15:08 +07:00
parent bc6d99d252
commit 95cd0f93e4
9 changed files with 481 additions and 19 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ agen/profile/
payment/paydisini/api_control.php
config/connect.php
config/whatsapp_api.php
whapi_webhook/
whapi_webhook/*.log
+1 -1
View File
@@ -1 +1 @@
NO ACTION => 2 <-> cc.net Limit_Tgl_5<br>NO ACTION => 3 <-> nsn utama Limit_Tgl_10<br>NO ACTION => 3 <-> ciangsana Limit_Tgl_15<br>NO ACTION => 4 <-> fast.net Limit_Tgl_12<br>NO ACTION => 5 <-> bima net Limit Tagihan Tgl 15<br>NO ACTION => 6 <-> kingnet Limit Tgl 15<br>NO ACTION => 8 <-> diamond.net Limit_Tgl_15<br>NO ACTION => 9 <-> 22 p.net Limit_Tgl_15<br>NO ACTION => 10 <-> nettizen Tagihan Limit tgl 15<br>NO ACTION => 12 <-> Tagihan_Limit_Tgl5<br>NO ACTION => 15 <-> Tag_NTA2 Limit Tgl 5<br>NO ACTION => 16 <-> Tagihan Limit Tgl 5<br>BUAT TAGIHAN => 13 <-> Limit Tanggal 26 (Infinnet) Start : 2025-07-04 - Last : 2025-07-09<br>REMAND => 18 <-> BUM-Limit-Tgl-5<br>NO ACTION => 14 <-> Kh_Limit Tanggal 25<br>KIRIM TAGIHAN => 17 <-> Tagihan Limit Tgl 10<br>NO ACTION => 17 <-> Tagihan Limit Tgl 15<br>NO ACTION => 20 <-> IVVI-10<br>NO ACTION => 20 <-> IVVI-20<br>NO ACTION => 20 <-> IVVI-30<br>BUAT TAGIHAN => 21 <-> QONNET Start : 2025-07-02 - Last : 2025-07-05<br>NO ACTION => 21 <-> QONNET2<br>NO ACTION => 25 <-> Tagihan Limit Tgl 5<br>REMAND => 23 <-> Limit Tanggal 5<br>NO ACTION => 26 <-> Limit Tanggal 10<br>NO ACTION => 24 <-> Tagihan30<br>BUAT TAGIHAN => 23 <-> limit tanggal 19 Start : 2025-06-27 - Last : 2025-07-14<br>KIRIM TAGIHAN => 31 <-> 23-ISOLIR<br>NO ACTION => 33 <-> usolir-10<br>NO ACTION => 37 <-> paket 140 ribu<br>REMAND => 28 <-> PAKET-100K<br>REMAND => 28 <-> PAKET-150K<br>REMAND => 28 <-> PAKET-200K<br>REMAND => 28 <-> PAKET-300K<br>KIRIM TAGIHAN => 42 <-> meldina-20<br>BUAT TAGIHAN => 41 <-> lippy-20 Start : 2025-07-04 - Last : 2025-07-09<br>BUAT TAGIHAN => 43 <-> Tagihan_Limit_tgl_13 Start : 2025-07-01 - Last : 2025-07-06<br>REMAND => 46 <-> Limit_Tgl_5<br>NO ACTION => 35 <-> PAKET 1 DEVICE<br>NO ACTION => 35 <-> PAKET 2 DEVICE<br>NO ACTION => 35 <-> PAKET 3 DEVICE<br>NO ACTION => 35 <-> PAKET 4 DEVICE<br>NO ACTION => 35 <-> PAKET 5 DEVICE [1/80]<br>NO ACTION => 35 <-> PAKET 5 DEVICE [1/70]<br>NO ACTION => 35 <-> PAKET 6 DEVICE [1/80]<br>NO ACTION => 35 <-> PAKET 6 DEVICE [1/70]<br>NO ACTION => 35 <-> PAKET 7 DEVICE<br>NO ACTION => 35 <-> PAKET 8 DEVICE<br>BUAT TAGIHAN => 44 <-> Isolir_20 Start : 2025-07-04 - Last : 2025-07-07<br>BUAT TAGIHAN => 53 <-> PAKET BRONZE Start : 2025-07-01 - Last : 2025-07-06<br>KIRIM TAGIHAN => 54 <-> Muhamad rouf<br>BUAT TAGIHAN => 53 <-> PAKET PLATINUM 5MBs Start : 2025-07-01 - Last : 2025-07-06<br>BUAT TAGIHAN => 53 <-> PAKET GLOD 7 MBs Start : 2025-07-01 - Last : 2025-07-06<br>BUAT TAGIHAN => 53 <-> PAKET GLOD+ 10 MBs Start : 2025-07-01 - Last : 2025-07-06<br>NO ACTION => 59 <-> Isolir_21<br>BUAT TAGIHAN => 46 <-> Limit tgl 30 Start : 2025-06-29 - Last : 2025-07-24<br>NO ACTION => 61 <-> Isolir_20<br>BUAT TAGIHAN => 55 <-> Dcn_CO_Isolir Start : 2025-06-28 - Last : 2025-07-24<br>REMAND => 62 <-> limit tanggal 5<br>NO ACTION => 21 <-> VIP-BAGUS<br>REMAND => 55 <-> Dcn_GB_Isolir<br>BUAT TAGIHAN => 49 <-> TAGIHAN TANGGAL 20 Start : 2025-06-29 - Last : 2025-07-18<br>
NO ACTION => 2 <-> cc.net Limit_Tgl_5<br>NO ACTION => 3 <-> nsn utama Limit_Tgl_10<br>NO ACTION => 3 <-> ciangsana Limit_Tgl_15<br>NO ACTION => 4 <-> fast.net Limit_Tgl_12<br>NO ACTION => 5 <-> bima net Limit Tagihan Tgl 15<br>NO ACTION => 6 <-> kingnet Limit Tgl 15<br>NO ACTION => 8 <-> diamond.net Limit_Tgl_15<br>NO ACTION => 9 <-> 22 p.net Limit_Tgl_15<br>NO ACTION => 10 <-> nettizen Tagihan Limit tgl 15<br>NO ACTION => 12 <-> Tagihan_Limit_Tgl5<br>NO ACTION => 15 <-> Tag_NTA2 Limit Tgl 5<br>NO ACTION => 16 <-> Tagihan Limit Tgl 5<br>BUAT TAGIHAN => 13 <-> Limit Tanggal 26 (Infinnet) Start : 2025-07-04 - Last : 2025-07-09<br>REMAND => 18 <-> BUM-Limit-Tgl-5<br>NO ACTION => 14 <-> Kh_Limit Tanggal 25<br>KIRIM TAGIHAN => 17 <-> Tagihan Limit Tgl 10<br>NO ACTION => 17 <-> Tagihan Limit Tgl 15<br>NO ACTION => 20 <-> IVVI-10<br>NO ACTION => 20 <-> IVVI-20<br>NO ACTION => 20 <-> IVVI-30<br>BUAT TAGIHAN => 21 <-> QONNET Start : 2025-07-02 - Last : 2025-07-05<br>NO ACTION => 21 <-> QONNET2<br>NO ACTION => 25 <-> Tagihan Limit Tgl 5<br>REMAND => 23 <-> Limit Tanggal 5<br>NO ACTION => 26 <-> Limit Tanggal 10<br>NO ACTION => 24 <-> Tagihan30<br>BUAT TAGIHAN => 23 <-> limit tanggal 19 Start : 2025-06-27 - Last : 2025-07-14<br>KIRIM TAGIHAN => 31 <-> 23-ISOLIR<br>NO ACTION => 33 <-> usolir-10<br>NO ACTION => 37 <-> paket 140 ribu<br>REMAND => 28 <-> PAKET-100K<br>REMAND => 28 <-> PAKET-150K<br>REMAND => 28 <-> PAKET-200K<br>REMAND => 28 <-> PAKET-300K<br>KIRIM TAGIHAN => 42 <-> meldina-20<br>BUAT TAGIHAN => 41 <-> lippy-20 Start : 2025-07-04 - Last : 2025-07-09<br>BUAT TAGIHAN => 43 <-> Tagihan_Limit_tgl_13 Start : 2025-07-01 - Last : 2025-07-06<br>REMAND => 46 <-> Limit_Tgl_5<br>NO ACTION => 35 <-> PAKET 1 DEVICE<br>NO ACTION => 35 <-> PAKET 2 DEVICE<br>NO ACTION => 35 <-> PAKET 3 DEVICE<br>NO ACTION => 35 <-> PAKET 4 DEVICE<br>NO ACTION => 35 <-> PAKET 5 DEVICE [1/80]<br>NO ACTION => 35 <-> PAKET 5 DEVICE [1/70]<br>NO ACTION => 35 <-> PAKET 6 DEVICE [1/80]<br>NO ACTION => 35 <-> PAKET 6 DEVICE [1/70]<br>NO ACTION => 35 <-> PAKET 7 DEVICE<br>NO ACTION => 35 <-> PAKET 8 DEVICE<br>BUAT TAGIHAN => 44 <-> Isolir_20 Start : 2025-07-04 - Last : 2025-07-07<br>BUAT TAGIHAN => 53 <-> PAKET BRONZE Start : 2025-07-01 - Last : 2025-07-06<br>KIRIM TAGIHAN => 54 <-> Muhamad rouf<br>BUAT TAGIHAN => 53 <-> PAKET PLATINUM 5MBs Start : 2025-07-01 - Last : 2025-07-06<br>BUAT TAGIHAN => 53 <-> PAKET GLOD 7 MBs Start : 2025-07-01 - Last : 2025-07-06<br>BUAT TAGIHAN => 53 <-> PAKET GLOD+ 10 MBs Start : 2025-07-01 - Last : 2025-07-06<br>NO ACTION => 59 <-> Isolir_21<br>BUAT TAGIHAN => 46 <-> Limit tgl 30 Start : 2025-06-29 - Last : 2025-07-24<br>
+15 -15
View File
@@ -1,23 +1,23 @@
SV_Cikembar_Utama Data pelanggan tidak ada
2025-07-05 15:29:01SV_BojongKerta Data pelanggan tidak ada
2025-07-05 15:29:01SV_Permata_Sampora Data pelanggan tidak ada
2025-07-05 15:29:01SV_Kingnet_Cibadak Data pelanggan tidak ada
2025-07-05 15:29:01SV_CC-Net_Cipicung Data pelanggan tidak ada
2025-07-05 15:29:01SV_Nusaina_Cibadak Data pelanggan tidak ada
2025-07-05 15:29:01SV_Diamond Net Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:44:01SV_BojongKerta Data pelanggan tidak ada
2025-07-05 15:44:01SV_Permata_Sampora Data pelanggan tidak ada
2025-07-05 15:44:01SV_Kingnet_Cibadak Data pelanggan tidak ada
2025-07-05 15:44:01SV_CC-Net_Cipicung Data pelanggan tidak ada
2025-07-05 15:44:01SV_Nusaina_Cibadak Data pelanggan tidak ada
2025-07-05 15:44:01SV_Diamond Net Status koneksi tidak aktif atau interval tidak tersedia.
SV_22P Net Cibadak Data pelanggan tidak ada
2025-07-05 15:29:01SV_Nettizen_Segaranten Data pelanggan tidak ada
2025-07-05 14:59:01SV-DNY-Net-1 Data pelanggan tidak ada
2025-07-05 15:39:01SV_NTA_2_Pasawahan Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:44:01SV_Nettizen_Segaranten Data pelanggan tidak ada
2025-07-05 15:14:01SV-DNY-Net-1 Data pelanggan tidak ada
2025-07-05 15:54:01SV_NTA_2_Pasawahan Status koneksi tidak aktif atau interval tidak tersedia.
SV_NTA_1 Status koneksi tidak aktif atau interval tidak tersedia.
SV-Cicukang Status koneksi tidak aktif atau interval tidak tersedia.
RO-Bumdes-Mekarmanah Status koneksi tidak aktif atau interval tidak tersedia.
RO-Pak-Kholiq Data pelanggan tidak ada
2025-07-05 15:44:01RO-Dendrit-Net Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:59:01RO-Dendrit-Net Status koneksi tidak aktif atau interval tidak tersedia.
LJN.NS.CSR.NET Status koneksi tidak aktif atau interval tidak tersedia.
IVVINET-CBD Data pelanggan tidak ada
2025-07-05 15:29:01QONNET Data pelanggan tidak ada
2025-07-05 15:29:01Mikrotik_X86 Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:44:01QONNET Data pelanggan tidak ada
2025-07-05 15:44:01Mikrotik_X86 Status koneksi tidak aktif atau interval tidak tersedia.
Mikrotik_BSW_1 Status koneksi tidak aktif atau interval tidak tersedia.
Mikrotik_Alea Status koneksi tidak aktif atau interval tidak tersedia.
STANG Status koneksi tidak aktif atau interval tidak tersedia.
@@ -37,14 +37,14 @@ RO_Wargasari Status koneksi tidak aktif atau interval tidak tersedia.
LJN_AGUNG Status koneksi tidak aktif atau interval tidak tersedia.
RNET-CMS Status koneksi tidak aktif atau interval tidak tersedia.
DCN-GB-CCR Data pelanggan tidak ada
2025-07-05 15:29:01coba Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:44:01coba Status koneksi tidak aktif atau interval tidak tersedia.
412NET Status koneksi tidak aktif atau interval tidak tersedia.
brf Status koneksi tidak aktif atau interval tidak tersedia.
BMSNET Status koneksi tidak aktif atau interval tidak tersedia.
purabaya Status koneksi tidak aktif atau interval tidak tersedia.
DCN-CO-GX4 Data pelanggan tidak ada
2025-07-05 15:29:01MIKROTIK GX4 Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:44:01MIKROTIK GX4 Status koneksi tidak aktif atau interval tidak tersedia.
RO - Netborhood Wifi Status koneksi tidak aktif atau interval tidak tersedia.
Neglasari Status koneksi tidak aktif atau interval tidak tersedia.
SV-DNY-Net-2 Data pelanggan tidak ada
2025-07-05 15:39:01DNY-Neglasari Status koneksi tidak aktif atau interval tidak tersedia.
2025-07-05 15:54:01DNY-Neglasari Status koneksi tidak aktif atau interval tidak tersedia.
+2 -2
View File
@@ -1,4 +1,4 @@
Successfully started background process for IP: 103.26.176.93
Successfully started background process for IP: tunnel.manjapro.net
Successfully started background process for IP: 103.242.104.69
Successfully started background process for IP: 103.26.176.93
Started parallel processes for checking vouchers. => 2025-07-05 15:57:01
Started parallel processes for checking vouchers. => 2025-07-05 16:12:02
+28
View File
@@ -18,3 +18,31 @@ LJN.NS.CSR.NET =><br>
IVVINET-CBD =><br>
QONNET =><br>
Mikrotik_X86 =><br>
Mikrotik_BSW_1 =><br>
Mikrotik_Alea =><br>
STANG =><br>
UNIX-NET =><br>
SV_NTA_2_TBL =><br>
MULYANAJAYA =><br>
PERWASIM.NET =><br>
RO_MELDINA =><br>
RO_LIPPY =><br>
RO_Asep =><br>
BATUNUNGGAL =><br>
PADINET =><br>
RAGILNET =><br>
RO_Sukasari =><br>
RO_Wargasari =><br>
LJN_AGUNG =><br>
RNET-CMS =><br>
DCN-GB-CCR =><br>
412NET =><br>
brf =><br>
BMSNET =><br>
purabaya =><br>
DCN-CO-GX4 =><br>
MIKROTIK GX4 =><br>
RO - Netborhood Wifi =><br>
Neglasari =><br>
SV-DNY-Net-2 =><br>
DNY-Neglasari =><br>
+8
View File
@@ -0,0 +1,8 @@
2025-05-25 09:22:06 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-25 09:22:16 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-25 09:22:26 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-25 09:22:36 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-30 22:04:51 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-30 22:05:01 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-30 22:05:11 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
2025-05-30 22:05:21 Exception ResponAI: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'nomor_whatsapp' at row 1
+111
View File
@@ -0,0 +1,111 @@
<?php
include __DIR__ . "/../../config/whatsapp_api.php";
include __DIR__ . "/respon_ai.php";
// Setup error reporting untuk debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Simpan log raw input untuk debug paling awal
// file_put_contents(__DIR__ . "/debug_raw_input.log", date('Y-m-d H:i:s') . " Input:\n" . print_r(file_get_contents('php://input'), true) . "\n", FILE_APPEND);
try {
// Ambil dan decode input JSON
$data = file_get_contents('php://input');
$json_data = json_decode($data, true);
if (!isset($json_data['results']['apiKey'])) {
http_response_code(400);
echo "apiKey tidak ditemukan.";
exit;
}
$apiKey = $json_data['results']['apiKey'];
// file_put_contents(__DIR__ . "/debug_apikey.log", date('Y-m-d H:i:s') . " apiKey: $apiKey\n", FILE_APPEND);
if (
isset($json_data['type']) && $json_data['type'] === 'message' &&
isset($json_data['results']['fromMe']) && $json_data['results']['fromMe'] === false &&
isset($json_data['results']['isGroupMsg']) && $json_data['results']['isGroupMsg'] === false
) {
$sender = $json_data['results']['sender'] ?? 'Tidak diketahui';
$sender = str_replace("@s.whatsapp.net", "", $sender);
$body = $json_data['results']['body'] ?? '';
// file_put_contents(__DIR__ . "/debug_sender_body.log", date('Y-m-d H:i:s') . " Sender: $sender, Body: $body\n", FILE_APPEND);
$filtered = [
'sender' => $sender,
'body' => $body,
'apiKey' => $apiKey
];
$log_file = __DIR__ . "/" . $apiKey . ".log";
$log_entry = "[" . date('Y-m-d H:i:s') . "] Masuk: " . print_r($filtered, true);
// Pastikan kelas ResponAI ada
if (!class_exists('ResponAI')) {
file_put_contents(__DIR__ . "/error.log", date('Y-m-d H:i:s') . " Class ResponAI tidak ditemukan!\n", FILE_APPEND);
http_response_code(500);
exit("Server error: ResponAI class missing");
}
$ResAI = new ResponAI();
// Tangkap exception saat proses respon_chat
try {
$Respon = $ResAI->respon_chat($body, $sender, $apiKey);
} catch (Exception $e) {
file_put_contents(__DIR__ . "/error.log", date('Y-m-d H:i:s') . " Exception ResponAI: " . $e->getMessage() . "\n", FILE_APPEND);
http_response_code(500);
exit("Server error: gagal proses AI");
}
// file_put_contents(__DIR__ . "/step2_respon_ai.log", date('Y-m-d H:i:s') . " " . print_r($Respon, true), FILE_APPEND);
if (!empty($Respon['id']) && !empty($Respon['nomor'])) {
if (!class_exists('PesanWA')) {
file_put_contents(__DIR__ . "/error.log", date('Y-m-d H:i:s') . " Class PesanWA tidak ditemukan!\n", FILE_APPEND);
http_response_code(500);
exit("Server error: PesanWA class missing");
}
$API_WA = new PesanWA();
try {
$send_result = $API_WA->Send_Pesan($Respon['id'], 'sendMessage', array($Respon['nomor']), $Respon['respon']);
} catch (Exception $e) {
file_put_contents(__DIR__ . "/error.log", date('Y-m-d H:i:s') . " Exception Send_Pesan: " . $e->getMessage() . "\n", FILE_APPEND);
http_response_code(500);
exit("Server error: gagal kirim pesan");
}
// file_put_contents(__DIR__ . "/step3_send_pesan.log", date('Y-m-d H:i:s') . " Kirim pesan ke: {$Respon['nomor']}\nResponse Send_Pesan: " . print_r($send_result, true), FILE_APPEND);
$log_entry .= "[" . date('Y-m-d H:i:s') . "] Balasan AI: " . print_r($Respon, true) . PHP_EOL;
// file_put_contents($log_file, $log_entry, FILE_APPEND);
http_response_code(200);
exit;
} else {
// file_put_contents(__DIR__ . "/error_send_pesan.log", date('Y-m-d H:i:s') . " Gagal kirim pesan, id atau nomor kosong: " . print_r($Respon, true) . "\n", FILE_APPEND);
http_response_code(500);
echo "Gagal mengirim pesan: data tidak lengkap.";
exit;
}
} else {
http_response_code(400);
echo "Data tidak valid atau bukan pesan yang diinginkan.";
exit;
}
} catch (Throwable $t) {
// Tangkap semua error fatal / throwable
file_put_contents(__DIR__ . "/error.log", date('Y-m-d H:i:s') . " Fatal error: " . $t->getMessage() . "\n", FILE_APPEND);
http_response_code(500);
echo "Server error: " . $t->getMessage();
exit;
}
+276
View File
@@ -0,0 +1,276 @@
<?php
class ResponAI {
private function connectDB() {
include __DIR__ . "/../../config/connect.php"; // Harus mengisi $pdo
return $pdo;
}
private function deteksi_topik($message) {
$rules = [
'gangguan' => ['lambat', 'tidak konek', 'jaringan', 'trouble', 'gangguan', 'internet mati'],
'tagihan' => ['tagihan', 'bayar', 'invoice', 'pembayaran', 'rekening'],
'pemasangan' => ['pasang', 'berlangganan', 'pemasangan', 'registrasi', 'daftar', 'masang'],
'umum' => []
];
$message = strtolower($message);
foreach ($rules as $topik => $keywords) {
foreach ($keywords as $keyword) {
if (strpos($message, $keyword) !== false) {
return $topik;
}
}
}
return 'umum';
}
private function get_data_pelanggan($sender) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT nama, nama_paket, status, akun, status_koneksi FROM v_pelanggan WHERE nomor_whatsapp = ?");
$stmt->execute([$sender]);
$pelanggan = $stmt->fetch(PDO::FETCH_ASSOC);
if ($pelanggan) {
return "Pelanggan atas nama {$pelanggan['nama']} (ID: {$pelanggan['akun']}) menggunakan paket {$pelanggan['nama_paket']} dan status koneksi {$pelanggan['status_koneksi']}. Status langganan: {$pelanggan['status']}.";
}
return "Data pelanggan tidak ditemukan.";
}
private function get_id_server($apikey_wa) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT id FROM data_server WHERE apikey_whatsapp = ?");
$stmt->execute([$apikey_wa]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['id'] ?? null;
}
private function get_paket_berlangganan($id) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT nama, harga_paket FROM profile_paket WHERE id_data_server = ?");
$stmt->execute([$id]);
$pakets = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!$pakets) return "Paket berlangganan belum tersedia.";
$list = "Berikut adalah daftar paket layanan:\n";
foreach ($pakets as $p) {
$list .= "- {$p['nama']}: Rp " . number_format($p['harga_paket'], 0, ',', '.') . "\n";
}
return trim($list);
}
private function haversine($lat1, $lon1, $lat2, $lon2) {
$earthRadius = 6371;
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
$a = sin($dLat / 2) ** 2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon / 2) ** 2;
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return $earthRadius * $c;
}
private function get_info_pemasangan($id, $lat = null, $lon = null) {
$pdo = $this->connectDB();
$stmt1 = $pdo->prepare("SELECT harga_sewa FROM data_server WHERE id = ?");
$stmt1->execute([$id]);
$row = $stmt1->fetch(PDO::FETCH_ASSOC);
$biaya = isset($row['harga_sewa']) ? "Biaya pemasangan sebesar Rp " . number_format($row['harga_sewa'], 0, ',', '.') . "." : "";
$stmt2 = $pdo->prepare("SELECT nama FROM master_desa WHERE id_data_server = ?");
$stmt2->execute([$id]);
$desas = $stmt2->fetchAll(PDO::FETCH_ASSOC);
$wilayah = $desas ? implode(", ", array_column($desas, 'nama')) : "Wilayah layanan belum terdaftar.";
$stmt3 = $pdo->prepare("SELECT titik_koordinat FROM master_topologi WHERE id_data_server = ?");
$stmt3->execute([$id]);
$koordinats = $stmt3->fetchAll(PDO::FETCH_ASSOC);
if ($lat !== null && $lon !== null && $koordinats) {
foreach ($koordinats as $k) {
$raw = $k['titik_koordinat'];
// Cek apakah tidak kosong dan mengandung koma
if (!empty($raw) && strpos($raw, ',') !== false) {
$parts = explode(',', $raw);
// Pastikan hasil explode memiliki dua elemen
if (count($parts) === 2) {
$latParsed = trim($parts[0]);
$lonParsed = trim($parts[1]);
// Validasi bahwa lat dan lon adalah angka
if (is_numeric($latParsed) && is_numeric($lonParsed)) {
$distance = $this->haversine($lat, $lon, (float)$latParsed, (float)$lonParsed);
if ($distance <= 0.3) {
$formulir = "Anda berada dalam jangkauan layanan kami.\n\nSilakan lengkapi data berikut untuk registrasi:\n"
. "- Nama lengkap\n"
. "- NIK\n"
. "- Alamat Lengkap\n"
. "- Titik Koordinat\n"
. "- Nomor WhatsApp\n"
. "- Paket Layanan";
return "$biaya\n$formulir";
}
}
}
}
}
return "Mohon maaf, titik koordinat Anda belum terjangkau jaringan kami.";
}
return "$biaya Wilayah layanan mencakup: $wilayah.\n\nSilakan kirimkan titik koordinat lokasi Anda agar kami bisa melakukan pengecekan jangkauan.";
}
private function get_data_tagihan($sender) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT nama, total_tagihan, limit_pembayaran, tanggal_bayar, status FROM v_tagihan WHERE nomor_whatsapp = ? ORDER BY tanggal_bayar DESC");
$stmt->execute([$sender]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!$rows) return "Tidak ada tagihan yang ditemukan.";
$list = "Riwayat tagihan:\n";
foreach ($rows as $row) {
$list .= "- Tagihan: Rp " . number_format($row['total_tagihan'], 0, ',', '.') . " | Jatuh Tempo: {$row['limit_pembayaran']} | Status: {$row['status']}\n";
}
return trim($list);
}
private function simpan_sesi($sender, $topik) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("INSERT INTO chat_session (nomor_whatsapp, topik_terakhir) VALUES (?, ?) ON DUPLICATE KEY UPDATE topik_terakhir = VALUES(topik_terakhir)");
$stmt->execute([$sender, $topik]);
}
private function ambil_sesi($sender) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT topik_terakhir FROM chat_session WHERE nomor_whatsapp = ?");
$stmt->execute([$sender]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['topik_terakhir'] ?? null;
}
private function simpan_log($sender, $role, $pesan, $id) {
$pdo = $this->connectDB();
$stmt = $pdo->prepare("INSERT INTO chat_log (nomor_whatsapp, role, pesan, id_data_server) VALUES (?, ?, ?, ?)");
$stmt->execute([$sender, $role, $pesan, $id]);
}
public function respon_chat($message, $sender, $apikey_wa) {
$OPENAI_API_KEY = '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'; // Ganti dengan API key valid
$id = $this->get_id_server($apikey_wa);
if (empty($message) || empty($sender) || !$id) {
return [
'id' => $id,
'nomor' => $sender,
'respon' => 'Input tidak valid atau data server tidak ditemukan.'
];
}
$topik = $this->deteksi_topik($message);
$topik_sesi = $this->ambil_sesi($sender);
if (!$topik && $topik_sesi) {
$topik = $topik_sesi;
}
if ($topik) {
$this->simpan_sesi($sender, $topik);
}
$this->simpan_log($sender, 'user', $message, $id);
$pdo = $this->connectDB();
$stmt = $pdo->prepare("SELECT role, pesan FROM chat_log WHERE id_data_server = ? AND nomor_whatsapp = ? ORDER BY id DESC LIMIT 10");
$stmt->execute([$id, $sender]);
$riwayat = array_reverse($stmt->fetchAll(PDO::FETCH_ASSOC));
$messages = [];
foreach ($riwayat as $log) {
$messages[] = ['role' => $log['role'], 'content' => $log['pesan']];
}
$messages[] = ['role' => 'user', 'content' => $message];
$data_pelanggan = $this->get_data_pelanggan($sender);
$info_paket = $this->get_paket_berlangganan($id);
$info_pasang = $this->get_info_pemasangan($id);
$data_tagihan = $this->get_data_tagihan($sender);
$roles = [
'gangguan' => 'Kamu adalah customer service penyedia layanan internet untuk masalah teknis.',
'tagihan' => 'Kamu adalah customer service penyedia layanan internet untuk urusan tagihan.',
'pemasangan' => 'Kamu adalah customer service penyedia layanan internet untuk pemasangan baru.',
'umum' => 'Kamu adalah customer service penyedia layanan internet untuk pertanyaan umum.'
];
$topik_final = $topik ?: 'umum';
switch ($topik_final) {
case 'tagihan':
$tambahan = $data_tagihan;
break;
case 'pemasangan':
$tambahan = $info_paket . "\n" . $info_pasang;
break;
default:
$tambahan = '';
break;
}
$system_message = $roles[$topik_final] . " Data pelanggan: $data_pelanggan\n$tambahan\nJawaban maksimal 3 kalimat, singkat, sopan, dan informatif.";
array_unshift($messages, ['role' => 'system', 'content' => $system_message]);
$payload = [
'model' => 'gpt-3.5-turbo',
'messages' => $messages,
'temperature' => 0.7,
'max_tokens' => 100
];
$ch = curl_init('https://api.openai.com/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $OPENAI_API_KEY,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
return [
'id' => $id,
'nomor' => $sender,
'respon' => 'Terjadi kesalahan koneksi ke OpenAI: ' . $error
];
}
curl_close($ch);
$data = json_decode($response, true);
$reply = $data['choices'][0]['message']['content'] ?? 'Maaf, tidak dapat memberikan jawaban saat ini.';
$this->simpan_log($sender, 'assistant', $reply, $id);
$hasil = [
'id' => $id,
'nomor' => $sender,
'respon' => trim($reply)
];
// Debug log
// file_put_contents("debug_respon_chat.log",
// "====\n[" . date("Y-m-d H:i:s") . "]\n".
// "Payload:\n" . print_r($payload, true) .
// "Response:\n" . print_r($data, true) .
// "Final:\n" . print_r($hasil, true),
// FILE_APPEND
// );
return $hasil;
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
// Menangkap data JSON dari webhook
$data = file_get_contents('php://input');
// Decode JSON untuk membaca isinya
$json_data = json_decode($data, true);
// Validasi payload JSON
if (isset($json_data['results']['apiKey'])) {
$apiKey = $json_data['results']['apiKey'];
// Periksa jika bukan pesan grup
if (isset($json_data['results']['isGroupMsg']) && $json_data['results']['isGroupMsg'] === false) {
// Nama file log berdasarkan apiKey
$log_file = $apiKey . ".log";
// Menambahkan data baru dengan waktu (opsional)
$log_entry = "[" . date('Y-m-d H:i:s') . "] " . $data . PHP_EOL;
// Simpan ke file log sesuai apiKey
if (file_put_contents($log_file, $log_entry, FILE_APPEND) !== false) {
// Tanggapan ke pengirim webhook
http_response_code(200);
echo "Data webhook diterima dan disimpan di $log_file";
} else {
// Gagal menyimpan file log
http_response_code(500);
echo "Gagal menyimpan data ke file log.";
}
} else {
// Pesan grup tidak diproses
http_response_code(400);
echo "Pesan grup tidak diproses.";
}
} else {
// Jika `apiKey` tidak ditemukan
http_response_code(400);
}
?>