644 lines
29 KiB
PHP
644 lines
29 KiB
PHP
<?php
|
|
session_start();
|
|
include 'koneksi.php';
|
|
require_once 'PushHelper.php'; // Web Push Helper
|
|
|
|
// Default to 1 for development since session wasn't found globally yet.
|
|
$id_account = isset($_SESSION['id_account']) ? $_SESSION['id_account'] : 1;
|
|
|
|
$action = isset($_POST['action']) ? $_POST['action'] : '';
|
|
|
|
// Create chats table if not exists
|
|
$pdo->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 = "<div class='chat-img-wrap' onclick=\"openLightbox('{$urlRelative}')\"><img src='{$urlRelative}' class='chat-img'></div>";
|
|
} else if (in_array($ext, $audioExts)) {
|
|
$tgEndpoint = "sendVoice";
|
|
$tgFileType = "voice";
|
|
$localHtml = "<div class='voice-msg'><button class='voice-play-btn' onclick=\"toggleVoice(this,'{$urlRelative}')\"><i class='mdi mdi-play'></i></button><div class='voice-bar'><div class='voice-progress'></div></div><span class='voice-dur'>0:00</span></div>";
|
|
} 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 = "
|
|
<div class='wa-doc-bubble'>
|
|
<div class='wa-doc-top'>
|
|
<div class='wa-doc-icon' style='background:{$bgIconColor}'><i class='mdi {$iconClass}'></i></div>
|
|
<div class='wa-doc-info'>
|
|
<div class='wa-doc-name'>{$attachmentName}</div>
|
|
<div class='wa-doc-meta'>{$typeStr} • {$sizeStr}</div>
|
|
</div>
|
|
</div>
|
|
<div class='wa-doc-bottom'>
|
|
<a href='{$urlRelative}' target='_blank'>Open</a>
|
|
<a href='{$urlRelative}' download>Save as...</a>
|
|
</div>
|
|
</div>";
|
|
}
|
|
|
|
// Append text message as caption to local HTML
|
|
if (!empty($message)) {
|
|
$localHtml .= "<div class='chat-caption' style='margin-top:8px;'>".htmlspecialchars($message)."</div>";
|
|
}
|
|
} 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 = "<div class='fwd-label'><i class='mdi mdi-share'></i> Diteruskan</div>" . $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) . " <i class='mdi mdi-pencil-outline edit-tag' style='font-size:11px; margin-left:3px;' title='Diedit'></i>";
|
|
|
|
// 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']);
|