Add Telegram Bot webhook integration

This commit is contained in:
mwpn
2026-01-26 09:27:28 +07:00
parent 3f7f6e1be9
commit 44acff2a35
5 changed files with 737 additions and 76 deletions

266
TELEGRAM_BOT_WEBHOOK.md Normal file
View File

@@ -0,0 +1,266 @@
# 🤖 Telegram Bot Webhook Integration
Dokumentasi untuk integrasi Telegram Bot webhook dengan API.
## 📋 Overview
Webhook Telegram Bot terintegrasi dengan Fast API untuk mengecek tagihan PDAM melalui bot Telegram.
## 🚀 Setup
### 1. Konfigurasi Environment
Pastikan konfigurasi di `.env` sudah benar:
```env
# Telegram API Configuration
TELEGRAM_BOT_TOKEN=8325211525:AAGPN-Ko2UZr-OIshu54jvi_7wzaMClR8SA
# Fast API Configuration (for Telegram Bot)
FAST_API_CLIENT_ID=FAS_1753810437_4ff75b
FAST_API_CLIENT_SECRET=d286ae4f60902d63b72854a38cdaeb9436c6e011f99ad4cf57e512fd6573f711
# Base URL (untuk memanggil Fast API)
BASE_URL=https://api.wipay.id
```
### 2. Set Webhook di Telegram
Set webhook URL ke endpoint API:
**Windows (CMD/PowerShell):**
```cmd
curl -X POST "https://api.telegram.org/bot8325211525:AAGPN-Ko2UZr-OIshu54jvi_7wzaMClR8SA/setWebhook" -d "url=https://api.wipay.id/telegram/webhook"
```
**Linux/Mac:**
```bash
curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \
-d "url=https://api.wipay.id/telegram/webhook"
```
**Atau gunakan browser (Paling Mudah):**
```
https://api.telegram.org/bot8325211525:AAGPN-Ko2UZr-OIshu54jvi_7wzaMClR8SA/setWebhook?url=https://api.wipay.id/telegram/webhook
```
**PowerShell (Alternatif):**
```powershell
Invoke-WebRequest -Uri "https://api.telegram.org/bot8325211525:AAGPN-Ko2UZr-OIshu54jvi_7wzaMClR8SA/setWebhook?url=https://api.wipay.id/telegram/webhook" -Method POST
```
### 3. Verifikasi Webhook
Cek status webhook:
```bash
curl "https://api.telegram.org/bot<BOT_TOKEN>/getWebhookInfo"
```
## 📍 Endpoint
### POST /telegram/webhook
Endpoint untuk menerima update dari Telegram.
**Request:**
- Method: `POST`
- Content-Type: `application/json`
- Body: Telegram Update JSON (dikirim otomatis oleh Telegram)
**Response:**
```json
{
"status": "ok"
}
```
## 🎯 Fitur Bot
### Commands
1. **/start** - Memulai bot dan menampilkan menu utama
2. **/cekid** - Menampilkan ID Telegram user
3. **/tagihan** - Memulai proses cek tagihan
### Menu Inline
1. **Cek Tagihan** - Memulai proses cek tagihan
2. **Cek ID Telegram** - Menampilkan ID Telegram user
3. **Bantuan** - Menampilkan daftar perintah
### Flow Cek Tagihan
1. User klik "Cek Tagihan" atau ketik `/tagihan`
2. Bot meminta nomor pelanggan
3. User memasukkan nomor pelanggan (contoh: `059912`)
4. Bot memanggil Fast API `/fast/check_bill`
5. Bot menampilkan hasil tagihan
## 📁 File Structure
```
tim-backend/timo.wipay.id_api/
├── src/
│ ├── Controllers/
│ │ └── TelegramBotController.php # Controller untuk webhook
│ └── Helpers/
│ ├── TelegramHelper.php # Helper untuk Telegram API
│ └── SessionHelper.php # Helper untuk session management
├── storage/
│ └── telegram_sessions.json # File session (auto-generated)
└── logs/
└── telegram_bot.log # Log bot (auto-generated)
```
## 🔧 Komponen
### TelegramBotController
Controller utama yang menangani webhook:
- `webhook()` - Entry point untuk webhook
- `handleCallbackQuery()` - Handle inline button clicks
- `handleMessage()` - Handle text messages
- `handlePelangganInput()` - Handle nomor pelanggan input
### TelegramHelper
Helper untuk interaksi dengan Telegram API:
- `sendText()` - Kirim pesan teks
- `sendMenu()` - Kirim pesan dengan inline keyboard
- `answerCallback()` - Jawab callback query
- `cleanUtf8()` - Clean UTF-8 text
- `safe()` - Escape HTML
- `log()` - Logging
### SessionHelper
Helper untuk session management (file-based):
- `getSession()` - Ambil session
- `setSession()` - Set session
- `clearSession()` - Hapus session
- `loadSessions()` - Load semua sessions
- `saveSessions()` - Save semua sessions
## 📊 Response Format
### Fast API Response
Bot memanggil `/fast/check_bill` dan memproses response:
```json
{
"status": "success",
"data": {
"errno": 0,
"error": "",
"recordsTotal": 1,
"data": [
{
"pel_nama": "EKSAN HADI",
"pel_alamat": "PERUM AGNIA D1 NO.17",
"rek_bln": 12,
"rek_thn": 2025,
"pemakaian": 11,
"rek_total": 82740,
"rek_ket": "Tagihan Air"
}
]
}
}
```
### Error Cases
1. **errno = 5**: Wajib bayar di loket
2. **recordsTotal = 0**: Tidak ada tagihan
3. **recordsTotal = 1**: Satu tagihan (tampilkan detail)
4. **recordsTotal > 1**: Multiple tagihan (tampilkan list)
## 🔍 Logging
Semua aktivitas bot di-log ke file:
- `logs/telegram_bot.log`
Format log:
```
[2026-01-26 10:30:45] RAW UPDATE: {...}
[2026-01-26 10:30:45] SEND TEXT - Chat ID: 123456, HTTP: 200, Response: {...}
```
## 🛡️ Security
1. **No Authentication Required**: Webhook endpoint tidak memerlukan autentikasi (Telegram akan mengirim request langsung)
2. **Fast API Authentication**: Bot menggunakan API Key untuk memanggil Fast API
3. **Session Management**: Session disimpan di file system (bisa diubah ke database jika diperlukan)
## 🧪 Testing
### Test Webhook Lokal
1. Install ngrok:
```bash
ngrok http 8000
```
2. Set webhook ke ngrok URL:
```bash
curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \
-d "url=https://your-ngrok-url.ngrok.io/telegram/webhook"
```
3. Test dengan mengirim pesan ke bot
### Test dengan cURL
```bash
curl -X POST "http://localhost:8000/telegram/webhook" \
-H "Content-Type: application/json" \
-d '{
"update_id": 123456789,
"message": {
"message_id": 1,
"from": {
"id": 123456789,
"first_name": "Test",
"username": "testuser"
},
"chat": {
"id": 123456789,
"type": "private"
},
"date": 1234567890,
"text": "/start"
}
}'
```
## 📝 Notes
1. **Session Storage**: Saat ini menggunakan file-based storage. Untuk production, pertimbangkan menggunakan database atau Redis.
2. **Error Handling**: Bot akan menampilkan pesan error yang user-friendly jika terjadi masalah.
3. **Rate Limiting**: Telegram memiliki rate limiting sendiri. Tidak perlu implement rate limiting tambahan.
4. **Webhook Security**: Untuk production, pertimbangkan untuk memverifikasi signature dari Telegram (belum diimplementasikan).
## 🔄 Migration dari Script PHP Lama
Script PHP lama sudah di-migrate ke struktur Slim Framework:
- ✅ Semua fungsi sudah di-convert ke class methods
- ✅ Session management menggunakan helper class
- ✅ Telegram API calls menggunakan helper class
- ✅ Logging terintegrasi dengan sistem logging
- ✅ Error handling lebih robust
## 🎯 Next Steps
1. **Database Session**: Migrate session dari file ke database
2. **Webhook Verification**: Implement signature verification
3. **More Commands**: Tambahkan command lain sesuai kebutuhan
4. **Payment Integration**: Integrate dengan payment flow jika diperlukan
---
**Last Updated**: 2026-01-26
**Status**: ✅ Ready for Production

