TKK_E32230273/bot_polling.php

242 lines
13 KiB
PHP

<?php
// bot_polling.php - Script untuk menjalankan Telegram Bot via Long Polling di Localhost
// Jalankan via CLI: php bot_polling.php
include 'koneksi.php';
$botToken = "8184881871:AAFOz6uzIgxE7rk3WttcKKrr0DtcNGIt-Ho";
$website = "https://api.telegram.org/bot" . $botToken;
echo "Memulai Telegram Bot (Polling Mode)...\n";
echo "Tekan Ctrl+C untuk berhenti.\n\n";
// Fungsi untuk request API
function request($url, $postData = []) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (!empty($postData)) {
curl_setopt($ch, CURLOPT_POST, 1);
// Penting: gunakan JSON untuk reply_markup jika berbentuk array
if(isset($postData['reply_markup']) && is_array($postData['reply_markup'])) {
$postData['reply_markup'] = json_encode($postData['reply_markup']);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$res = curl_exec($ch);
curl_close($ch);
return json_decode($res, true);
}
// Fungsi Download File dari Telegram
function downloadTelegramFile($fileId, $botToken, $type, $originalName = "") {
$urlGetFile = "https://api.telegram.org/bot{$botToken}/getFile?file_id={$fileId}";
$res = json_decode(file_get_contents($urlGetFile), true);
if (isset($res['ok']) && $res['ok']) {
$filePathApi = $res['result']['file_path'];
$downloadUrl = "https://api.telegram.org/file/bot{$botToken}/{$filePathApi}";
$ext = pathinfo($filePathApi, PATHINFO_EXTENSION);
$fileName = time() . '_' . rand(1000, 9999) . '.' . $ext;
if (!empty($originalName)) {
$fileName = time() . '_' . preg_replace('/[^A-Za-z0-9.\-_]/', '', $originalName);
}
$savePath = __DIR__ . '/images/chat_uploads/' . $fileName;
file_put_contents($savePath, file_get_contents($downloadUrl));
$urlRelative = "images/chat_uploads/" . $fileName;
if ($type === "Photo") {
return "<a href='{$urlRelative}' target='_blank'><img src='{$urlRelative}' style='max-width:200px; border-radius:8px; display:block;'></a>";
} else if ($type === "Video") {
return "<video controls style='max-width:200px; border-radius:8px;'><source src='{$urlRelative}' type='video/mp4'></video>";
} else if ($type === "Voice") {
return "<audio controls style='max-width:220px;'><source src='{$urlRelative}' type='audio/ogg'></audio>";
} else {
return "<a href='{$urlRelative}' target='_blank' style='display:flex; align-items:center; gap:12px; padding:10px; background:rgba(0,0,0,0.05); border-radius:8px; text-decoration:none; color:inherit;'>
<i class='mdi mdi-file-document-outline' style='font-size:32px; color:#4b49ac;'></i>
<span style='font-weight:600; font-size:13px; word-break:break-all;'>{$fileName}</span>
</a>";
}
}
return "[Attachment Failed]";
}
// Hapus Webhook jika sebelumnya pernah diset (Webhook dan Polling tidak bisa bersamaan)
request($website . "/deleteWebhook");
$offset = 0;
while (true) {
// Ambil data (Long Polling)
$response = request($website . "/getUpdates", [
'offset' => $offset,
'timeout' => 20 // Tahan koneksi sampai 20 detik jika tak ada pesan baru
]);
if (!empty($response['ok']) && !empty($response['result'])) {
foreach ($response['result'] as $update) {
$offset = $update['update_id'] + 1; // Update offset agar pesan ini tidak ditarik lagi
if (isset($update["message"])) {
$chatId = $update["message"]["chat"]["id"];
$username = isset($update["message"]["from"]["first_name"]) ? $update["message"]["from"]["first_name"] : "User";
echo "[".date('Y-m-d H:i:s')."] Pesan dari $username ($chatId): ";
// Command /start
if (isset($update["message"]["text"]) && $update["message"]["text"] === "/start") {
echo "/start\n";
$text = "Halo! Saya adalah *Identia*.\n\n"
. "Penting untuk diketahui: *Ini bukanlah Bot otomatis yang bisa menjawab secara otomatis*. Ini adalah *saluran interaksi langsung* untuk terhubung secara personal dengan Admin Identia.\n\n"
. "Namun, untuk memulai obrolan langsung dengan Admin, kami perlu memverifikasi data Anda terlebih dahulu.\n\n"
. "👇 *Silakan klik tombol di bawah ini untuk Membagikan Kontak Anda* agar kami dapat mencocokkan nomor handphone Anda dengan sistem kami.";
$postData = [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'Markdown',
'reply_markup' => [
'keyboard' => [
[ ['text' => '📱 Bagikan Kontak Saya', 'request_contact' => true] ]
],
'resize_keyboard' => true,
'one_time_keyboard' => true
]
];
request($website."/sendMessage", $postData);
continue; // lanjut ke update berikutnya
}
// Konfirmasi / Cek Nomor HP
if (isset($update["message"]["contact"])) {
$phoneNumber = $update["message"]["contact"]["phone_number"];
echo "[Share Contact: $phoneNumber]\n";
$normalizedPhone = preg_replace('/^\+?62/', '0', $phoneNumber);
// Cek database di tabel occupant
try { $pdo->exec("ALTER TABLE occupant ADD COLUMN telegram_id VARCHAR(100) NULL AFTER no_hp"); } catch(PDOException $e) {}
$stmt = $pdo->prepare("SELECT id_occupant FROM occupant WHERE no_hp = ? OR no_hp = ? OR no_hp = ?");
$stmt->execute([
$phoneNumber,
$normalizedPhone,
"62" . ltrim($normalizedPhone, '0')
]);
$occupant = $stmt->fetch(PDO::FETCH_ASSOC);
if ($occupant) {
$updateStmt = $pdo->prepare("UPDATE occupant SET telegram_id = ? WHERE id_occupant = ?");
$updateStmt->execute([$chatId, $occupant['id_occupant']]);
$text = "✅ *Verifikasi Berhasil!*\n\n"
. "Nomor Anda telah terverifikasi sebagai Penghuni *Identia* yang sah.\n\n"
. "Saat ini, Anda sudah *Terhubung Langsung* dengan saluran pribadi Admin *Identia*.\n\n"
. "Silakan sampaikan pertanyaan, laporan kendala, atau pesan Anda di sini kapan pun Anda butuhkan. Admin akan membalas pesan Anda dari Control Panel sesegera mungkin.";
$postData = [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'Markdown',
'reply_markup' => ['remove_keyboard' => true]
];
request($website."/sendMessage", $postData);
} else {
$postData = [
'chat_id' => $chatId,
'text' => "❌ Maaf, nomor handphone Anda ($phoneNumber) tidak ditemukan pada daftar penghuni Identia.\n\nPastikan Anda mendaftar melalui Admin terlebih dahulu."
];
request($website."/sendMessage", $postData);
}
continue;
}
// Handle Teks Biasa (Occupant membalas/chat ke Admin)
if (isset($update["message"])) {
$msgObj = $update["message"];
$textMessage = "";
$captionStr = isset($msgObj["caption"]) ? htmlspecialchars($msgObj["caption"]) : "";
if (isset($msgObj["text"])) {
$textMessage = htmlspecialchars($msgObj["text"]);
echo "Teks: $textMessage\n";
} else {
// Kalau bukan text biasa, kita abaikan saja agar tidak tersimpan di database
continue;
}
if (!empty($textMessage)) {
try { $pdo->exec("ALTER TABLE occupant ADD COLUMN telegram_id VARCHAR(100) NULL AFTER no_hp"); } catch(PDOException $e) {}
$stmt = $pdo->prepare("SELECT id_occupant FROM occupant WHERE telegram_id = ?");
$stmt->execute([$chatId]);
$occupant = $stmt->fetch(PDO::FETCH_ASSOC);
if ($occupant) {
$id_account = 1;
try { $pdo->exec("ALTER TABLE chats ADD COLUMN reply_to_chat_id INT NULL AFTER telegram_msg_id"); } catch(PDOException $e) {}
$replyToId = null;
if (isset($msgObj['reply_to_message']) && isset($msgObj['reply_to_message']['message_id'])) {
$tgReplyId = $msgObj['reply_to_message']['message_id'];
// Temukan chat lokal berdasarkan telegram_msg_id
$qRep = $pdo->prepare("SELECT id_chat FROM chats WHERE telegram_msg_id = ? LIMIT 1");
$qRep->execute([$tgReplyId]);
$foundRep = $qRep->fetch();
if ($foundRep) $replyToId = $foundRep['id_chat'];
}
$insertStmt = $pdo->prepare("INSERT INTO chats (id_account, id_occupant, sender, message, is_read, telegram_msg_id, reply_to_chat_id) VALUES (?, ?, 'occupant', ?, 0, ?, ?)");
$insertStmt->execute([$id_account, $occupant['id_occupant'], $textMessage, $msgObj['message_id'], $replyToId]);
// ALL PREVIOUS MESSAGES TO THIS USER ARE NOW READ
try {
$pdo->exec("UPDATE chats SET is_read = 1 WHERE id_occupant = {$occupant['id_occupant']} AND sender = 'account'");
} catch(PDOException $e) {}
try { $pdo->exec("ALTER TABLE occupant ADD COLUMN last_active DATETIME NULL"); } catch(PDOException $e) {}
$updateLastActive = $pdo->prepare("UPDATE occupant SET last_active = NOW() WHERE id_occupant = ?");
$updateLastActive->execute([$occupant['id_occupant']]);
} else {
$postData = [
'chat_id' => $chatId,
'text' => "Sesi chat Anda belum terhubung dengan Identia.\n\nSilakan kirim perintah /start lalu klik tombol 'Bagikan Kontak Saya' terlebih dahulu untuk memulai obrolan dengan Admin."
];
request($website."/sendMessage", $postData);
}
}
}
}
// Handle Pesan Diedit (Occupant mengedit pesan di Telegram)
if (isset($update["edited_message"])) {
$chatId = $update["edited_message"]["chat"]["id"];
if (isset($update["edited_message"]["text"])) {
$editedText = $update["edited_message"]["text"];
$messageId = $update["edited_message"]["message_id"];
$stmt = $pdo->prepare("SELECT id_occupant FROM occupant WHERE telegram_id = ?");
$stmt->execute([$chatId]);
$occupant = $stmt->fetch(PDO::FETCH_ASSOC);
if ($occupant) {
$newText = htmlspecialchars($editedText) . " <i class='mdi mdi-pencil-outline edit-tag' style='font-size:11px; margin-left:3px;' title='Diedit'></i>";
$updateStmt = $pdo->prepare("UPDATE chats SET message = ? WHERE telegram_msg_id = ? AND id_occupant = ?");
$updateStmt->execute([$newText, $messageId, $occupant['id_occupant']]);
}
}
}
}
} else {
// Sleep sebentar jika tidak ada payload baru sebelum lanjut polling
sleep(1);
}
}
?>