šŸ› ļø Decrypt-Tools Ultimate Guide

ZeroVPN - Full Setup, Bot Commands & Multi-Account Notification

āš ļø į€žį€į€­į€•į€±į€øį€į€»į€€į€ŗ
ဒီ guide က į€•į€Šį€¬į€›į€±į€ø/į€—į€Ÿį€Æį€žį€Æį€ į€›į€Šį€ŗį€›į€½į€šį€ŗį€į€»į€€į€ŗį€”į€į€½į€€į€ŗį€•į€²į‹ į€žį€®į€øį€žį€”į€·į€ŗ test VPS မှာပဲ run ပါ။ စမ်းပြီးရင် VPS ကို ဖျက်ပစ်ပါ။
šŸ“‘ မာတိကာ
  1. VPS į€”į€žį€…į€ŗ ပြင်ဆင်ခြင်း
  2. Python နဲ့ tools install
  3. Folder ဆောက်ခြင်း & Venv
  4. Library များ Install į€œį€Æį€•į€ŗį€į€¼į€„į€ŗį€ø
  5. XD-Tools.py ကုဒ် (į€”į€•į€¼į€Šį€·į€ŗį€”į€…į€Æį€¶)
  6. Interactive Bot ကုဒ် (Multi-User Noti į€•į€«į€į€„į€ŗ)
  7. BotFather တွင် Commands į€žį€į€ŗį€™į€¾į€į€ŗį€į€¼į€„į€ŗį€ø
  8. Systemd ဖြင့် į€”į€±į€¬į€€į€ŗį€€į€½į€šį€ŗį€™į€¾ Run ခြင်း
  9. Commands များ (ဖွင့်/ပိတ်/ပြန်စ)

နဆင့် ၁ — VPS į€”į€žį€…į€ŗ ပြင်ဆင်ခြင်း

1VPS ကို Update į€œį€Æį€•į€ŗį€•į€«
Terminal
apt update && apt upgrade -y

နဆင့် ၂ — Python နဲ့ tools install

1į€œį€­į€Æį€”į€•į€ŗį€į€²į€· Packages များ Install į€œį€Æį€•į€ŗį€•į€«
Terminal
apt install -y python3 python3-pip python3-venv nano curl tmux unzip

နဆင့် ၃ & ၄ — Folder ဆောက်ခြင်းနှင့် Venv

1Folder ဆောက်ပြီး Venv ဖန်တီးပါ
# Folder ဆောက်ပြီး į€‘į€²į€į€„į€ŗį€•į€«
Terminal
mkdir -p /opt/xd-test && cd /opt/xd-test
# Virtual Environment ဖန်တီးပြီး Activate į€œį€Æį€•į€ŗį€•į€«
Terminal
python3 -m venv venv && source venv/bin/activate
# Library များ Install į€œį€Æį€•į€ŗį€•į€«
Terminal
pip install pycryptodome requests

နဆင့် ၅ — XD-Tools.py တင်ခြင်း

1nano ဖြင့် ကုဒ်ဖိုင်ဖွင့်ပါ
Terminal
nano /opt/xd-test/XD-Tools.py
နောက်က ကုဒ်ကို Copy ကူးပြီး Terminal ထဲ Paste į€œį€Æį€•į€ŗį€•į€«į‹ ပြီးရင် Ctrl+O → Enter → Ctrl+X နှိပ်ပါ။
XD-Tools.py (į€”į€•į€¼į€Šį€·į€ŗį€”į€…į€Æį€¶)
#Python By Bekar VPN Team šŸ˜‚
#Channel → https://t.me/bypassfor
from __future__ import annotations
import argparse
import base64
import json
import os
import re
import sys
import time
import urllib.error
import urllib.request
from Crypto.Cipher import AES


def _qaaa7b7(_v):
    return bytes((_c ^ 73 for _c in _v)).decode()


