Update .gitignore and remove
This commit is contained in:
+1
-1
@@ -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 @@
|
||||
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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user