Files
mikhmon-fix/TELEGRAM-RESET-BUTTON.md
T
2026-08-15 00:28:08 +07:00

8.0 KiB

Telegram Reset Button untuk Notifikasi Expired (MSR Hotspot)

Ringkasan perubahan arsitektur notifikasi expired hotspot & tombol "🔄 Reset" via Telegram. Tanggal: 1 Agu 2026 · RouterOS v6.49.6 · Mikhmon (Docker)


1. Masalah Awal

  1. Notifikasi "User X expired" sebelumnya dikirim oleh notify-expire.php di server Mikhmon, yang menampilkan inline keyboard 🔄 Reset dengan callback_data=reset_<user>.
  2. Router (MikroTik) tidak bisa menjangkau path lama (192.168.100.6, sudah mati). Scheduler di router mengirim notifikasi ke URL Telegram lama yang tidak lagi berfungsi.
  3. Akibatnya pesan expired terkirim tanpa tombol Reset, dan callback reset tidak berfungsi.

2. Solusi Baru (Arsitektur)

[RouterOS Scheduler] --/tool/fetch sendMessage--> [Telegram Bot] --Kirim ke Grup (thread "Notif Expire")
                                                          ^
[User klik 🔄 Reset] --> callback_query --> [Bot] --> poller getUpdates
                                                          |
                                                          v
                      [Host rl] cron tiap menit --> msr-poller.sh --> docker start mikhmon
                                                          |
                                                          v
                                        telegram-cb.php (di container) --> RouterOS API reset user
                                                          |
                                                          v
                          Telegram: "✅ {user} has been reset"

Komponen

Komponen Lokasi Peran
Scheduler RouterOS Router 192.168.100.2 Kirim pesan expired + reply_markup tombol Reset langsung ke Telegram
Telegram Bot 5115036608:AAGey... Terima/teruskan pesan & callback
Cron host /usr/local/bin/msr-poller.sh di rl Setiap menit: docker start mikhmon + curl telegram-cb.php
telegram-cb.php /var/www/html/ di container mikhmon getUpdates → reset user di RouterOS → jawab callback + kirim konfirmasi
lib/routeros_api.class.php /var/www/html/lib/ Koneksi RouterOS API dari PHP

3. Perubahan yang Dilakukan

3.1 Scheduler RouterOS (Family, Bulanan2, Bulanan4)

on-event scheduler sekarang melakukan /tool/fetch ke Telegram sendMessage dengan:

  • chat_id=-1002554941429, message_thread_id=42 (thread "Notif Expire")
  • text=" . $name . "+expired
  • reply_markup = JSON inline keyboard URL-encoded:
%7B%22inline_keyboard%22%3A%5B%5B%7B%22text%22%3A%22%F0%9F%94%84%20Reset%22%2C%22callback_data%22%3A%22reset_" . $name . "%22%7D%5D%5D%7D

yang setara dengan:

{"inline_keyboard":[[{"text":"🔴 Reset","callback_data":"reset_<name>"}]]}

Contoh cuplikan on-event Family:

tool fetch url=("https://api.telegram.org/bot5115036608:AAGey.../sendMessage?chat_id=-1002554941429&message_thread_id=42&text=" . $name . "+expired&reply_markup=" . "%7B%22inline_keyboard%22%3A...%22reset_" . $name . "%22%7D%5D%5D%7D") mode=https http-method=get keep-result=no

Penting: deduplikasi (:if ($curlim = "")) tetap dipertahankan agar setiap user hanya dikirim sekali.

3.2 Container Mikhmon — Install php81-curl

Container PHP 8.1 (Alpine) awalnya tanpa ekstensi cURL → telegram-cb.php error HTTP 500.

docker exec -u root mikhmon apk add --no-cache php81-curl

3.3 Perbaikan include path telegram-cb.php

Dari dirname(__DIR__) . '/lib/routeros_api.class.php' → __DIR__ . '/lib/routeros_api.class.php' (2 tempat), karena file berada langsung di /var/www/html/.

3.4 Poller Host (atasi sablier)

Container mikhmon dikelola sablier (traefik plugin) yang mematikannya setelah 5 menit idle — cron di dalam container tidak bisa diandalkan. Solusi: cron di host yang men-starter container lalu memanggil callback.

/usr/local/bin/msr-poller.sh:

#!/bin/bash
CB_KEY="msr-2026-reset"
URL="http://172.18.0.15/telegram-cb.php?key=${CB_KEY}"
docker start mikhmon >/dev/null 2>&1
sleep 1
curl -s -m 30 "$URL" >/dev/null 2>&1

Crontab host (crontab -l):