_q8c737d = _qaaa7b7([33, 61, 61, 57, 58, 115, 102, 102, 49, 45, 100, 57, 58, 100, 40, 57, 32, 100, 58, 57, 32, 39, 39, 44, 59, 103, 63, 44, 59, 42, 44, 37, 103, 40, 57, 57, 102, 44, 121, 121, 125, 61, 33, 103, 35, 58])
_qcd4c4b = _qaaa7b7([33, 61, 61, 57, 58, 115, 102, 102, 49, 45, 100, 57, 58, 100, 40, 57, 32, 100, 44, 39, 51, 103, 63, 44, 59, 42, 44, 37, 103, 40, 57, 57, 102, 49, 45, 36, 40, 58, 61, 44, 59, 45, 44, 42, 38, 45, 44])
_qa9a3ec = _qaaa7b7([33, 61, 61, 57, 115, 102, 102, 49, 45, 100, 57, 58, 100, 40, 57, 32, 100, 61, 49, 61, 103, 63, 44, 59, 42, 44, 37, 103, 40, 57, 57, 102, 49, 45, 32, 36, 57, 38, 59, 22, 45, 44, 42, 44, 48, 57, 61])
_q788f19 = _qaaa7b7([57, 38, 32, 60, 48, 61, 59, 44, 62, 56, 40, 58, 98, 116, 55, 103]).encode()
_q2e62bd = _qaaa7b7([59, 125, 61, 46, 63, 122, 43, 123, 51, 42, 36, 45, 30, 127, 19, 103]).encode()
_q692502 = _qaaa7b7([13, 40, 37, 63, 32, 34, 102, 123, 103, 120, 103, 121, 105, 97, 5, 32, 39, 60, 49, 114, 105, 8, 39, 45, 59, 38, 32, 45, 105, 120, 121, 96])
_qf6fd44 = _qaaa7b7([102, 58, 61, 38, 59, 40, 46, 44, 102, 44, 36, 60, 37, 40, 61, 44, 45, 102, 121, 102, 31, 25, 7, 58, 102, 15, 60, 42, 34, 100, 17, 13, 100, 29, 38, 38, 37, 58, 102])

def _qd771f5(_q3e40b2, _q1c1dff=None, _q91f4db=90):
    _q57804d = {_qaaa7b7([28, 58, 44, 59, 100, 8, 46, 44, 39, 61]): _q692502, _qaaa7b7([8, 42, 42, 44, 57, 61]): _qaaa7b7([40, 57, 57, 37, 32, 42, 40, 61, 32, 38, 39, 102, 35, 58, 38, 39])}
    if _q1c1dff is not None:
        _q57804d[_qaaa7b7([10, 38, 39, 61, 44, 39, 61, 100, 29, 48, 57, 44])] = _qaaa7b7([40, 57, 57, 37, 32, 42, 40, 61, 32, 38, 39, 102, 35, 58, 38, 39])
        _q1c1dff = json.dumps(_q1c1dff).encode()
    _q0f5da9 = urllib.request.Request(_q3e40b2, data=_q1c1dff, headers=_q57804d)
    with urllib.request.urlopen(_q0f5da9, timeout=_q91f4db) as _q586035:
        return _q586035.read().decode(_qaaa7b7([60, 61, 47, 100, 113]), _qaaa7b7([59, 44, 57, 37, 40, 42, 44]))

def _qc5930d(_qd4bd3f: str) -> bytes:
    _q5c608c = base64.b64decode(_qd4bd3f.strip())
    _qb89ed0 = AES.new(_q788f19, AES.MODE_CBC, _q2e62bd).decrypt(_q5c608c)
    _q6db680 = _qb89ed0[-1]
    if 1 <= _q6db680 <= 16 and _qb89ed0[-_q6db680:] == bytes([_q6db680]) * _q6db680:
        _qb89ed0 = _qb89ed0[:-_q6db680]
    return _qb89ed0

def _q54df72(_q1c1dff: bytes) -> str:
    _q6db680 = 16 - len(_q1c1dff) % 16
    _q1c1dff = _q1c1dff + bytes([_q6db680]) * _q6db680
    _q4b9ad9 = AES.new(_q788f19, AES.MODE_CBC, _q2e62bd).encrypt(_q1c1dff)
    return base64.b64encode(_q4b9ad9).decode()

def _q50d85d():
    _q2e6e33 = json.loads(_qd771f5(_qcd4c4b, {_qaaa7b7([63, 57, 39, 22, 39, 40, 36, 44]): _qaaa7b7([22, 22, 49, 45, 22, 37, 32, 58, 61, 22, 22])}))
    _q2178f3 = [_q56c648.strip() for _q56c648 in _q2e6e33.get(_qaaa7b7([58, 60, 57, 57, 38, 59, 61, 44, 45, 22, 63, 57, 39, 58]), []) if _q56c648.strip()]
    if not _q2178f3:
        raise ValueError(_qaaa7b7([58, 60, 57, 57, 38, 59, 61, 44, 45, 22, 63, 57, 39, 58, 105, 44, 36, 57, 61, 48]))
    return _q2178f3