View File

@@ -215,5 +215,9 @@ $app->get('/fast/mandiri/{tanggal}', [$fastController, 'mandiri']);
$app->post('/site/verify_bri', [$siteController, 'verifyBri']); $app->post('/site/verify_bri', [$siteController, 'verifyBri']);
$app->post('/site/approve/{id_trx}', [$siteController, 'approve']); $app->post('/site/approve/{id_trx}', [$siteController, 'approve']);
// Telegram Bot Routes
$telegramBotController = new \App\Controllers\TelegramBotController();
$app->post('/telegram/webhook', [$telegramBotController, 'webhook']);
// Run app // Run app
$app->run(); $app->run();

View File

@@ -0,0 +1,266 @@
<?php
namespace App\Controllers;
use App\Helpers\HttpHelper;
use App\Helpers\ResponseHelper;
use App\Helpers\SessionHelper;
use App\Helpers\TelegramHelper;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
class TelegramBotController
{
private $fastApiId;
private $fastApiSecret;
private $fastApiUrl;
public function __construct()
{
// Get Fast API credentials from environment or config
$this->fastApiId = $_ENV['FAST_API_CLIENT_ID'] ?? 'FAS_1753810437_4ff75b';
$this->fastApiSecret = $_ENV['FAST_API_CLIENT_SECRET'] ?? 'd286ae4f60902d63b72854a38cdaeb9436c6e011f99ad4cf57e512fd6573f711';
$this->fastApiUrl = $_ENV['BASE_URL'] ?? 'https://api.wipay.id';
}
/**
* POST /telegram/webhook
* Webhook endpoint untuk menerima update dari Telegram
*/
public function webhook(Request $request, Response $response): Response
{
try {
// Get raw input
$raw = $request->getBody()->getContents();
TelegramHelper::log("RAW UPDATE: $raw");
$update = json_decode($raw, true);
if (!$update) {
return ResponseHelper::json($response, [
'status' => 'error',
'message' => 'Invalid JSON'
], 400);
}
// Handle callback query (button clicks)
if (isset($update["callback_query"])) {
$this->handleCallbackQuery($update["callback_query"]);
return ResponseHelper::json($response, ['status' => 'ok'], 200);
}
// Handle regular message
if (isset($update["message"])) {
$this->handleMessage($update["message"]);
return ResponseHelper::json($response, ['status' => 'ok'], 200);
}
// Unknown update type
return ResponseHelper::json($response, ['status' => 'ok'], 200);
} catch (\Exception $e) {
error_log("Telegram Webhook Error: " . $e->getMessage());
return ResponseHelper::json($response, [
'status' => 'error',
'message' => $e->getMessage()
], 500);
}
}
/**
* Handle callback query (inline button clicks)
*/
private function handleCallbackQuery($callbackQuery)
{
$chatId = $callbackQuery["message"]["chat"]["id"];
$data = $callbackQuery["data"];
$callbackQueryId = $callbackQuery["id"];
// Answer callback to remove loading state
TelegramHelper::answerCallback($callbackQueryId);
if ($data == "menu_tagihan") {
SessionHelper::clearSession($chatId);
SessionHelper::setSession($chatId, "WAIT_PEL");
TelegramHelper::sendText($chatId,
"Masukkan <b>Nomor Pelanggan</b> PDAM.\nContoh: <code>059912</code>"
);
return;
}
if ($data == "menu_cekid") {
TelegramHelper::sendMenu($chatId, "ID Telegram Anda: <b>$chatId</b>");
return;
}
if ($data == "menu_bantuan") {
TelegramHelper::sendMenu($chatId,
"<b>Perintah Bot:</b>\n" .
"- /cekid\n" .
"- /tagihan\n"
);
return;
}
}
/**
* Handle regular message
*/
private function handleMessage($message)
{
$chatId = $message["chat"]["id"];
$text = $message["text"] ?? "";
$firstName = TelegramHelper::safe($message["from"]["first_name"] ?? "Pelanggan");
$username = TelegramHelper::safe($message["from"]["username"] ?? "");
$displayName = $username ? "@$username" : $firstName;
// Handle commands
if ($text == "/start") {
SessionHelper::clearSession($chatId);
$msg = "Halo $displayName\n" .
"Selamat datang di <b>Tirta Intan Mobile Bot</b>.\n\n" .
"Gunakan menu di bawah untuk memulai.";
TelegramHelper::sendMenu($chatId, $msg);
return;
}
if ($text == "/cekid") {
TelegramHelper::sendMenu($chatId, "ID Telegram Anda: <b>$chatId</b>");
return;
}
if ($text == "/tagihan") {
SessionHelper::clearSession($chatId);
SessionHelper::setSession($chatId, "WAIT_PEL");
TelegramHelper::sendText($chatId,
"Masukkan <b>Nomor Pelanggan</b> PDAM.\nContoh: <code>059912</code>"
);
return;
}
// Handle user input based on session
$session = SessionHelper::getSession($chatId);
if ($session == "WAIT_PEL") {
$this->handlePelangganInput($chatId, $text);
return;
}
// Unknown command
TelegramHelper::sendMenu($chatId,
"Perintah tidak dikenali.\nGunakan menu di bawah atau ketik /bantuan."
);
}
/**
* Handle pelanggan number input
*/
private function handlePelangganInput($chatId, $text)
{
$pelNo = preg_replace('/\D/', '', $text);
SessionHelper::clearSession($chatId);
TelegramHelper::log("User input pel_no: $pelNo");
// Call Fast API check_bill
$url = $this->fastApiUrl . "/fast/check_bill";
$payload = json_encode(["no_sl" => $pelNo]);
TelegramHelper::log("CALL FAST API: $url payload=$payload");
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"X-Client-ID: " . $this->fastApiId,
"X-Client-Secret: " . $this->fastApiSecret
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$apiResponse = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
TelegramHelper::log("FAST API RESPONSE (HTTP $httpCode): $apiResponse");
$res = json_decode($apiResponse, true);
// Safety check if response failed
if (!$res || !isset($res["data"])) {
TelegramHelper::sendMenu($chatId,
"Terjadi kesalahan saat menghubungi server.\nSilakan coba lagi nanti."
);
return;
}
$data = $res["data"];
$errno = $data["errno"] ?? -1;
$error = TelegramHelper::safe($data["error"] ?? "");
$rows = $data["data"] ?? [];
$count = $data["recordsTotal"] ?? 0;
// CASE: WAJIB DI LOKET (errno 5)
if ($errno == 5) {
$msg = "Nomor pelanggan <b>" . TelegramHelper::safe($pelNo) . "</b> $error.\n\n" .
"Silakan bayar di loket PDAM atau hubungi:\n<b>+62 823-8891-0073 (Rais Haerullah)</b>.";
TelegramHelper::sendMenu($chatId, $msg);
return;
}
// CASE: TIDAK ADA TAGIHAN
if ($count == 0) {
$msg = "Tidak ada tagihan untuk nomor pelanggan <b>" . TelegramHelper::safe($pelNo) . "</b>.\n" .
"Status: $error";
TelegramHelper::sendMenu($chatId, $msg);
return;
}
// CASE: SATU TAGIHAN
if ($count == 1) {
$r = $rows[0];
$msg = "<b>Tagihan PDAM Tirta Intan</b>\n\n" .
"Nama: <b>" . TelegramHelper::safe($r["pel_nama"]) . "</b>\n" .
"Alamat: " . TelegramHelper::safe($r["pel_alamat"]) . "\n" .
"Bulan: " . $r["rek_bln"] . " / " . $r["rek_thn"] . "\n" .
"Pemakaian: " . $r["pemakaian"] . " m3\n\n" .
"Total Tagihan: <b>Rp " . number_format($r["rek_total"], 0, ',', '.') . "</b>\n\n";
TelegramHelper::sendMenu($chatId, $msg);
return;
}
// CASE: MULTI TAGIHAN
$nama = TelegramHelper::safe($rows[0]["pel_nama"] ?? "");
$alamat = TelegramHelper::safe($rows[0]["pel_alamat"] ?? "");
$list = "";
$sum = 0;
foreach ($rows as $row) {
$bln = $row["rek_bln"];
$thn = $row["rek_thn"];
$ket = TelegramHelper::safe($row["rek_ket"]);
$amt = (int)$row["rek_total"];
$sum += $amt;
$list .= "- " . $bln . "/" . $thn . " (" . $ket . ") - Rp " . number_format($amt, 0, ',', '.') . "\n";
}
$msg = "<b>Tagihan PDAM Tirta Intan</b>\n\n" .
"Nama: <b>$nama</b>\n" .
"Alamat: $alamat\n\n" .
"<b>Daftar Tagihan:</b>\n" .
$list . "\n" .
"<b>Total: Rp " . number_format($sum, 0, ',', '.') . "</b>";
TelegramHelper::sendMenu($chatId, $msg);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Helpers;
class SessionHelper
{
private static $sessionFile;
private static function getSessionFile()
{
if (self::$sessionFile === null) {
$storageDir = __DIR__ . "/../../storage";
if (!file_exists($storageDir)) {
mkdir($storageDir, 0777, true);
}
self::$sessionFile = $storageDir . "/telegram_sessions.json";
}
return self::$sessionFile;
}
/**
* Load all sessions
*/
public static function loadSessions()
{
$file = self::getSessionFile();
if (!file_exists($file)) {
file_put_contents($file, json_encode(["sessions" => []], JSON_PRETTY_PRINT));
}
$json = json_decode(file_get_contents($file), true);
return $json["sessions"] ?? [];
}
/**
* Save all sessions
*/
public static function saveSessions($sessions)
{
$file = self::getSessionFile();
file_put_contents($file, json_encode(["sessions" => $sessions], JSON_PRETTY_PRINT));
}
/**
* Get session for a chat ID
*/
public static function getSession($chatId)
{
$sessions = self::loadSessions();
return $sessions[$chatId] ?? null;
}
/**
* Set session for a chat ID
*/
public static function setSession($chatId, $value)
{
$sessions = self::loadSessions();
$sessions[$chatId] = $value;
self::saveSessions($sessions);
}
/**
* Clear session for a chat ID
*/
public static function clearSession($chatId)
{
$sessions = self::loadSessions();
unset($sessions[$chatId]);
self::saveSessions($sessions);
}
}

View File

@@ -4,108 +4,160 @@ namespace App\Helpers;
class TelegramHelper class TelegramHelper
{ {
private static $botToken = null; private static $apiURL;
private static $adminTransaction = []; private static $botToken;
private static $adminGangguan = [];
/** public static function init()
* Initialize Telegram config from environment
*/
private static function init()
{ {
if (self::$botToken === null) { self::$botToken = $_ENV['TELEGRAM_BOT_TOKEN'] ?? '';
self::$botToken = $_ENV['TELEGRAM_BOT_TOKEN'] ?? '8325211525:AAGPN-Ko2UZr-OIshu54jvi_7wzaMClR8SA'; self::$apiURL = "https://api.telegram.org/bot" . self::$botToken . "/";
self::$adminTransaction = explode(',', $_ENV['TELEGRAM_ADMIN_TRANSACTION'] ?? '1128050689');
self::$adminGangguan = explode(',', $_ENV['TELEGRAM_ADMIN_GANGGUAN'] ?? '237213251,257394015');
}
} }
/** /**
* Send Telegram message * Clean UTF-8 text
*/ */
public static function sendTelegram($pesan, $chatIds = null) public static function cleanUtf8($text)
{
if (!is_string($text)) {
$text = (string)$text;
}
// Remove carriage return
$text = str_replace("\r", '', $text);
// Ensure UTF-8
if (function_exists('mb_detect_encoding')) {
if (!mb_detect_encoding($text, 'UTF-8', true)) {
$text = mb_convert_encoding($text, 'UTF-8', 'UTF-8,ISO-8859-1,Windows-1252');
}
} else {
$text = iconv('UTF-8', 'UTF-8//IGNORE', $text);
}
// Remove control characters (except newline and tab)
$text = preg_replace('/[^\P{C}\n\t]+/u', '', $text);
return $text;
}
/**
* Safe string for HTML
*/
public static function safe($str)
{
$str = self::cleanUtf8($str ?? "");
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
/**
* Send text message
*/
public static function sendText($chatId, $text)
{ {
self::init(); self::init();
if (empty($pesan)) { $text = self::cleanUtf8($text);
return false;
}
if ($chatIds === null) { $params = [
$chatIds = self::$adminTransaction; "chat_id" => $chatId,
} "text" => $text,
"parse_mode" => "HTML"
];
if (!is_array($chatIds)) { $ch = curl_init(self::$apiURL . "sendMessage");
$chatIds = [$chatIds]; curl_setopt($ch, CURLOPT_POST, true);
} curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$res = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$url = 'https://api.telegram.org/bot' . self::$botToken . '/sendMessage'; self::log("SEND TEXT - Chat ID: $chatId, HTTP: $httpCode, Response: $res");
$successCount = 0;
$failedCount = 0;
foreach ($chatIds as $chatId) { return json_decode($res, true);
$data = [ }
'chat_id' => $chatId,
'text' => $pesan, /**
'parse_mode' => 'Markdown' * Send message with inline keyboard
*/
public static function sendMenu($chatId, $text, $keyboard = null)
{
self::init();
$text = self::cleanUtf8($text);
if ($keyboard === null) {
$keyboard = [
"inline_keyboard" => [
[
["text" => "Cek Tagihan", "callback_data" => "menu_tagihan"]
],
[
["text" => "Cek ID Telegram", "callback_data" => "menu_cekid"]
],
[
["text" => "Bantuan", "callback_data" => "menu_bantuan"]
]
]
]; ];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($data),
CURLOPT_TIMEOUT => 30,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
error_log('Telegram API - cURL Error for Chat ID ' . $chatId . ': ' . $error);
$failedCount++;
continue;
}
if ($httpCode == 200) {
$result = json_decode($response, true);
if (isset($result['ok']) && $result['ok'] === true) {
error_log('Telegram API - Message sent successfully to Chat ID: ' . $chatId);
$successCount++;
} else {
error_log('Telegram API - Error for Chat ID ' . $chatId . ': ' . ($result['description'] ?? 'Unknown error'));
$failedCount++;
}
} else {
error_log('Telegram API - HTTP Error ' . $httpCode . ' for Chat ID ' . $chatId);
$failedCount++;
}
} }
return $successCount > 0; $params = [
"chat_id" => $chatId,
"text" => $text,
"parse_mode" => "HTML",
"reply_markup" => json_encode($keyboard)
];
$ch = curl_init(self::$apiURL . "sendMessage");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$res = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
self::log("SEND MENU - Chat ID: $chatId, HTTP: $httpCode, Response: $res");
return json_decode($res, true);
} }
/** /**
* Send to transaction admin * Answer callback query
*/ */
public static function sendToTransactionAdmin($pesan) public static function answerCallback($callbackQueryId, $text = null, $showAlert = false)
{ {
self::init(); self::init();
return self::sendTelegram($pesan, self::$adminTransaction);
$params = [
"callback_query_id" => $callbackQueryId,
"text" => $text,
"show_alert" => $showAlert
];
$ch = curl_init(self::$apiURL . "answerCallbackQuery");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$res = curl_exec($ch);
curl_close($ch);
return json_decode($res, true);
} }
/** /**
* Send to gangguan admin * Log message (public static untuk bisa dipanggil dari controller)
*/ */
public static function sendToGangguanAdmin($pesan) public static function log($message)
{ {
self::init(); $logFile = __DIR__ . "/../../logs/telegram_bot.log";
return self::sendTelegram($pesan, self::$adminGangguan); $logDir = dirname($logFile);
if (!file_exists($logDir)) {
mkdir($logDir, 0777, true);
}
$timestamp = date("Y-m-d H:i:s");
file_put_contents($logFile, "[$timestamp] $message\n", FILE_APPEND);
} }
} }