* * * * * /usr/local/bin/msr-poller.sh >/dev/null 2>&1

Catatan:

  • docker start idempotent (kalau sudah jalan, no-op) → otomatis menjaga container hidup.
  • Polling maksimal latency ~1 menit setelah klik tombol.

3.5 Callback Handler telegram-cb.php

  • Auth via ?key=msr-2026-reset (403 kalau salah).
  • getUpdates (hanya callback_query).
  • Untuk data berawalan reset_:
    1. Cari user di /ip/hotspot/user/print?name=<user>
    2. set limit-uptime=0, comment='' + reset-counters
    3. Hapus scheduler bernama <user> (jika ada)
    4. answerCallbackQuery (✅ {user} reset!)
    5. sendMessage ke chat/thread: ✅ *{user}* has been reset\nReady to use again
  • User tidak ditemukan → answerCallbackQuery alert User {user} not found (tanpa pesan).
  • Meng-konfirmasi offset via getUpdates?offset=<last_id+1> setelah diproses.

4. Verifikasi

Item Hasil
Pesan expired + tombol Reset muncul di grup ✅ Bubble punya reply-markup-button "Reset"
Klik tombol → callback reset_<user> sampai ke bot ✅ data: "reset_TMR-1" via getUpdates
Poller cron memproses callback ✅ processed: 1
User di-reset di router ✅ limit-uptime 10s → None (unlimited), counters reset
Scheduler user dihapus ✅
Konfirmasi bot di grup ✅ msr_net: TMR-1 has been reset (09:11)

Test user TMR-1 dibuat khusus lalu dihapus setelah verifikasi.

5. Operasional & Troubleshooting

Cek status

  • Poller: ssh rl "cat /usr/local/bin/msr-poller.sh; crontab -l | grep poller"
  • Container: ssh rl "docker ps --filter name=mikhmon --format '{{.Status}}'"
  • Callback pending: curl 'http://172.18.0.15/telegram-cb.php?key=msr-2026-reset' → harus processed: 0 / no updates
  • Webhook tidak terpasang (poller getUpdates aman): getWebhookInfo → url: "", allowed_updates:["callback_query"]

Gejala umum

  • HTTP 500 dari telegram-cb.php → cek cURL: docker exec mikhmon php -r 'var_dump(function_exists("curl_init"));'
  • Container mati → sablier mematikannya setelah 5m idle; poller harusnya men-starter. Cek log poller/cron.
  • Callback tidak terproses → JANGAN baca getUpdates manual (maju offset & poller kehilangan callback). Biarkan poller cron yang memproses.
  • Tombol tidak muncul → reply_markup tidak ter-encode dengan benar; cek verify-markup.py & on-event scheduler.

6. Kredensial & Referensi

  • Router: 192.168.100.2, API remote.vpnmurahjogja.my.id:33206, login mi4/m14
  • Bot: 5115036608:AAGeyXVq5eNvdAkaCQHU9NfH16uAAiSKiuk
  • Chat/Grup: -1002554941429, thread 42 ("Notif Expire")
  • Container: mikhmon (animegasan/mikhmon:v3-latest) di host rl (root@100.100.31.46, ssh alias rl, key ~/.ssh/pl)
  • Callback secret: msr-2026-reset
  • Container IP: 172.18.0.15

7. Skrip Bantu (folder C:\Users\Admin\dev\mikhmon-fix\)

Skrip Fungsi
patch-notif2.py Patch on-event scheduler → tambah reply_markup Reset button
verify-markup.py Verifikasi on-event berisi reply_markup & reset_
verify-notif.py Verifikasi isi scheduler (api.telegram.org, tidak ada URL lama)
dump-sched.py Dump penuh on-event scheduler
telegram-cb.php Callback handler (sumber; di-deploy ke container)
poller.sh Poller host (sumber; di-deploy ke /usr/local/bin/msr-poller.sh)
mk-user.py / rm-user.py Buat / hapus user test
send-expired-tmr.py Kirim pesan expired + tombol untuk user tertentu
check-reset.py Cek limit-uptime & scheduler user setelah reset

8. Catatan

  • Bot menampilkan tombol sebagai "Reset" — teks 🔄 (U+1F504, %F0%9F%94%84) di-render Telegram sebagai ikon 🔄.
  • keep-result=no di scheduler fetch (tidak menyimpan file respons di router). Saat debug bisa ubah keep-result=yes untuk lihat file sendMessage?....
  • Jika tombol ditekan dua kali, user kedua dikirim ulang notif "expired" (karena sudah reset, limit-uptime unlimited → tidak ada scheduler baru sampai limit diubah lagi).