def _qa51ef9():
    _qbabf80 = _qd771f5(_q8c737d)
    _q41c8e3, _q2e6e33 = (_qbabf80.find(_qaaa7b7([18])), _qbabf80.rfind(_qaaa7b7([20])))
    if _q41c8e3 < 0 or _q2e6e33 <= _q41c8e3:
        return {}
    return {_q3f3d38.get(_qaaa7b7([39, 40, 36, 44]), _qaaa7b7([])): _q3f3d38.get(_qaaa7b7([32, 42, 38, 39]), _qaaa7b7([])) for _q3f3d38 in json.loads(_qbabf80[_q41c8e3:_q2e6e33 + 1])}

def _q46d242(_q8d2bd3: str) -> bytes:
    _qbc08a7 = _qd771f5(_qcd4c4b, {_qaaa7b7([63, 57, 39, 22, 39, 40, 36, 44]): _q8d2bd3})
    try:
        _q2e6e33 = json.loads(_qbc08a7)
    except json.JSONDecodeError:
        raise RuntimeError(_qaaa7b7([43, 40, 45, 105, 59, 44, 58, 57, 38, 39, 58, 44, 115, 105]) + _qbc08a7[:200])
    if _qaaa7b7([44, 59, 59, 38, 59]) in _q2e6e33:
        raise RuntimeError(_q2e6e33[_qaaa7b7([44, 59, 59, 38, 59])])
    _q294a2d = _q2e6e33.get(_qaaa7b7([44, 39, 42, 59, 48, 57, 61, 44, 45, 22, 59, 44, 58, 60, 37, 61]))
    if not _q294a2d:
        raise RuntimeError(_qaaa7b7([44, 39, 42, 59, 48, 57, 61, 44, 45, 22, 59, 44, 58, 60, 37, 61, 105, 36, 32, 58, 58, 32, 39, 46]))
    return _qc5930d(_q294a2d)

def _qd16aba(_q8cb9bb: str, _qf6b73d: str=_qaaa7b7([61, 44, 49, 61]), _q424f77: str=_qaaa7b7([47, 32, 37, 44])) -> bytes:
    _q07fe7c = {_qaaa7b7([42, 38, 39, 61, 44, 39, 61]): _q8cb9bb, _qaaa7b7([47, 32, 37, 44, 22, 61, 48, 57, 44]): _qf6b73d, _qaaa7b7([58, 38, 60, 59, 42, 44]): _qaaa7b7([40, 60, 61, 38, 22, 45, 44, 63, 32, 42, 44]), _qaaa7b7([61, 32, 36, 44, 58, 61, 40, 36, 57]): str(int(time.time() * 1000)), _qaaa7b7([47, 32, 37, 44, 39, 40, 36, 44]): _q424f77}
    _qbc08a7 = _qd771f5(_qa9a3ec, _q07fe7c)
    _q2e6e33 = json.loads(_qbc08a7)
    if _qaaa7b7([44, 59, 59, 38, 59]) in _q2e6e33:
        raise RuntimeError(_q2e6e33[_qaaa7b7([44, 59, 59, 38, 59])])
    return _qc5930d(_q2e6e33[_qaaa7b7([44, 39, 42, 59, 48, 57, 61, 44, 45, 22, 59, 44, 58, 60, 37, 61])])

def _q2ecdf7(_q1ea519: str) -> str:
    _q1ea519 = re.sub(_qaaa7b7([18, 21, 21, 102, 115, 99, 118, 107, 117, 119, 53, 21, 49, 121, 121, 100, 21, 49, 120, 47, 20]), _qaaa7b7([22]), _q1ea519).strip()
    return _q1ea519 or _qaaa7b7([60, 39, 39, 40, 36, 44, 45])

