exec("CREATE TABLE IF NOT EXISTS chats (
id_chat INT AUTO_INCREMENT PRIMARY KEY,
id_account INT NOT NULL,
id_occupant INT NOT NULL,
sender ENUM('account', 'occupant') NOT NULL,
message TEXT NOT NULL,
is_read TINYINT DEFAULT 0,
deleted_by_occupant TINYINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
// Automatically add columns to existing tables if updating
try {
$pdo->exec("ALTER TABLE chats ADD COLUMN deleted_by_occupant TINYINT DEFAULT 0 AFTER is_read");
} catch(PDOException $e) { /* Column likely exists */ }
try {
$pdo->exec("ALTER TABLE occupant ADD COLUMN last_active DATETIME NULL");
} catch(PDOException $e) { /* Column likely exists */ }
try {
$pdo->exec("ALTER TABLE occupant ADD COLUMN telegram_id VARCHAR(100) NULL AFTER no_hp");
} catch(PDOException $e) { /* Column likely exists */ }
try {
$pdo->exec("ALTER TABLE chats ADD COLUMN telegram_msg_id INT NULL AFTER id_chat");
} catch(PDOException $e) { /* Column likely exists */ }
try {
$pdo->exec("ALTER TABLE chats ADD COLUMN reply_to_chat_id INT NULL AFTER telegram_msg_id");
} catch(PDOException $e) { /* Column likely exists */ }
try {
$pdo->exec("ALTER TABLE chats ADD COLUMN is_pinned TINYINT DEFAULT 0 AFTER reply_to_chat_id");
} catch(PDOException $e) { /* Column likely exists */ }
// AUTO CLEANUP: Hapus chat yang usianya lebih dari 3 hari (72 Jam)
try {
$pdo->exec("DELETE FROM chats WHERE created_at < NOW() - INTERVAL 3 DAY AND is_pinned = 0");
} catch(PDOException $e) {}
if ($action === 'get_contacts') {
// Fetch all occupants, join with latest message and unread count
$stmt = $pdo->query("SELECT o.*,
(SELECT message FROM chats c WHERE c.id_occupant = o.id_occupant AND c.id_account = $id_account ORDER BY c.created_at DESC LIMIT 1) as last_message,
(SELECT created_at FROM chats c WHERE c.id_occupant = o.id_occupant AND c.id_account = $id_account ORDER BY c.created_at DESC LIMIT 1) as last_time,
(SELECT COUNT(*) FROM chats c WHERE c.id_occupant = o.id_occupant AND c.id_account = $id_account AND c.sender = 'occupant' AND c.is_read = 0) as unread_count
FROM occupant o
WHERE (SELECT id_chat FROM chats c WHERE c.id_occupant = o.id_occupant AND c.id_account = $id_account LIMIT 1) IS NOT NULL
OR o.telegram_id IS NOT NULL
ORDER BY last_time DESC, o.name ASC");
$contacts = $stmt->fetchAll();
// Add default avatar handling
foreach ($contacts as &$contact) {
if (empty($contact['foto']) || !file_exists($contact['foto'])) {
$contact['foto'] = 'images/faces/user.jpg';
}
}
echo json_encode(['status' => 'success', 'data' => $contacts]);
exit;
}
if ($action === 'get_messages') {
$id_occupant = isset($_POST['id_occupant']) ? (int)$_POST['id_occupant'] : 0;
// Optional parameter to know who is fetching
$viewer = isset($_POST['viewer']) ? $_POST['viewer'] : 'account';
if ($viewer === 'occupant') {
// Update their online status since they are fetching messages
$updateLastActive = $pdo->prepare("UPDATE occupant SET last_active = NOW() WHERE id_occupant = ?");
$updateLastActive->execute([$id_occupant]);
}
// Mark messages as read based on who is viewing
if ($viewer === 'account') {
$updateStmt = $pdo->prepare("UPDATE chats SET is_read = 1 WHERE id_account = ? AND id_occupant = ? AND sender = 'occupant' AND is_read = 0");
} else {
$updateStmt = $pdo->prepare("UPDATE chats SET is_read = 1 WHERE id_account = ? AND id_occupant = ? AND sender = 'account' AND is_read = 0");
}
$updateStmt->execute([$id_account, $id_occupant]);
// Fetch messages
if ($viewer === 'occupant') {
// If viewed by occupant, don't show deleted ones
$stmt = $pdo->prepare("
SELECT c.*, r.message as reply_message, r.sender as reply_sender, r.id_chat as reply_id_chat
FROM chats c
LEFT JOIN chats r ON c.reply_to_chat_id = r.id_chat
WHERE c.id_account = ? AND c.id_occupant = ? AND c.deleted_by_occupant = 0
ORDER BY c.created_at ASC
");
} else {
$stmt = $pdo->prepare("
SELECT c.*, r.message as reply_message, r.sender as reply_sender, r.id_chat as reply_id_chat
FROM chats c
LEFT JOIN chats r ON c.reply_to_chat_id = r.id_chat
WHERE c.id_account = ? AND c.id_occupant = ?
ORDER BY c.created_at ASC
");
}
$stmt->execute([$id_account, $id_occupant]);
$messages = $stmt->fetchAll();
// Fetch pinned message
$pinStmt = $pdo->prepare("SELECT * FROM chats WHERE id_account = ? AND id_occupant = ? AND is_pinned = 1 ORDER BY created_at DESC LIMIT 1");
$pinStmt->execute([$id_account, $id_occupant]);
$pinned = $pinStmt->fetch();
// Fetch occupant details for header
$occStmt = $pdo->prepare("SELECT * FROM occupant WHERE id_occupant = ?");
$occStmt->execute([$id_occupant]);
$occupant = $occStmt->fetch();
if (empty($occupant['foto']) || !file_exists($occupant['foto'])) {
$occupant['foto'] = 'images/faces/user.jpg';
}
echo json_encode(['status' => 'success', 'data' => $messages, 'occupant' => $occupant, 'pinned' => $pinned]);
exit;
}
if ($action === 'send_message') {
$id_occupant = isset($_POST['id_occupant']) ? (int)$_POST['id_occupant'] : 0;
$message = isset($_POST['message']) ? trim($_POST['message']) : '';
$sender = isset($_POST['sender']) ? $_POST['sender'] : 'account';
$reply_to_chat_id = isset($_POST['reply_to_chat_id']) ? (int)$_POST['reply_to_chat_id'] : null;
// Process File Upload if present
$hasAttachment = false;
$attachmentPath = "";
$attachmentName = "";
$tgEndpoint = "sendMessage";
$tgFileType = "";
$localHtml = "";
if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] === UPLOAD_ERR_OK) {
$hasAttachment = true;
$tmpName = $_FILES['attachment']['tmp_name'];
$attachmentName = $_FILES['attachment']['name'];
$ext = strtolower(pathinfo($attachmentName, PATHINFO_EXTENSION));
$newFileName = time() . '_' . rand(1000, 9999) . '.' . $ext;
$uploadDir = __DIR__ . '/images/chat_uploads/';
if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
$attachmentPath = $uploadDir . $newFileName;
move_uploaded_file($tmpName, $attachmentPath);
$urlRelative = "images/chat_uploads/" . $newFileName;
// Determine type for local HTML and Telegram API
$photoExts = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
$audioExts = ['webm', 'ogg', 'mp3', 'wav', 'oga'];
if (in_array($ext, $photoExts)) {
$tgEndpoint = "sendPhoto";
$tgFileType = "photo";
// msg-type-img will be applied via JS if the content only contains this wrap
$localHtml = "

";
} else if (in_array($ext, $audioExts)) {
$tgEndpoint = "sendVoice";
$tgFileType = "voice";
$localHtml = "";
} else {
$tgEndpoint = "sendDocument";
$tgFileType = "document";
$extLow = strtolower($ext);
$iconClass = 'mdi-file-document-outline';
$bgIconColor = '#94a3b8'; // default slate
if ($extLow === 'pdf') { $iconClass = 'mdi-file-pdf-box'; $bgIconColor = '#ef4444'; } // red
else if (in_array($extLow, ['doc','docx'])) { $iconClass = 'mdi-file-word-box'; $bgIconColor = '#3b82f6'; } // blue
else if (in_array($extLow, ['xls','xlsx'])) { $iconClass = 'mdi-file-excel-box'; $bgIconColor = '#10b981'; } // green
$fileSize = round(filesize($attachmentPath) / 1024);
$sizeStr = $fileSize > 1024 ? round($fileSize/1024, 1) . ' MB' : $fileSize . ' KB';
$typeStr = strtoupper($extLow);
$localHtml = "
{$attachmentName}
{$typeStr} • {$sizeStr}
";
}
// Append text message as caption to local HTML
if (!empty($message)) {
$localHtml .= "".htmlspecialchars($message)."
";
}
} else {
$localHtml = htmlspecialchars($message); // no attachment, just text
}
if ($sender === 'occupant') {
// Keeps occupant online
$updateLastActive = $pdo->prepare("UPDATE occupant SET last_active = NOW() WHERE id_occupant = ?");
$updateLastActive->execute([$id_occupant]);
}
// Only proceed if there is text or an attachment
if ($id_occupant > 0 && (!empty($message) || $hasAttachment)) {
$stmt = $pdo->prepare("INSERT INTO chats (id_account, id_occupant, sender, message, reply_to_chat_id) VALUES (?, ?, ?, ?, ?)");
if ($stmt->execute([$id_account, $id_occupant, $sender, $localHtml, $reply_to_chat_id])) {
$id_chat = $pdo->lastInsertId();
// Fetch Telegram Reply ID if replying
$tgReplyId = null;
if ($reply_to_chat_id) {
$qRep = $pdo->prepare("SELECT telegram_msg_id FROM chats WHERE id_chat = ? LIMIT 1");
$qRep->execute([$reply_to_chat_id]);
$fRep = $qRep->fetch();
if ($fRep && $fRep['telegram_msg_id']) {
$tgReplyId = $fRep['telegram_msg_id'];
}
}
// +++++ SEND TO TELEGRAM IF SENDER IS ACCOUNT +++++
if ($sender === 'account') {
$telStmt = $pdo->prepare("SELECT telegram_id FROM occupant WHERE id_occupant = ?");
$telStmt->execute([$id_occupant]);
$telegramUser = $telStmt->fetch();
if ($telegramUser && !empty($telegramUser['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$website = "https://api.telegram.org/bot".$botToken;
$postData = [
'chat_id' => $telegramUser['telegram_id']
];
// IF Replying
if ($tgReplyId) {
$postData['reply_to_message_id'] = $tgReplyId;
}
// IF Attachment
if ($hasAttachment) {
$postData[$tgFileType] = new CURLFile($attachmentPath);
if (!empty($message)) {
$postData['caption'] = $message;
}
} else {
$postData['text'] = $message;
}
$ch = curl_init($website."/".$tgEndpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$result = curl_exec($ch);
curl_close($ch);
if ($result) {
$resJson = json_decode($result, true);
if (isset($resJson['ok']) && $resJson['ok'] && isset($resJson['result']['message_id'])) {
$tgMsgId = $resJson['result']['message_id'];
$updateMsg = $pdo->prepare("UPDATE chats SET telegram_msg_id = ? WHERE id_chat = ?");
$updateMsg->execute([$tgMsgId, $id_chat]);
}
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++
// WEB PUSH NOTIFICATION DISPATCH
if ($sender === 'occupant') {
// Occupant sends message -> Notify Admins
// Fetch occupant name to display in the push body
$qOcc = $pdo->prepare("SELECT name FROM occupant WHERE id_occupant = ?");
$qOcc->execute([$id_occupant]);
$occName = $qOcc->fetchColumn() ?: "Resident";
$pushTitle = "New Message from {$occName}";
$pushBody = strip_tags($localHtml);
PushHelper::broadcastToAdmins($pdo, $pushTitle, $pushBody, '/chats.php');
} else {
// Admin sends message -> Notify the specific Occupant
$pushTitle = "New Message from Admin";
$pushBody = strip_tags($localHtml);
PushHelper::sendPush($pdo, $id_occupant, $pushTitle, $pushBody, '/chats.php');
}
$msgStmt = $pdo->prepare("SELECT * FROM chats WHERE id_chat = ?");
$msgStmt->execute([$id_chat]);
$newMsg = $msgStmt->fetch();
echo json_encode(['status' => 'success', 'data' => $newMsg]);
exit;
}
}
echo json_encode(['status' => 'error', 'message' => 'Invalid data']);
exit;
}
if ($action === 'login_occupant') {
$no_hp = isset($_POST['no_hp']) ? trim($_POST['no_hp']) : '';
$pin = isset($_POST['pin']) ? trim($_POST['pin']) : '';
if (empty($no_hp) || empty($pin)) {
echo json_encode(['status' => 'error', 'message' => 'Lengkapi form.']);
exit;
}
$stmt = $pdo->prepare("SELECT id_occupant, name, status, access FROM occupant WHERE no_hp = ?");
$stmt->execute([$no_hp]);
$occ = $stmt->fetch();
if ($occ) {
if ($occ['status'] !== 'approved' || $occ['access'] !== 'active') {
echo json_encode(['status' => 'error', 'message' => 'Akun belum disetujui atau sedang tidak aktif.']);
exit;
}
$verifyStmt = $pdo->prepare("SELECT id_occupant FROM occupant WHERE no_hp = ? AND pin = ?");
$verifyStmt->execute([$no_hp, $pin]);
if ($verifyStmt->fetch()) {
$_SESSION['chat_occupant_id'] = $occ['id_occupant'];
echo json_encode(['status' => 'success', 'data' => $occ]);
exit;
}
}
echo json_encode(['status' => 'error', 'message' => 'No HP atau PIN salah.']);
exit;
}
if ($action === 'delete_history') {
$id_occupant = isset($_POST['id_occupant']) ? (int)$_POST['id_occupant'] : 0;
if ($id_occupant > 0) {
$stmt = $pdo->prepare("UPDATE chats SET deleted_by_occupant = 1 WHERE id_account = ? AND id_occupant = ?");
$stmt->execute([$id_account, $id_occupant]);
echo json_encode(['status' => 'success', 'message' => 'Chat history deleted from your view.']);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'Invalid occupant ID.']);
exit;
}
if ($action === 'delete_message') {
$id_chat = isset($_POST['id_chat']) ? (int)$_POST['id_chat'] : 0;
$delete_type = isset($_POST['delete_type']) ? $_POST['delete_type'] : 'me'; // 'me' or 'everyone'
// Validate message belongs to account before deleting
$stmt = $pdo->prepare("SELECT c.sender, c.telegram_msg_id, o.telegram_id
FROM chats c
LEFT JOIN occupant o ON c.id_occupant = o.id_occupant
WHERE c.id_chat = ? AND c.id_account = ?");
$stmt->execute([$id_chat, $id_account]);
$msg = $stmt->fetch();
if ($msg) {
if ($msg['sender'] === 'account') {
// It's the admin's message
// Delete from Database
$delStmt = $pdo->prepare("DELETE FROM chats WHERE id_chat = ?");
$delStmt->execute([$id_chat]);
// Delete from Telegram if exists AND delete_type is 'everyone'
if ($delete_type === 'everyone' && !empty($msg['telegram_msg_id']) && !empty($msg['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$website = "https://api.telegram.org/bot".$botToken;
$postData = [
'chat_id' => $msg['telegram_id'],
'message_id' => $msg['telegram_msg_id']
];
$ch = curl_init($website."/deleteMessage");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_exec($ch);
curl_close($ch);
}
echo json_encode(['status' => 'success']);
exit;
} else {
// It's the occupant's message
// Based on user request, admin can now delete occupant messages from their own view (Delete for Me)
// Occupant messages cannot be deleted from Telegram via bot API anyway
$delStmt = $pdo->prepare("DELETE FROM chats WHERE id_chat = ?");
$delStmt->execute([$id_chat]);
echo json_encode(['status' => 'success']);
exit;
}
}
echo json_encode(['status' => 'error', 'message' => 'Message not found']);
exit;
}
// ── FORWARD MESSAGE ──
if ($action === 'forward_message') {
$id_chat = isset($_POST['id_chat']) ? (int)$_POST['id_chat'] : 0;
$target_occupant = isset($_POST['target_occupant']) ? (int)$_POST['target_occupant'] : 0;
if ($id_chat > 0 && $target_occupant > 0) {
$srcStmt = $pdo->prepare("SELECT message FROM chats WHERE id_chat = ?");
$srcStmt->execute([$id_chat]);
$srcMsg = $srcStmt->fetch();
if ($srcMsg) {
$fwdHtml = " Diteruskan
" . $srcMsg['message'];
$insStmt = $pdo->prepare("INSERT INTO chats (id_account, id_occupant, sender, message) VALUES (?, ?, 'account', ?)");
$insStmt->execute([$id_account, $target_occupant, $fwdHtml]);
$newId = $pdo->lastInsertId();
// Send to Telegram
$telStmt = $pdo->prepare("SELECT telegram_id FROM occupant WHERE id_occupant = ?");
$telStmt->execute([$target_occupant]);
$tgUser = $telStmt->fetch();
if ($tgUser && !empty($tgUser['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$plainText = strip_tags($srcMsg['message']);
$postData = ['chat_id' => $tgUser['telegram_id'], 'text' => "[Diteruskan]\n" . $plainText];
$ch = curl_init("https://api.telegram.org/bot{$botToken}/sendMessage");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$res = curl_exec($ch);
curl_close($ch);
if ($res) {
$rj = json_decode($res, true);
if (isset($rj['ok']) && $rj['ok'] && isset($rj['result']['message_id'])) {
$pdo->prepare("UPDATE chats SET telegram_msg_id = ? WHERE id_chat = ?")->execute([$rj['result']['message_id'], $newId]);
}
}
}
echo json_encode(['status' => 'success']);
exit;
}
}
echo json_encode(['status' => 'error', 'message' => 'Invalid forward data']);
exit;
}
// ── EDIT MESSAGE ──
if ($action === 'edit_message') {
$id_chat = isset($_POST['id_chat']) ? (int)$_POST['id_chat'] : 0;
$new_message = isset($_POST['new_message']) ? trim($_POST['new_message']) : '';
if ($id_chat > 0 && !empty($new_message)) {
// Only allow editing account messages
$stmt = $pdo->prepare("SELECT sender, telegram_msg_id, (SELECT telegram_id FROM occupant WHERE id_occupant = chats.id_occupant) as telegram_id FROM chats WHERE id_chat = ? AND id_account = ?");
$stmt->execute([$id_chat, $id_account]);
$msg = $stmt->fetch();
if ($msg && $msg['sender'] === 'account') {
$formattedHtml = htmlspecialchars($new_message) . " ";
// Update local DB
$updStmt = $pdo->prepare("UPDATE chats SET message = ? WHERE id_chat = ?");
$updStmt->execute([$formattedHtml, $id_chat]);
// Update Telegram if telegram_msg_id exists
if (!empty($msg['telegram_msg_id']) && !empty($msg['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$postData = [
'chat_id' => $msg['telegram_id'],
'message_id' => $msg['telegram_msg_id'],
'text' => $new_message
];
$ch = curl_init("https://api.telegram.org/bot{$botToken}/editMessageText");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_exec($ch);
curl_close($ch);
}
echo json_encode(['status' => 'success', 'new_message' => $formattedHtml]);
exit;
}
}
echo json_encode(['status' => 'error', 'message' => 'Cannot edit this message']);
exit;
}
// ── BULK DELETE MESSAGES ──
if ($action === 'bulk_delete_messages') {
$ids = isset($_POST['id_chats']) ? $_POST['id_chats'] : [];
$deleteType = isset($_POST['delete_type']) ? $_POST['delete_type'] : 'me'; // 'everyone' or 'me'
if (is_array($ids) && count($ids) > 0) {
$deletedCount = 0;
foreach ($ids as $mid) {
$mid = (int)$mid;
if ($mid <= 0) continue;
// Validate message ownership and info
$stmt = $pdo->prepare("SELECT sender, telegram_msg_id, telegram_id FROM chats c LEFT JOIN occupant o ON c.id_occupant = o.id_occupant WHERE id_chat = ? AND id_account = ?");
$stmt->execute([$mid, $id_account]);
$msg = $stmt->fetch();
if ($msg) {
// Determine if we can delete from Telegram
// Only 'account' messages can be deleted from Telegram by the bot.
if ($deleteType === 'everyone' && $msg['sender'] === 'account' && !empty($msg['telegram_msg_id']) && !empty($msg['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$ch = curl_init("https://api.telegram.org/bot{$botToken}/deleteMessage");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'chat_id' => $msg['telegram_id'],
'message_id' => $msg['telegram_msg_id']
]);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_exec($ch);
curl_close($ch);
}
// Delete from DB (applies for both 'me' and 'everyone' types)
$delStmt = $pdo->prepare("DELETE FROM chats WHERE id_chat = ? AND id_account = ?");
$delStmt->execute([$mid, $id_account]);
$deletedCount++;
}
}
echo json_encode(['status' => 'success', 'message' => "Berhasil menghapus $deletedCount pesan."]);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'Tidak ada pesan yang dipilih']);
exit;
}
// ── PIN / UNPIN MESSAGE ──
if ($action === 'pin_message') {
$id_chat = isset($_POST['id_chat']) ? (int)$_POST['id_chat'] : 0;
$id_occupant = isset($_POST['id_occupant']) ? (int)$_POST['id_occupant'] : 0;
if ($id_chat > 0 && $id_occupant > 0) {
// Unpin all first
$pdo->prepare("UPDATE chats SET is_pinned = 0 WHERE id_account = ? AND id_occupant = ?")->execute([$id_account, $id_occupant]);
// Pin this one
$pdo->prepare("UPDATE chats SET is_pinned = 1 WHERE id_chat = ?")->execute([$id_chat]);
echo json_encode(['status' => 'success']);
exit;
}
echo json_encode(['status' => 'error']);
exit;
}
if ($action === 'unpin_message') {
$id_chat = isset($_POST['id_chat']) ? (int)$_POST['id_chat'] : 0;
if ($id_chat > 0) {
$pdo->prepare("UPDATE chats SET is_pinned = 0 WHERE id_chat = ?")->execute([$id_chat]);
echo json_encode(['status' => 'success']);
exit;
}
echo json_encode(['status' => 'error']);
exit;
}
// ── DELETE MULTIPLE MESSAGES ──
if ($action === 'delete_multiple') {
$ids = isset($_POST['ids']) ? json_decode($_POST['ids'], true) : [];
if (is_array($ids) && count($ids) > 0) {
foreach ($ids as $mid) {
$mid = (int)$mid;
$stmt = $pdo->prepare("SELECT sender, telegram_msg_id, (SELECT telegram_id FROM occupant WHERE id_occupant = chats.id_occupant) as telegram_id FROM chats WHERE id_chat = ? AND id_account = ?");
$stmt->execute([$mid, $id_account]);
$m = $stmt->fetch();
if ($m && $m['sender'] === 'account') {
$pdo->prepare("DELETE FROM chats WHERE id_chat = ?")->execute([$mid]);
if (!empty($m['telegram_msg_id']) && !empty($m['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$ch = curl_init("https://api.telegram.org/bot{$botToken}/deleteMessage");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['chat_id' => $m['telegram_id'], 'message_id' => $m['telegram_msg_id']]);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_exec($ch);
curl_close($ch);
}
}
}
echo json_encode(['status' => 'success']);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'No IDs provided']);
exit;
}
if ($action === 'request_call' && $id_occupant) {
$telStmt = $pdo->prepare("SELECT telegram_id FROM occupant WHERE id_occupant = ?");
$telStmt->execute([$id_occupant]);
$telegramUser = $telStmt->fetch();
if ($telegramUser && !empty($telegramUser['telegram_id'])) {
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$website = "https://api.telegram.org/bot".$botToken;
$msg = "📞 *PANGGILAN DARI ADMIN*\n\nAdmin SkyDash sedang mencoba menghubungi Anda via sistem. Silakan merespon melalui obrolan ini.";
$postData = [
'chat_id' => $telegramUser['telegram_id'],
'text' => $msg,
'parse_mode' => 'Markdown'
];
$ch = curl_init($website."/sendMessage");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$result = curl_exec($ch);
curl_close($ch);
if ($result) {
$resJson = json_decode($result, true);
if (isset($resJson['ok']) && $resJson['ok']) {
echo json_encode(['status' => 'success']);
exit;
}
}
}
echo json_encode(['status' => 'error', 'message' => 'Gagal menghubungi Telegram bot penghuni.']);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'Invalid action']);