xseaqbka/Nawaab_RoBotPublic · Bot Template

AIThis Telegram bot acts as a TOTP authenticator: users can add accounts via Base32 secret, QR code, or otpauth:// URI, list saved keys, and generate current OTP codes on demand with refresh and delete options. It includes an admin panel with user ban/unban, paginated user management, required-channel management, and a broadcast system that sends text, image, or copied replied messages to all private chats. A web dashboard endpoint provides OTP generation and account management over HTTP. The bot also supports an on/off maintenance switch and per-user access gating.

Utilitytotpauthenticatorotp2fabroadcastadmin
ProfileTelegram
59 commands1 envUpdated 10d agoCreated Aug 28, 2026
Back to folder

commands/_handle_callback_query.js

javascript · 432 lines

Raw
1/**#command2name: /handle_callback_query3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12/* Command: /handle_callback_query */13 14if (!update.callback_query) return;15 16const data = String(17  update.callback_query.data || ""18);19 20 21/* =========================================================22   ACKNOWLEDGE CALLBACK23   ========================================================= */24 25Api.answerCallbackQuery({26  callback_query_id:27    update.callback_query.id28});29 30 31/* =========================================================32   STANDARD ROUTES33   ========================================================= */34 35const routes = {36 37  /* User */38  start: "/start",39  menu: "/start",40  help: "/help",41  check_join: "/check_join",42 43  add_key: "/add_key",44  my_keys: "/my_keys",45  about: "/about",46  support: "/support",47 48  close: "/close",49 50  add_secret: "/add_secret",51  add_qr: "/add_qr",52 53  use_detected_name:54    "/use_detected_name",55 56  custom_name:57    "/receive_name",58 59  cancel_add:60    "/cancel_add",61 62 63  /* Admin */64  admin_menu: "/admin_menu",65  admin_help: "/admin_help",66 67  admin_stats: "/admin_stats",68  admin_users: "/admin_users",69 70  channels: "/channels",71 72  bot_status: "/bot_status",73  bot_on: "/bot_on",74  bot_off: "/bot_off",75 76  broadcast: "/broadcast",77 78  broadcast_skip_image:79    "/broadcast_skip_image",80 81  broadcast_skip_buttons:82    "/broadcast_skip_buttons",83 84  broadcast_cancel:85    "/broadcast_cancel",86 87  admin_access:88    "/admin_access",89 90  admin_developer:91    "/admin_developer",92 93  media_settings:94    "/media_settings",95 96  setup: "/setup",97 98 99  /* Support */100  support_settings:101    "/support_settings",102 103  support_set_owner:104    "/support_set_owner",105 106  support_set_channel:107    "/support_set_channel",108 109  support_set_community:110    "/support_set_community",111 112 113  /* Broadcast confirmation */114  bd_confirm:115    "/bd_confirm",116 117  bd_cancel:118    "/bd_cancel"119};120 121 122/* =========================================================123   RUN NORMAL ROUTE124   ========================================================= */125 126if (routes[data]) {127 128  Bot.runCommand(129    routes[data]130  );131 132  return;133}134 135 136/* =========================================================137   VIEW ACCOUNT138   ========================================================= */139 140if (/^view_\d+$/.test(data)) {141 142  Bot.runCommand(143    "/view",144    {145      index: data.slice(5)146    }147  );148 149  return;150}151 152 153/* =========================================================154   DELETE ACCOUNT155   ========================================================= */156 157if (/^delete_\d+$/.test(data)) {158 159  Bot.runCommand(160    "/delete",161    {162      index: data.slice(7)163    }164  );165 166  return;167}168 169 170/* =========================================================171   CONFIRM DELETE172   ========================================================= */173 174if (/^confirm_delete_\d+$/.test(data)) {175 176  Bot.runCommand(177    "/confirm_delete",178    {179      index: data.slice(15)180    }181  );182 183  return;184}185 186 187/* =========================================================188   BAN USER189   ========================================================= */190 191if (/^ban_user_\d+$/.test(data)) {192 193  Bot.runCommand(194    "/ban_user",195    {196      target_id: data.slice(9)197    }198  );199 200  return;201}202 203 204/* =========================================================205   UNBAN USER206   ========================================================= */207 208if (/^unban_user_\d+$/.test(data)) {209 210  Bot.runCommand(211    "/unban_user",212    {213      target_id: data.slice(11)214    }215  );216 217  return;218}219 220 221/* =========================================================222   ADMIN USER ACTION223   ========================================================= */224 225if (/^user_\d+$/.test(data)) {226 227  Bot.runCommand(228    "/admin_user_action",229    {230      target_id: data.slice(5)231    }232  );233 234  return;235}236 237 238/* =========================================================239   ADMIN USERS PAGINATION240   ========================================================= */241 242if (/^admin_users_\d+$/.test(data)) {243 244  Bot.runCommand(245    "/admin_users",246    {247      page: data.slice(12)248    }249  );250 251  return;252}253 254 255/* =========================================================256   KEY BUTTON257   ========================================================= */258 259if (/^key_/.test(data)) {260 261  Bot.runCommand(262    "/view",263    {264      index: data.slice(4)265    }266  );267 268  return;269}270 271 272/* =========================================================273   GOOGLE AUTHENTICATOR MIGRATION274   ========================================================= */275 276if (/^migration_select_\d+$/.test(data)) {277 278  const index = parseInt(279    data.slice(280      "migration_select_".length281    ),282    10283  );284 285  const accounts =286    await db.user.get(287      "pending_qr_accounts",288      []289    );290 291 292  if (293    !Array.isArray(accounts) ||294    !accounts[index]295  ) {296 297    Bot.runCommand(298      "/add_qr"299    );300 301    return;302  }303 304 305  const account =306    accounts[index];307 308 309  const parsed =310    authUtils.parseOtpAuth(311      account.uri312    );313 314 315  if (!parsed) {316 317    Bot.runCommand(318      "/add_qr"319    );320 321    return;322  }323 324 325  await authUtils.savePendingAccount(326    parsed,327    "qr"328  );329 330 331  const detectedName =332    account.name ||333    account.issuer ||334    "Authenticator Account";335 336 337  await db.user.set(338    "pending_detected_name",339    detectedName340  );341 342 343  await authUtils.renderMedia(344 345    "🏷️ <b>Name Your Account</b>\n\n" +346 347    "✅ Account imported successfully.\n\n" +348 349    "Detected name:\n" +350 351    "<code>" +352    authUtils.escapeHtml(353      detectedName354    ) +355    "</code>\n\n" +356 357    "Send a custom name or use the detected name.",358 359    [360 361      [362        authUtils.btn(363          "✨ Use Detected Name",364          "use_detected_name",365          "primary"366        )367      ],368 369      [370        authUtils.btn(371          "✏️ Custom Name",372          "custom_name"373        )374      ],375 376      [377        authUtils.btn(378          "✕ Cancel",379          "cancel_add",380          "danger"381        )382      ]383 384    ],385 386    "key_image"387  );388 389  return;390}391 392 393/* =========================================================394   UNKNOWN CALLBACK395   ========================================================= */396 397Api.sendMessage({398 399  chat_id: chat.id,400 401  text:402    "⚠️ <b>Unknown Action</b>\n\n" +403    "This button is no longer available.\n" +404    "Please open the menu again.",405 406  parse_mode: "HTML",407 408  reply_markup: {409    inline_keyboard: [410 411      [412        {413          text: "🏠 Main Menu",414          callback_data: "start",415          style: "primary"416        }417      ],418 419      [420        {421          text: "✕ Close",422          callback_data: "close",423          style: "danger"424        }425      ]426 427    ]428  }429 430});431 432return;