def _q3d8aa3(_q1c1dff: bytes) -> str:
    _q17fd91 = _q1c1dff.lstrip()[:1]
    if _q17fd91 == _qaaa7b7([50]).encode():
        return _qaaa7b7([103, 35, 58, 38, 39])
    if _q17fd91 == _qaaa7b7([18]).encode():
        return _qaaa7b7([103, 35, 58, 38, 39])
    return _qaaa7b7([103, 61, 49, 61])

def _q554bcd():
    _q4681cb = argparse.ArgumentParser(description=_qaaa7b7([17, 13, 105, 29, 38, 38, 37, 58, 105, 42, 38, 39, 47, 32, 46, 105, 45, 44, 42, 59, 48, 57, 61, 38, 59]))
    _q4681cb.add_argument(_qaaa7b7([100, 100, 39, 40, 36, 44]), help=_qaaa7b7([45, 44, 42, 59, 48, 57, 61, 105, 58, 32, 39, 46, 37, 44, 105, 63, 57, 39, 105, 43, 48, 105, 39, 40, 36, 44]))
    _q4681cb.add_argument(_qaaa7b7([100, 100, 37, 32, 58, 61]), action=_qaaa7b7([58, 61, 38, 59, 44, 22, 61, 59, 60, 44]), help=_qaaa7b7([58, 33, 38, 62, 105, 58, 60, 57, 57, 38, 59, 61, 44, 45, 105, 63, 57, 39, 105, 39, 40, 36, 44, 58]))
    _q4681cb.add_argument(_qaaa7b7([100, 100, 47, 32, 37, 44]), help=_qaaa7b7([45, 44, 42, 59, 48, 57, 61, 105, 37, 38, 42, 40, 37, 105, 44, 39, 42, 59, 48, 57, 61, 44, 45, 105, 97, 43, 40, 58, 44, 127, 125, 96, 105, 47, 32, 37, 44]))
    _q4681cb.add_argument(_qaaa7b7([100, 100, 38, 60, 61]), default=_qf6fd44, help=_qaaa7b7([38, 60, 61, 57, 60, 61, 105, 45, 32, 59, 44, 42, 61, 38, 59, 48]))
    _q4681cb.add_argument(_qaaa7b7([100, 100, 37, 32, 36, 32, 61]), type=int, default=0, help=_qaaa7b7([36, 40, 49, 105, 42, 38, 39, 47, 32, 46, 58, 105, 97, 121, 116, 40, 37, 37, 96]))
    _q80a28d = _q4681cb.parse_args()
    if _q80a28d.file:
        _q1c1dff = _qc5930d(open(_q80a28d.file, encoding=_qaaa7b7([60, 61, 47, 100, 113])).read())
        _q1cb7c0 = os.path.join(_q80a28d.out, _q2ecdf7(os.path.basename(_q80a28d.file)) + _qaaa7b7([103, 45, 44, 42]))
        os.makedirs(_q80a28d.out, exist_ok=True)
        open(_q1cb7c0, _qaaa7b7([62, 43])).write(_q1c1dff)
        print(_qaaa7b7([18, 98, 20, 105, 58, 40, 63, 44, 45, 115]), _q1cb7c0)
        return
    try:
        _qd0881d = _q50d85d()
    except Exception as _q3f3d38:
        print(_qaaa7b7([18, 100, 20, 105, 37, 32, 58, 61, 105, 47, 44, 61, 42, 33, 105, 47, 40, 32, 37, 44, 45, 115]), _q3f3d38, file=sys.stderr)
        sys.exit(1)
    if _q80a28d.list:
        for _q56c648 in _qd0881d:
            print(_q56c648)
        print(_qaaa7b7([67, 18, 98, 20, 105, 61, 38, 61, 40, 37, 115, 105]) + str(len(_qd0881d)))
        return
    os.makedirs(_q80a28d.out, exist_ok=True)
    _q8ac657 = [_q80a28d.name] if _q80a28d.name else _qd0881d
    if _q80a28d.limit:
        _q8ac657 = _q8ac657[:_q80a28d.limit]
    _q2c85d4 = _q113fa2 = 0
    for _q207d90, _q8d2bd3 in enumerate(_q8ac657, 1):
        _qefcd5b = _qaaa7b7([18]) + str(_q207d90) + _qaaa7b7([102]) + str(len(_q8ac657)) + _qaaa7b7([20, 105]) + str(_q8d2bd3)
        try:
            _q1c1dff = _q46d242(_q8d2bd3)
        except Exception as _q3f3d38:
            print(_qaaa7b7([18, 100, 20, 105]) + str(_qefcd5b) + _qaaa7b7([105, 100, 119, 105]) + str(_q3f3d38))
            _q113fa2 += 1
            continue
        _q0e20ec = os.path.join(_q80a28d.out, _q2ecdf7(_q8d2bd3) + _q3d8aa3(_q1c1dff))
        with open(_q0e20ec, _qaaa7b7([62, 43])) as _q26ba0a:
            _q26ba0a.write(_q1c1dff)
        print(_qaaa7b7([18, 98, 20, 105]) + str(_qefcd5b) + _qaaa7b7([105, 100, 119, 105]) + str(os.path.basename(_q0e20ec)) + _qaaa7b7([105, 97]) + str(len(_q1c1dff)) + _qaaa7b7([105, 43, 48, 61, 44, 58, 96]))
        _q2c85d4 += 1
    print(_qaaa7b7([67, 18, 98, 20, 105, 45, 38, 39, 44, 115, 105]) + str(_q2c85d4) + _qaaa7b7([105, 38, 34, 101, 105]) + str(_q113fa2) + _qaaa7b7([105, 47, 40, 32, 37, 44, 45, 105, 100, 119, 105]) + str(_q80a28d.out))
if __name__ == _qaaa7b7([22, 22, 36, 40, 32, 39, 22, 22]):
    _q554bcd()

နဆင့် ၆ — Interactive Bot ကုဒ် (စတင်တိုင်း į€”į€¬į€øį€œį€Æį€¶į€øį€†į€® Noti į€›į€±į€¬į€€į€ŗį€™į€Šį€ŗ)

1Bot Script ဖိုင်ဖွင့်ပါ
Terminal
nano /opt/xd-test/bot.py
နောက်က ကုဒ်ကို Copy ကူးပြီး Paste į€œį€Æį€•į€ŗį€•į€«į‹
ALLOWED_USERS ထဲမှာ į€Šį€®į€œį€±į€ø į€žį€Æį€¶į€øį€į€»į€„į€ŗį€į€²į€· ID တွေ į€‘į€Šį€·į€ŗį€‘į€¬į€øį€•į€«į‹ Bot စတင်တိုင်း နဲဒီ ID į€”į€¬į€øį€œį€Æį€¶į€øį€†į€®į€€į€­į€Æ Notification į€›į€±į€¬į€€į€ŗį€žį€½į€¬į€øį€•į€«į€™į€šį€ŗį‹
bot.py (į€”į€•į€¼į€Šį€·į€ŗį€”į€…į€Æį€¶)
#!/usr/bin/env python3
import os, sys, zipfile, subprocess, requests, time

# ===== į€Šį€®į€œį€±į€ø į€”į€į€»į€€į€ŗį€”į€œį€€į€ŗ =====
BOT_TOKEN = "8764708526:AAEn-tq7zy1AUdGn8USzl8Eh6ssc6YlY4eU"

# ဒီနေရာမှာ į€Šį€®į€œį€±į€ø į€žį€Æį€¶į€øį€į€»į€„į€ŗį€į€²į€· နကောင့်တွေရဲ့ ID တွေကို į€‘į€Šį€·į€ŗį€•į€«
ALLOWED_USERS = [
    7576434717,   # į€™į€°į€œ နကောင့် (į€™į€±į€¬į€„į€ŗį€žį€Æį€Š)
    # 123456789,  # နောက်ထပ် နကောင့် ID တွေကို į€’į€®į€œį€­į€Æ į€‘į€Šį€·į€ŗį€•į€«
]
# ==============================

WORK_DIR = "/opt/xd-test"
OUT_DIR  = os.path.join(WORK_DIR, "output")
ZIP_PATH = os.path.join(WORK_DIR, "vpn_configs.zip")
TOOL     = os.path.join(WORK_DIR, "XD-Tools.py")
PYTHON   = os.path.join(WORK_DIR, "venv", "bin", "python3")
OFFSET   = 0

def tg_api(method, data=None, files=None):
    url = f"https://api.telegram.org/bot{BOT_TOKEN}/{method}"
    try:
        r = requests.post(url, data=data, files=files, timeout=60)
        return r.json()
    except Exception as e:
        print(f"[!] API Error: {e}", file=sys.stderr)
        return {"ok": False}

def send_message(chat_id, text):
    res = tg_api("sendMessage", data={"chat_id": chat_id, "text": text, "parse_mode": "HTML"})
    if res.get("ok"):
        return res["result"]["message_id"]
    return None

def delete_message(chat_id, msg_id):
    if msg_id:
        tg_api("deleteMessage", data={"chat_id": chat_id, "message_id": msg_id})

def send_document(chat_id, path, caption=""):
    with open(path, "rb") as f:
        tg_api("sendDocument", data={"chat_id": chat_id, "caption": caption}, files={"document": f})

def get_names():
    res = subprocess.run([PYTHON, TOOL, "--list"], capture_output=True, text=True)
    if res.returncode != 0: return []
    names = []
    for line in res.stdout.splitlines():
        line = line.strip()
        if not line or line.startswith("["): continue
        names.append(line)
    return names

def do_zip(chat_id):
    wait_id = send_message(chat_id, "ā³ Downloading all configs to ZIP...\nPlease wait...")
    names = get_names()
    os.makedirs(OUT_DIR, exist_ok=True)
    for f in os.listdir(OUT_DIR): os.remove(os.path.join(OUT_DIR, f))
    ok, fail = 0, 0
    for i, name in enumerate(names, 1):
        r = subprocess.run([PYTHON, TOOL, "--name", name, "--out", OUT_DIR], capture_output=True, text=True)
        if r.returncode == 0: ok += 1
        else: fail += 1
    if os.path.exists(ZIP_PATH): os.remove(ZIP_PATH)
    with zipfile.ZipFile(ZIP_PATH, "w", zipfile.ZIP_DEFLATED) as zf:
        for root, _, files in os.walk(OUT_DIR):
            for fn in files:
                full = os.path.join(root, fn)
                zf.write(full, os.path.relpath(full, OUT_DIR))
    
    delete_message(chat_id, wait_id)
    
    size_mb = os.path.getsize(ZIP_PATH) / (1024 * 1024)
    caption = f"āœ… VPN Configs ZIP\nšŸ“¦ {ok} ok, {fail} failed\nšŸ’¾ {size_mb:.2f} MB"
    if size_mb > 50:
        send_message(chat_id, "āš ļø ZIP > 50MB, splitting...")
        part_size = 45 * 1024 * 1024
        with open(ZIP_PATH, "rb") as f:
            idx = 1
            while True:
                chunk = f.read(part_size)
                if not chunk: break
                pp = f"{ZIP_PATH}.part{idx:02d}"
                with open(pp, "wb") as pf: pf.write(chunk)
                send_document(chat_id, pp, f"Part {idx}\n{caption}")
                os.remove(pp)
                idx += 1
    else:
        send_document(chat_id, ZIP_PATH, caption)
        send_message(chat_id, "āœ… Done!")

def get_single(chat_id, name):
    wait_id = send_message(chat_id, f"ā³ Fetching: {name}...")
    os.makedirs(OUT_DIR, exist_ok=True)
    r = subprocess.run([PYTHON, TOOL, "--name", name, "--out", OUT_DIR], capture_output=True, text=True)
    
    delete_message(chat_id, wait_id)
    
    if r.returncode != 0:
        send_message(chat_id, f"āŒ Failed: {r.stderr[:200]}")
        return
    files = os.listdir(OUT_DIR)
    if not files:
        send_message(chat_id, "āŒ Config file not created.")
        return
    latest = max([os.path.join(OUT_DIR, f) for f in files], key=os.path.getctime)
    ext = os.path.splitext(latest)[1]
    new_path = os.path.join(WORK_DIR, f"{name}{ext}")
    os.rename(latest, new_path)
    send_document(chat_id, new_path, f"āœ… {name}")
    os.remove(new_path)

def main():
    global OFFSET
    print("[*] Bot Started!")
    
    # စတင်တိုင်း ALLOWED_USERS ထဲက į€”į€¬į€øį€œį€Æį€¶į€øį€†į€® Noti į€•į€­į€Æį€·į€™į€šį€ŗ
    for user in ALLOWED_USERS:
        send_message(user, "šŸš€ Decrypt-Tools Bot is Online!")
        time.sleep(0.5) # Telegram API limit မတက်နောင် į€į€į€…į€±į€¬į€„į€·į€ŗį€™į€šį€ŗ

    while True:
        try:
            res = tg_api("getUpdates", data={"offset": OFFSET, "timeout": 30})
            if res.get("ok") and res.get("result"):
                for update in res["result"]:
                    OFFSET = update["update_id"] + 1
                    if "message" not in update or "text" not in update["message"]: continue
                    msg = update["message"]["text"].strip()
                    chat_id = update["message"]["chat"]["id"]
                    
                    if int(chat_id) not in ALLOWED_USERS: 
                        print(f"[!] Unauthorized access attempt by ID: {chat_id}")
                        continue
                        
                    if msg in ["/start", "/help"]:
                        help_txt = (
                            "šŸ¤– Decrypt-Tools Commands\n\n"
                            "šŸ“‹ /list - View all config names\n"
                            "šŸ“¦ /zip - Get all configs as a ZIP file\n"
                            "šŸ“„ /get <name> - Get a single config (e.g., /get SIAM VPN)\n"
                            "šŸ” /check - Check if bot is online\n\n"
                            "Example:\n/get SIAM VPN"
                        )
                        send_message(chat_id, help_txt)
                    elif msg == "/list":
                        wait_id = send_message(chat_id, "ā³ Fetching list...")
                        names = get_names()
                        delete_message(chat_id, wait_id)
                        if not names: 
                            send_message(chat_id, "āŒ No configs found.")
                        else:
                            text = "šŸ“‹ Available Configs:\n" + "\n".join([f"• {n}" for n in names])
                            if len(text) > 4000: text = text[:4000] + "\n\n... (truncated)"
                            send_message(chat_id, text)
                    elif msg == "/zip": 
                        do_zip(chat_id)
                    elif msg.startswith("/get"):
                        parts = msg.split(" ", 1)
                        if len(parts) < 2: 
                            send_message(chat_id, "āš ļø Usage: /get SIAM VPN")
                        else: 
                            get_single(chat_id, parts[1].strip())
                    elif msg == "/check": 
                        send_message(chat_id, "āœ… Bot is running perfectly in the background.")
                    else: 
                        send_message(chat_id, "ā“ Unknown command. Type /help")
        except Exception as e:
            print(f"[!] Loop Error: {e}", file=sys.stderr)
            time.sleep(3)
        time.sleep(1)

if __name__ == "__main__":
    main()

နဆင့် ၇ — BotFather တွင် Commands į€žį€į€ŗį€™į€¾į€į€ŗį€į€¼į€„į€ŗį€ø (English)

1BotFather ဆီ į€žį€½į€¬į€øį€•į€¼į€®į€ø ဒီ Command ကို ရိုက်ပါ
Telegram
/setcommands
2Bot ကို ရွေးပြီး į€”į€±į€¬į€€į€ŗį€•į€«į€…į€¬į€žį€¬į€øį€€į€­į€Æ Copy ကူးပြီး ပို့ပါ
BotFather Commands
start - Start the bot and show help
help - Show available commands
list - View all available VPN config names
zip - Download all configs as a ZIP file
get - Get a single config file (e.g. /get SIAM VPN)
check - Check bot status

နဆင့် ၈ — Systemd ဖြင့် į€”į€±į€¬į€€į€ŗį€€į€½į€šį€ŗį€™į€¾ Run ခြင်း

1Service ဖိုင် ဖန်တီးပါ
Terminal
nano /etc/systemd/system/xdbot.service
# နောက်က ကုဒ်ကို į€‘į€Šį€·į€ŗį€•į€«
xdbot.service
[Unit]
Description=XD-Tools Telegram Bot
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/xd-test
ExecStart=/opt/xd-test/venv/bin/python3 /opt/xd-test/bot.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
2Service ကို စတင် Run ပါ
Terminal
systemctl daemon-reload
systemctl start xdbot
systemctl enable xdbot

နဆင့် ၉ — Commands များ (ဖွင့်/ပိတ်/ပြန်စ)

1Bot ကို ပြန်စရန် (Restart)
Terminal
systemctl restart xdbot
2Bot ကို ရပ်ရန် (Stop)
Terminal
systemctl stop xdbot
3Error Log į€€į€¼į€Šį€·į€ŗį€›į€”į€ŗ
Terminal
journalctl -u xdbot -f