indrajitghosh20006/Igstore_01botPublic ยท Bot Template

ProfileTelegram

AIThe bot provides an admin interface for a digital store, allowing the owner or coโ€‘admins to add balances, products, plans, and categories. It supports payment workflows via UPI and Binance Pay, automatically generating QR codes and handling manual approval of deposits. The code patches inline keyboards to use premium emoji icons and includes helper functions for user and bot properties. Overall, it serves as a commerce management tool for a Telegram-based storefront.

Commercestoreadminbalanceproductplancategory
170 commands0 envUpdated 7h agoCreated Oct 30, 2026
Back to folder

commands/_start.js

javascript ยท 1047 lines

Raw
1/**#command2name: /start3answer: 4keyboard: 5parse_mode: markdown6aliases: /START,/Start,/STArt,/stARt7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// PREMIUM BUTTON ICONS13(function(){14  try {15    if (!JSON.__premiumPatched) {16      var __origStringify = JSON.stringify;17      JSON.stringify = function(value, replacer, space) {18        try {19          if (value && value.inline_keyboard && Array.isArray(value.inline_keyboard)) {20            var premiumIds = [21              "6143444134125379822",22              "6091379307907652768",23              "6147534454819661264",24              "6147817325660741985",25              "6235683689292897318",26              "6102856637343600044"27            ];28            var rows = value.inline_keyboard.map(function(row, ri) {29              if (!Array.isArray(row)) return row;30              return row.map(function(btn, bi) {31                if (!btn || typeof btn !== "object") return btn;32                var copy = {};33                for (var k in btn) copy[k] = btn[k];34                if (!copy.icon_custom_emoji_id) copy.icon_custom_emoji_id = premiumIds[(ri + bi) % premiumIds.length];35                return copy;36              });37            });38            var cloned = {};39            for (var key in value) cloned[key] = value[key];40            cloned.inline_keyboard = rows;41            return __origStringify.call(JSON, cloned, replacer, space);42          }43        } catch (e) {}44        return __origStringify.call(JSON, value, replacer, space);45      };46      JSON.__premiumPatched = true;47    }48  } catch (e) {}49})();50 51 52 53try { 54  // One-time migration of legacy owner IDs to the current admin/owner.55  var storedOwnerId = String(Bot.getProperty("owner_id") || "");56  if (!storedOwnerId || ["7839151435"].indexOf(storedOwnerId) !== -1) {57    Bot.setProperty("owner_id", "7839151435", "string");58  }59  var currentStoreName = String(Bot.getProperty("store_name") || "");60  if (!currentStoreName || currentStoreName === "๐™„๐™‚ ๐™Ž๐™๐™Š๐™๐™€" || currentStoreName === "๐™„๐™‚ ๐™Ž๐™๐™Š๐™๐™€") {61    Bot.setProperty("store_name", "๐™„๐™‚ ๐™Ž๐™๐™Š๐™๐™€", "string");62  }63  var adminId = Bot.getProperty("owner_id") || "7839151435";64  var userId = String(user.telegramid);65  var uid = userId;66 67  // โญ TELEGRAM STARS โ€” fallback event detection (payment events may route here68  // generically depending on the platform, so we check and delegate explicitly)69  if (request && request.pre_checkout_query) {70    Bot.run({ command: "/onPreCheckoutQuery" });71    return;72  }73  if (request && request.message && request.message.successful_payment) {74    Bot.run({ command: "/onSuccessfulPayment" });75    return;76  }77  78  // Safe variable fallbacks for BJS environment79  var msgText = (typeof message !== 'undefined' && message) ? message.trim() : "";80 81  // =====================================================82  // ๐Ÿ–ผ๏ธ START PHOTO CAPTURE83  // Admin uses /set_start_photo, then sends the shop image once.84  // Telegram file_id is saved so /start and /menu can reuse the photo85  // without re-uploading it on every visit.86  // =====================================================87  var startPhotoStep = User.getProperty("set_start_photo_step");88  if (String(userId) === String(adminId) && startPhotoStep === "waiting_photo") {89    var incomingPhotos = (request && request.message && request.message.photo) ? request.message.photo : null;90    if (incomingPhotos && incomingPhotos.length) {91      var lastPhoto = incomingPhotos[incomingPhotos.length - 1];92      if (lastPhoto && lastPhoto.file_id) {93        Bot.setProperty("start_photo_file_id", String(lastPhoto.file_id), "string");94        User.setProperty("set_start_photo_step", null, "string");95        Bot.sendMessage(96          "<tg-emoji emoji-id='6208445114075847396'>โœ…</tg-emoji> <b>Start Photo Saved</b>\n\n" +97          "Ab <code>/start</code> aur <code>/menu</code> par ye photo shop dashboard ke saath show hogi.",98          {99            parse_mode: "HTML",100            reply_markup: JSON.stringify({101              inline_keyboard: [[102                { text: "Open Shop", callback_data: "/menu", style: "success", icon_custom_emoji_id: "6143444134125379822" }103              ]]104            })105          }106        );107        return;108      }109    }110 111    Bot.sendMessage(112      "<tg-emoji emoji-id='6093854128193152827'>โš ๏ธ</tg-emoji> <b>Photo nahi mili.</b>\n\nKripya shop ki image ko photo ke roop me send karein.",113      { parse_mode: "HTML" }114    );115    return;116  }117  // โœ… FIXED: pehle "data" naam ka ek undefined global variable padha ja raha tha, jo hamesha118  // empty rehta tha โ€” isliye koi bhi callback button jo "/start" call karta tha (jaise "Back to119  // Menu"), silently fail ho jaata tha aur user ko koi response hi nahi milta tha.120  var callbackData = (request && request.callback_query && request.callback_query.data) ? request.callback_query.data : "";121  // =====================================================122  // ๐Ÿ”— REFER & EARN โ€” PERSONALIZED DEEP-LINK REWARD123  // Referrer earns exactly โ‚น0.50 once when a new user first124  // starts the bot through that referrer's personalized link.125  // Self-referrals, duplicate rewards and invalid IDs are blocked.126  // =====================================================127  // STATIC _tgr CAMPAIGN LINK:128  // The Refer & Earn screen/share button uses the exact owner-provided link:129  // https://t.me/Igstore_01bot?start=ref_" + uid + "130  // Individual reward attribution requires a ref_<telegram_id> payload.131  var referralCode = "";132  try {133    if (msgText.toLowerCase().indexOf("/start") === 0) {134      var startParts = msgText.split(/\s+/);135      if (startParts.length > 1) {136        referralCode = String(startParts[1] || "").trim();137      }138    }139  } catch (refParseErr) {}140 141  if (referralCode.indexOf("ref_") === 0) {142    var referrerId = String(referralCode.substring(4) || "").trim();143 144    // Telegram IDs are numeric; reject malformed referral codes.145    var validReferrerId = /^[0-9]+$/.test(referrerId);146 147    if (validReferrerId && referrerId !== userId &&148        !Bot.getProperty("referral_claimed_" + userId) &&149        !Bot.getProperty("referrer_" + userId)) {150      try {151        // Count successful referrals; reward โ‚น2 for each 10 successful referrals.152        // Only mark as claimed AFTER the referral is successfully recorded.153        Bot.setProperty("referral_claimed_" + userId, true, "boolean");154        Bot.setProperty("referrer_" + userId, referrerId, "string");155 156        var refCount = Number(Bot.getProperty("referral_count_" + referrerId) || 0) + 1;157        var previousMilestones = Math.floor((refCount - 1) / 10);158        var currentMilestones = Math.floor(refCount / 10);159        var milestoneReward = (currentMilestones > previousMilestones) ? 2.00 : 0.00;160 161        if (milestoneReward > 0) {162          var refBalance = Libs.ResourcesLib.anotherUserRes("balance", referrerId);163          refBalance.add(milestoneReward);164        }165 166        var refEarned = Number(Bot.getProperty("referral_earned_" + referrerId) || 0) + milestoneReward;167        Bot.setProperty("referral_count_" + referrerId, refCount, "number");168        Bot.setProperty("referral_earned_" + referrerId, refEarned, "number");169 170        try {171          Api.sendMessage({172            chat_id: referrerId,173            text: "๐ŸŽ‰ <b>New referral joined!</b>\n\n" +174                  "๐Ÿ‘ค User ID: <code>" + userId + "</code>\n" +175                  (milestoneReward > 0 ? "๐Ÿ’ฐ <b>โ‚น2 reward credited!</b> (10 referrals complete)\n" : "๐Ÿ’ฐ <b>No reward yet.</b> 10 referrals complete hone par โ‚น2 milega.\n") +176                  "๐Ÿ‘ฅ Total referrals: <b>" + refCount + "</b>",177            parse_mode: "HTML"178          });179        } catch (refNotifyErr) {}180      } catch (refCreditErr) {181        // Do not mark the referral as claimed if wallet credit fails.182      }183    }184  }185 186 187  // =====================================================188  // ๐Ÿ›  MAINTENANCE MODE GATE (โœ… NEW)189  // Owner/Co-Admins hamesha through jaate hain; baaki sabko premium screen dikhta hai.190  // =====================================================191  var isMaintenanceOn = Bot.getProperty("maintenance_mode") || false;192  var isOwnerOrCoAdmin = (userId === adminId) || Bot.getProperty("co_admin_" + userId);193 194  if (isMaintenanceOn && !isOwnerOrCoAdmin) {195    Bot.sendMessage(196      "<blockquote><tg-emoji emoji-id='6100657257605763582'>๐Ÿ› </tg-emoji> <b>BOT UNDER MAINTENANCE</b></blockquote>\n\n" +197      "<i>Hum kuch premium improvements kar rahe hain! Kripya thodi der baad wapas try karein.</i>\n\n" +198      "<tg-emoji emoji-id='6100170496077204999'>๐Ÿ‘‘</tg-emoji> <i>Dhanyawad for your patience!</i>",199      { parse_mode: "HTML" }200    );201    return;202  }203 204  // โœ… NEW: Maintenance abhi-abhi hata hai โ€” is user ko ek baar premium "We're Back!" welcome do205  var maintenanceRemovedAt = Bot.getProperty("maintenance_removed_at");206  var userSeenMaintenanceRemoved = User.getProperty("seen_maintenance_removed_at");207  if (!isMaintenanceOn && maintenanceRemovedAt && userSeenMaintenanceRemoved !== maintenanceRemovedAt) {208    User.setProperty("seen_maintenance_removed_at", maintenanceRemovedAt, "number");209    Api.sendMessage({210      chat_id: chat.chatid,211      text: "<blockquote><tg-emoji emoji-id='6102856637343600044'>โœ…</tg-emoji> <b>MAINTENANCE REMOVED โ€” WE'RE BACK!</b></blockquote>\n\n" +212            "<tg-emoji emoji-id='6091571559233755994'>๐Ÿš€</tg-emoji> <i>Bot fully automated system ke saath phir se live hai!</i>\n" +213            "<i>Tap /start to continue, or Buy Now to grab your keys instantly.</i>",214      parse_mode: "HTML",215      reply_markup: JSON.stringify({216        inline_keyboard: [[217          { text: "Buy Now", callback_data: "/buy_hack", style: "success", icon_custom_emoji_id: "6312263493051489212" }218        ]]219      })220    });221  }222  223  var currentStep = User.getProperty("add_product_step");224  var isAwaitingBroadcast = User.getProperty("awaiting_broadcast_data");225 226  // ๐ŸŽ› ADMIN: Manage Button name / Premium Emoji ID input227  if (String(userId) === String(adminId)) {228    var mbStep = User.getProperty("manage_button_step");229    var mbKey = String(User.getProperty("manage_button_key") || "");230    var mbAllowed = ["shop","addfund","profile","how","lucky","share","support","download","reseller"];231    if (mbStep && mbAllowed.indexOf(mbKey) !== -1) {232      var incoming = String(msgText || "").trim();233      if (incoming.toLowerCase() === "/cancel") {234        User.setProperty("manage_button_step", null, "string");235        User.setProperty("manage_button_key", null, "string");236        Bot.sendMessage("โŒ Cancelled.");237        return;238      }239      if (!incoming) { Bot.sendMessage("โš ๏ธ Please send a value."); return; }240      if (mbStep === "name") {241        if (incoming.length > 50) { Bot.sendMessage("โš ๏ธ Button name is too long. Keep it under 50 characters."); return; }242        Bot.setProperty("menu_btn_name_" + mbKey, incoming, "string");243        User.setProperty("manage_button_step", null, "string");244        User.setProperty("manage_button_key", null, "string");245        Bot.sendMessage("โœ… Button name updated.\n\nNew name: " + incoming);246        return;247      }248      if (mbStep === "emoji") {249        if (!/^[0-9]{5,30}$/.test(incoming)) { Bot.sendMessage("โš ๏ธ Invalid Premium Emoji ID. Send only the numeric ID."); return; }250        Bot.setProperty("menu_btn_emoji_" + mbKey, incoming, "string");251        User.setProperty("manage_button_step", null, "string");252        User.setProperty("manage_button_key", null, "string");253        Bot.sendMessage("โœ… Premium Emoji ID updated.\n\nID: <code>" + incoming + "</code>", {parse_mode:"HTML"});254        return;255      }256    }257  }258 259  // ๐ŸŽจ PREMIUM CUSTOM EMOJIS DEFINITION (Fixed with escaped double quotes)260  var EMJ_VERIFIED_CHECK = "<tg-emoji emoji-id=\"5875465628285931233\">โœ”๏ธ</tg-emoji>";261  var EMJ_CROWN          = "<tg-emoji emoji-id=\"6311975081702597046\">๐Ÿ‘‘</tg-emoji>";262  var EMJ_DROP           = "<tg-emoji emoji-id=\"6080228009439141516\">๐Ÿ’ง</tg-emoji>";263  var EMJ_CHECK          = "<tg-emoji emoji-id=\"6080214566191505147\">โœ…</tg-emoji>";264  var EMJ_ROCKET         = "<tg-emoji emoji-id=\"6091571559233755994\">๐Ÿš€</tg-emoji>";265  var EMJ_RADAR          = "<tg-emoji emoji-id=\"6093591495237967001\">๐Ÿ“ก</tg-emoji>";266  var EMJ_STAR           = "<tg-emoji emoji-id=\"6093677128295914531\">โœจ</tg-emoji>";267  var EMJ_RED_DOT        = "<tg-emoji emoji-id=\"6093854128193152827\">๐Ÿ”ด</tg-emoji>";268  269  // Access Granted ke liye aapka requested special premium custom emoji270  var EMJ_NEW_ACCESS     = "<tg-emoji emoji-id=\"5875465628285931233\">โœ”๏ธ</tg-emoji>";271 272  // ==========================================273  // ๐Ÿ  HELPER: DIRECTLY SEND MAIN SHOP MENU274  // (Bot.runCommand("/menu") is unreliable in BJS -> inline it instead)275  // ==========================================276  function sendMainMenu() {277    try {278      var userBal = (function() {279        var resBal = 0;280        try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}281        var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);282        return (resBal + bonusBal).toFixed(2);283      })();284 285      // =====================================================286      // ๐Ÿช MEMBER START MENU โ€” exact custom emoji IDs supplied287      // =====================================================288      var storeName = String(Bot.getProperty("store_name") || "๐™„๐™‚ ๐™Ž๐™๐™Š๐™๐™€");289      var firstName = String((user && user.first_name) || "User");290      firstName = firstName.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");291      storeName = storeName.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");292 293      var welcomeMessage =294        "<tg-emoji emoji-id=\"6091170843080007327\">๐Ÿ›’</tg-emoji> โ”โ”โ”โ” <b>" + storeName + "</b> โ”โ”โ”โ” <tg-emoji emoji-id=\"6091170843080007327\">๐Ÿ›’</tg-emoji>\n\n" +295        "<tg-emoji emoji-id=\"6057721277001504261\">๐Ÿ‘‘</tg-emoji> <b>Welcome, " + firstName + "!</b>\n\n" +296        "<tg-emoji emoji-id=\"6147565374289220368\">๐Ÿ”</tg-emoji> <b>โ”โ” STORE HIGHLIGHTS โ”โ”</b> <tg-emoji emoji-id=\"6147565374289220368\">๐Ÿ”</tg-emoji>\n\n" +297        "<tg-emoji emoji-id=\"6285210748184434476\">๐ŸŽฎ</tg-emoji> Premium Game Keys\n" +298        "<tg-emoji emoji-id=\"6205981761353030383\">๐Ÿผ</tg-emoji> Instant Delivery 24/7\n" +299        "<tg-emoji emoji-id=\"6055639815590781298\">๐Ÿ’ฏ</tg-emoji> 100% Secure Payment\n" +300        "<tg-emoji emoji-id=\"6059653892025618055\">๐Ÿ›</tg-emoji> Best Prices Guaranteed\n" +301        "<tg-emoji emoji-id=\"6053197860395033789\">๐Ÿ‡ฎ๐Ÿ‡ณ</tg-emoji> Safe And Trusted\n" +302        "<tg-emoji emoji-id=\"6208445114075847396\">โœ…</tg-emoji> Professional Support\n" +303        "โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n" +304        "<tg-emoji emoji-id=\"6267068789146260253\">๐Ÿ’ฐ</tg-emoji> <b>Wallet Balance: โ‚น" + userBal + "</b>\n" +305        "โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n\n" +306        "<tg-emoji emoji-id=\"6064280370667332428\">๐Ÿ”ฅ</tg-emoji> <b>Tap Shop Now to Start!</b>";307 308      function menuName(key, fallback) { return String(Bot.getProperty("menu_btn_name_" + key) || fallback); }309      function menuEmoji(key, fallback) { return String(Bot.getProperty("menu_btn_emoji_" + key) || fallback); }310      var multiColorKeyboard = [311        [{ text: menuName("shop", "Shop / Store Product"), callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: menuEmoji("shop", "6143444134125379822") }],312        [313          { text: menuName("addfund", "Add Balance"), callback_data: "/addfund", style: "success", icon_custom_emoji_id: menuEmoji("addfund", "5409048419211682843") },314          { text: menuName("profile", "My Profile"), callback_data: "/profile", style: "primary", icon_custom_emoji_id: menuEmoji("profile", "6091379307907652768") }315        ],316        [317          { text: menuName("how", "How To Use"), callback_data: "/how", style: "primary", icon_custom_emoji_id: menuEmoji("how", "5341357385279612709") },318          { text: menuName("lucky", "Lucky"), callback_data: "/ludospin", style: "success", icon_custom_emoji_id: menuEmoji("lucky", "6116155973510895366") }319        ],320        [321          { text: menuName("share", "Share"), callback_data: "/referral", style: "primary", icon_custom_emoji_id: menuEmoji("share", "6147534454819661264") },322          { text: menuName("support", "Support"), callback_data: "/support", style: "primary", icon_custom_emoji_id: menuEmoji("support", "6147817325660741985") }323        ],324        [325          { text: menuName("download", "Download File"), callback_data: "/download_updates", style: "primary", icon_custom_emoji_id: menuEmoji("download", "6235683689292897318") },326          { text: menuName("reseller", "Reseller VIP"), callback_data: "/reseller_upgrade", style: "success", icon_custom_emoji_id: menuEmoji("reseller", "6102856637343600044") }327        ]328      ];329 330      if (!(Bot.getProperty("reseller_system_enabled") && !Bot.getProperty("is_reseller_" + userId))) {331        multiColorKeyboard[multiColorKeyboard.length - 1] = [{ text: menuName("download", "Download File"), callback_data: "/download_updates", style: "primary", icon_custom_emoji_id: menuEmoji("download", "6235683689292897318") }];332      }333 334      var markup = JSON.stringify({ inline_keyboard: multiColorKeyboard });335      var photoId = Bot.getProperty("start_photo_file_id");336 337      // When a custom emoji ID is invalid/unsupported, retry the same menu without338      // icon metadata so the menu still works instead of failing completely.339      function safeMenuMarkup(kb) {340        return JSON.stringify({ inline_keyboard: kb.map(function(row){ return row.map(function(b){341          return { text: b.text, callback_data: b.callback_data };342        }); }) });343      }344      if (photoId) {345        try {346          Api.sendPhoto({ chat_id: chat.chatid, photo: String(photoId), caption: welcomeMessage, parse_mode: "HTML", reply_markup: markup });347        } catch (menuSendErr) {348          Api.sendPhoto({ chat_id: chat.chatid, photo: String(photoId), caption: welcomeMessage, parse_mode: "HTML", reply_markup: safeMenuMarkup(multiColorKeyboard) });349        }350      } else {351        try {352          Api.sendMessage({ chat_id: chat.chatid, text: welcomeMessage, parse_mode: "HTML", reply_markup: markup });353        } catch (menuSendErr2) {354          Api.sendMessage({ chat_id: chat.chatid, text: welcomeMessage, parse_mode: "HTML", reply_markup: safeMenuMarkup(multiColorKeyboard) });355        }356      }357    } catch (menuErr) {358      Bot.sendMessage("๐Ÿ›‘ <b>Menu Send Error:</b> <code>" + menuErr.message + "</code>", { parse_mode: "HTML" });359    }360  }361 362  // [Member Profile] Save basic Telegram profile so Admin can view member details.363  try {364    Bot.setProperty("user_profile_" + userId, {365      first_name: user.first_name || "",366      last_name: user.last_name || "",367      username: user.username || ""368    }, "json");369  } catch (profileErr) {}370 371  // [Admin Start Notification - ONCE ONLY]372  // Owner + all current co-admins get one notification for each user's first /start.373  // Repeated /start calls from the same user will NOT send another notification.374  try {375    var startNotifyKey = "start_notified_" + userId;376    var alreadyNotified = Bot.getProperty(startNotifyKey);377    if (!alreadyNotified) {378      Bot.setProperty(startNotifyKey, true, "boolean");379 380      var startName = user.first_name || "Unknown";381      var startUsername = user.username ? "@" + user.username : "No username";382      var startText =383        "<blockquote><b>๐Ÿš€ NEW MEMBER STARTED BOT</b></blockquote>\n\n" +384        "โ€ข <b>Name:</b> " + startName + "\n" +385        "โ€ข <b>Username:</b> " + startUsername + "\n" +386        "โ€ข <b>User ID:</b> <code>" + userId + "</code>\n" +387        "โ€ข <b>Store:</b> <b>๐™„๐™‚ ๐™Ž๐™๐™Š๐™๐™€</b>";388 389      var notifyIds = [];390      var ownerNotifyId = String(Bot.getProperty("owner_id") || "7839151435");391      if (ownerNotifyId && notifyIds.indexOf(ownerNotifyId) === -1) notifyIds.push(ownerNotifyId);392 393      var coAdminList = Bot.getProperty("co_admin_list") || [];394      if (Array.isArray(coAdminList)) {395        for (var ci = 0; ci < coAdminList.length; ci++) {396          var coId = String(coAdminList[ci]);397          if (coId && notifyIds.indexOf(coId) === -1) notifyIds.push(coId);398        }399      }400 401      for (var ni = 0; ni < notifyIds.length; ni++) {402        try {403          Api.sendMessage({404            chat_id: notifyIds[ni],405            text: startText,406            parse_mode: "HTML"407          });408        } catch (notifyOneErr) {}409      }410    }411  } catch (startNotifyErr) {}412 413  // [Auto-Track User] List me user track karne ke liye414  var trackedUsers = Bot.getProperty("all_users_list") || [];415  if (!trackedUsers.includes(userId)) {416    trackedUsers.push(userId);417    Bot.setProperty("all_users_list", trackedUsers, "json");418 419    // ==========================================420 421  }422 423  // ๐Ÿ›ก๏ธ [ANTI-DUPLICATE CHECK] Agar user already verified hai toh seedhe menu par bhejein424  // โœ… FIXED: pehle sirf exact "msgText === '/start'" ya "callbackData === '/trigger_contact_popup'"425  // match hone par hi menu bhejta tha. Kisi bhi button jo callback_data "/start" call karta tha426  // (jaise cancel-order ke baad "Back to Menu"), us case me match fail ho jaata tha aur user ko427  // koi response nahi milta tha. Ab ye check robust hai โ€” jab tak ye genuinely ek contact-share428  // event nahi hai ya admin ek mid-flow step me nahi hai, verified user ko hamesha menu milega.429  var couponGenStep = User.getProperty("coupon_gen_step");430  var awaitingCouponFor = User.getProperty("awaiting_coupon_for");431  var isAlreadyVerified = Bot.getProperty("verified_" + userId);432  var isContactShareEvent = !!(request && request.contact && request.contact.user_id);433  var isAdminMidFlow = (userId === adminId && (currentStep || isAwaitingBroadcast || couponGenStep ||434    User.getProperty("addbal_step") || User.getProperty("addbalall_step") || User.getProperty("rembal_step") || User.getProperty("checkbal_step") ||435    User.getProperty("set_download_link_step") || User.getProperty("set_payment_upi_step") ||436    User.getProperty("set_payment_binance_step") ||437    User.getProperty("set_how_link_step") || User.getProperty("set_support_link_step")));438  var binanceUtrStep = User.getProperty("binance_utr_step");439  var isUserMidFlow = !!awaitingCouponFor || !!binanceUtrStep;440 441  // โœ… NEW: User ne jo bhi "/start"/"/START"/"/Start" type kiya, menu aane ke442  // baad us typed command-message ko vanish (delete) kar do โ€” chat clean rahe.443  if (msgText.toLowerCase() === "/start" && request && request.message_id) {444    try { Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (delStartErr) {}445  }446 447  if (isAlreadyVerified && !isContactShareEvent && !isAdminMidFlow && !isUserMidFlow) {448    sendMainMenu();449    return;450  }451 452  // ==========================================453  // ๐Ÿš€ DIRECT START ENTRY454  // Phone-number/contact verification removed.455  // /start now opens the main shop menu directly.456  // No extra START screen/button is shown.457  // ==========================================458  if (msgText.toLowerCase() === "/start" || callbackData === "/trigger_contact_popup") {459    sendMainMenu();460    return;461  }462 463  // ==========================================464  // ๐Ÿช ADMIN โ€” STORE NAME INPUT465  // ==========================================466  if (userId === adminId && User.getProperty("set_store_name_step") === "waiting_input") {467    if (!msgText || !String(msgText).trim()) {468      Bot.sendMessage("โš ๏ธ Please send a valid store name.");469      return;470    }471    var newStoreName = String(msgText).trim();472    Bot.setProperty("store_name", newStoreName, "string");473    User.setProperty("set_store_name_step", null, "string");474    Bot.sendMessage(475      "<tg-emoji emoji-id='6208445114075847396'>โœ…</tg-emoji> <b>Store name updated.</b>\n\n" +476      "New name: <b>" + newStoreName.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") + "</b>",477      { parse_mode: "HTML" }478    );479    return;480  }481 482  // ==========================================483  // ๐Ÿ“ฆ MODULE 1: STEP-BY-STEP PRODUCT CREATION (UPDATED FOR WEBSITE API ID)484  // ==========================================485  if (userId === adminId && currentStep) {486    if (currentStep === "waiting_for_name") {487      if (!msgText) {488        Bot.sendMessage("โš ๏ธ Invalid name. Please type a valid Product Name:");489        return;490      }491      User.setProperty("temp_product_name", msgText, "string");492      User.setProperty("add_product_step", "waiting_for_emoji", "string");493      Bot.sendMessage("๐Ÿ’Ž Great! Now send the <b>Premium Emoji ID</b> for this product:", { parse_mode: "HTML" });494      return; 495    }496    497    if (currentStep === "waiting_for_emoji") {498      if (!msgText) {499        Bot.sendMessage("โš ๏ธ Invalid Emoji ID. Please send a valid Telegram Premium Emoji ID:");500        return;501      }502      User.setProperty("temp_product_emoji", msgText, "string");503      User.setProperty("add_product_step", "waiting_for_pid", "string");504      Bot.sendMessage("๐Ÿ”‘ Nice! Now please enter the <b>Website API Product ID (PID)</b> for this item:", { parse_mode: "HTML" });505      return;506    }507 508    if (currentStep === "waiting_for_pid") {509      if (!msgText) {510        Bot.sendMessage("โš ๏ธ Invalid Product ID. Please type a valid Website PID:");511        return;512      }513 514      var savedName = User.getProperty("temp_product_name");515      var savedEmoji = User.getProperty("temp_product_emoji");516      var savedPid = msgText; // User ne jo PID abhi bheja517 518      var productList = Bot.getProperty("stored_products") || [];519      if (!Array.isArray(productList)) { productList = []; }520      521      // Saving Name, Emoji and Website API ID (id) inside database object522      productList.push({ 523        name: savedName, 524        emoji: savedEmoji, 525        id: savedPid, 526        plans: [] 527      });528 529      Bot.setProperty("stored_products", productList, "json");530      531      // Cleanup temporary states532      User.setProperty("add_product_step", null, "string");533      User.setProperty("temp_product_name", null, "string");534      User.setProperty("temp_product_emoji", null, "string");535      536      var successMsg = "โœ… <b>Product Added Successfully!</b>\n\n" +537                       "๐Ÿ“ฆ <b>Name:</b> " + savedName + "\n" +538                       "๐Ÿ’Ž <b>Emoji ID:</b> <code>" + savedEmoji + "</code>\n" +539                       "๐Ÿ”‘ <b>API Product ID (PID):</b> <code>" + savedPid + "</code>\n\n" +540                       "<i>Aap is product ke andar plans baad me configure kar sakte hain. Automatically website se integration ho gaya hai!</i>";541                       542      Bot.sendMessage(successMsg, { parse_mode: "HTML" });543      return; 544    }545  }546 547  // ==========================================548  // ๐ŸŸก MODULE 4b: ADMIN โ€” BINANCE PAYMENT CONFIG WIZARD549  // Step 1: QR (photo OR image URL โ€” whichever the admin sends, both work).550  // Step 2: Binance Pay ID. Step 3: USDT Address. Step 4: USD rate.551  // ==========================================552  if (userId === adminId) {553    var setPaymentBinanceStep = User.getProperty("set_payment_binance_step");554 555    // โœ… ROBUST photo detection โ€” different update shapes have shown up in this556    // environment, so we check every place Telegram (or this platform) might557    // put the photo array before giving up.558    var incomingPhotoArr = null;559    try {560      if (request) {561        if (request.message && request.message.photo && request.message.photo.length) {562          incomingPhotoArr = request.message.photo;563        } else if (request.photo && request.photo.length) {564          incomingPhotoArr = request.photo;565        } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {566          incomingPhotoArr = request.update.message.photo;567        }568      }569    } catch (photoDetectErr) {}570 571    if (setPaymentBinanceStep === "waiting_qr") {572      var savedQr = false;573 574      if (incomingPhotoArr) {575        var largestPhoto = incomingPhotoArr[incomingPhotoArr.length - 1];576        var qrFileId = largestPhoto.file_id;577        Bot.setProperty("binance_qr_file_id", qrFileId, "string");578        Bot.setProperty("binance_qr_url", null, "string");579        savedQr = true;580      } else if (msgText && (msgText.trim().indexOf("http://") === 0 || msgText.trim().indexOf("https://") === 0)) {581        Bot.setProperty("binance_qr_url", msgText.trim(), "string");582        Bot.setProperty("binance_qr_file_id", null, "string");583        savedQr = true;584      }585 586      if (savedQr) {587        User.setProperty("set_payment_binance_step", "waiting_binance_id", "string");588        Bot.sendMessage(589          "โœ… <b>QR Saved!</b>\n\n" +590          "<i>Step 2/4 โ€”</i> Ab apna <b>Binance Pay ID</b> bhejein (jaise: <code>839548203</code>):",591          { parse_mode: "HTML" }592        );593        return;594      }595 596      // โŒ Neither a photo nor a URL was recognised โ€” don't silently drop it.597      Bot.sendMessage(598        "โš ๏ธ QR receive nahi hua. Kripya QR ko ya toh <b>photo/image</b> ke roop me bhejein, ya QR image ka <b>direct URL link</b> (https://...) paste karein.",599        { parse_mode: "HTML" }600      );601      return;602    }603 604    if (setPaymentBinanceStep === "waiting_binance_id" && msgText) {605      Bot.setProperty("binance_pay_id", msgText.trim(), "string");606      User.setProperty("set_payment_binance_step", "waiting_usdt_address", "string");607      Bot.sendMessage(608        "โœ… <b>Binance Pay ID Saved!</b>\n\n" +609        "<i>Step 3/4 โ€”</i> Ab apna <b>USDT Address</b> bhejein (jaise: <code>TNvySU5Wk2mBAJNpBLGwvLk9pk4EgkeLXt</code>):",610        { parse_mode: "HTML" }611      );612      return;613    }614 615    if (setPaymentBinanceStep === "waiting_usdt_address" && msgText) {616      Bot.setProperty("binance_usdt_address", msgText.trim(), "string");617      User.setProperty("set_payment_binance_step", "waiting_usd_rate", "string");618      var rateNow = Bot.getProperty("usd_rate") || 91;619      Bot.sendMessage(620        "โœ… <b>USDT Address Saved!</b>\n\n" +621        "<i>Step 4/4 โ€”</i> Ab USD conversion rate bhejein (โ‚น kitne ka $1, jaise <code>91</code>).\n" +622        "<i>Current:</i> <code>โ‚น" + rateNow + " = $1</code>\n" +623        "<i>Same rakhna ho to bhi number type karke bhej dein.</i>",624        { parse_mode: "HTML" }625      );626      return;627    }628 629    if (setPaymentBinanceStep === "waiting_usd_rate" && msgText) {630      var finalRate = parseFloat(msgText.trim());631      if (isNaN(finalRate) || finalRate <= 0) {632        Bot.sendMessage("โŒ Invalid rate! Ek valid positive number bhejein, jaise 91.", { parse_mode: "HTML" });633        return;634      }635      Bot.setProperty("usd_rate", finalRate, "string");636      User.setProperty("set_payment_binance_step", null, "string");637 638      var qrStatusMsg = Bot.getProperty("binance_qr_file_id") || Bot.getProperty("binance_qr_url") ? "โœ… Set" : "โŒ Not set";639      Bot.sendMessage(640        "<blockquote>๐ŸŸก <b>BINANCE PAY CONFIG COMPLETE!</b></blockquote>\n\n" +641        "๐Ÿ–ผ <b>QR:</b> " + qrStatusMsg + "\n" +642        "๐Ÿ†” <b>Binance Pay ID:</b> <code>" + Bot.getProperty("binance_pay_id") + "</code>\n" +643        "๐Ÿ’ณ <b>USDT Address:</b> <code>" + Bot.getProperty("binance_usdt_address") + "</code>\n" +644        "๐Ÿ’ฑ <b>USD Rate:</b> <code>โ‚น" + finalRate + " = $1</code>\n\n" +645        "<i>Binance Pay ab live hai!</i>",646        { parse_mode: "HTML" }647      );648      return;649    }650  }651 652  // ==========================================653  // ๐ŸŸก MODULE 4c: USER โ€” BINANCE PROOF SUBMISSION (screenshot only)654  // ==========================================655  if (binanceUtrStep === "awaiting_screenshot") {656    var ssPhotoArr = null;657    try {658      if (request) {659        if (request.message && request.message.photo && request.message.photo.length) {660          ssPhotoArr = request.message.photo;661        } else if (request.photo && request.photo.length) {662          ssPhotoArr = request.photo;663        } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {664          ssPhotoArr = request.update.message.photo;665        }666      }667    } catch (ssPhotoDetectErr) {}668 669    if (!ssPhotoArr) {670      Bot.sendMessage("โš ๏ธ Kripya payment screenshot ek <b>image/photo</b> ke roop me bhejein.", { parse_mode: "HTML" });671      return;672    }673 674    var ssLargest = ssPhotoArr[ssPhotoArr.length - 1];675    var ssFileId = ssLargest.file_id;676 677    var subInr = User.getProperty("binance_pending_amount_inr");678    var subUsd = User.getProperty("binance_pending_amount_usd");679    var adminSupportId = Bot.getProperty("owner_id") || "7839151435";680 681    var fullNameSub = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";682    var usernameSub = user.username ? "@" + user.username : "No Username";683 684    var adminCaption =685      "<blockquote><tg-emoji emoji-id='6312263493051489212'>๐ŸŸก</tg-emoji> <b>NEW BINANCE PAY SUBMISSION</b></blockquote>\n" +686      "๐Ÿ‘ค <b>User:</b> <a href='tg://user?id=" + userId + "'>" + fullNameSub + "</a> (<code>" + userId + "</code>)\n" +687      "๐ŸŒ <b>Username:</b> " + usernameSub + "\n" +688      "๐Ÿ’ฐ <b>Amount:</b> $<code>" + subUsd + "</code> <i>(โ‚น" + subInr + ")</i>\n\n" +689      "<i>Verify the screenshot, then credit balance with the button below or:</i>\n<code>/addbal " + userId + "|" + subInr + "</code>";690 691    try {692      Api.sendPhoto({693        chat_id: adminSupportId,694        photo: ssFileId,695        caption: adminCaption,696        parse_mode: "HTML",697        reply_markup: JSON.stringify({698          inline_keyboard: [[699            { text: "โœ… Approve & Credit โ‚น" + subInr, callback_data: "/addbal_binance_approve " + userId + " " + subInr, style: "success" }700          ]]701        })702      });703    } catch (notifyAdminErr) {}704 705    User.setProperty("binance_utr_step", null, "string");706    User.setProperty("binance_pending_amount_inr", null, "string");707    User.setProperty("binance_pending_amount_usd", null, "string");708 709    Bot.sendMessage(710      "<blockquote><tg-emoji emoji-id='6147936236125298267'>โณ</tg-emoji> <b>WAIT FOR ADMIN CHECK</b></blockquote>\n\n" +711      "<i>Aapka payment screenshot admin ko bhej diya gaya hai. Admin manually verify karke aapka balance add karega โ€” thodi der wait karein!</i>",712      {713        parse_mode: "HTML",714        reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "primary" }]] })715      }716    );717    return;718  }719 720  // ==========================================721  // ๐Ÿ’ต MODULE 5: ADMIN BALANCE TOOLS (Add Bal / Remove Bal / Check Bal722  // button-click continuation โ€” fixes buttons that previously just723  // showed a "Wrong Format" error with no way to actually complete it)724  // ==========================================725  if (userId === adminId) {726    var addbalStep = User.getProperty("addbal_step");727    var addbalAllStep = User.getProperty("addbalall_step");728    var rembalStep = User.getProperty("rembal_step");729    var checkbalStep = User.getProperty("checkbal_step");730 731    if (addbalStep === "waiting_input" && msgText) {732      User.setProperty("addbal_step", null, "string");733 734      // โœ… FIXED: pehle sirf Bot.run(...) se /addbal ko dobara call kiya jaata tha โ€”735      // agar us re-run me "message" text sahi se forward nahi hota tha (jo wildcard736      // "*" -> /start delegation ke through hone par silently fail ho sakta tha),737      // toh balance kabhi credit hi nahi hota tha aur admin ko koi error bhi nahi738      // dikhta tha. Ab balance yahin, isi jagah, seedha add hota hai โ€” kisi doosre739      // command re-run par depend nahi karta. Bot.run wala call sirf backup ke740      // taur par neeche rakha hai.741      var addbalData = msgText.trim();742 743      if (addbalData.indexOf("|") === -1) {744        Bot.sendMessage("โŒ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });745        return;746      }747 748      var addbalParts = addbalData.split("|");749      var addbalTargetId = addbalParts[0].trim();750      var addbalAmount = parseFloat(addbalParts[1].trim());751 752      if (!addbalTargetId || isNaN(addbalAmount) || addbalAmount <= 0) {753        Bot.sendMessage("โŒ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });754        return;755      }756 757      try {758        // Primary wallet resource (same store the rest of the bot reads for purchases)759        try {760          Libs.ResourcesLib.anotherUserRes("balance", addbalTargetId).add(addbalAmount);761        } catch (resErr) {}762 763        // โœ… Bonus-balance property โ€” this is the SAME property /menu reads and adds764        // on top of the resource balance. Writing it here too guarantees the credited765        // amount always shows up for the user even if the resource write above fails766        // silently for a user who never triggered it before.767        var prevBonus = Number(Bot.getProperty("balance" + addbalTargetId) || 0);768        Bot.setProperty("balance" + addbalTargetId, (prevBonus + addbalAmount).toFixed(2), "string");769 770        Bot.sendMessage("โœ… Success! Added " + addbalAmount + " to user " + addbalTargetId, { parse_mode: "HTML" });771 772        try {773          Api.sendMessage({774            chat_id: addbalTargetId,775            text: "<blockquote>" +776              "<tg-emoji emoji-id='6192822213486321961'>๐Ÿ—ฃ</tg-emoji> Admin Added: " + addbalAmount + "\n" +777              "<tg-emoji emoji-id='6266967801580231067'>๐Ÿ’Ž</tg-emoji> Balance Credited!\n" +778              "<tg-emoji emoji-id='6267068789146260253'>๐Ÿ’ฐ</tg-emoji> Wallet Updated\n" +779              "<tg-emoji emoji-id='5866053971960929280'>๐Ÿ›’</tg-emoji> /start TO SHOP NOW" +780              "</blockquote>",781            parse_mode: "HTML"782          });783        } catch (notifyErr) {}784      } catch (addbalErr) {785        Bot.sendMessage("โš ๏ธ *Error:* " + addbalErr.message, { parse_mode: "Markdown" });786      }787      return;788    }789    if (addbalAllStep === "waiting_input" && msgText) {790      User.setProperty("addbalall_step", null, "string");791      Bot.run({ command: "/addbal_all", options: { message: "/addbal_all " + msgText.trim() } });792      return;793    }794    if (rembalStep === "waiting_input" && msgText) {795      User.setProperty("rembal_step", null, "string");796      Bot.run({ command: "/rembal", options: { message: "/rembal " + msgText.trim() } });797      return;798    }799    if (checkbalStep === "waiting_input" && msgText) {800      User.setProperty("checkbal_step", null, "string");801      Bot.run({ command: "/checkbal", options: { params: msgText.trim() } });802      return;803    }804 805    var setDownloadLinkStep = User.getProperty("set_download_link_step");806    if (setDownloadLinkStep === "waiting_input" && msgText) {807      User.setProperty("set_download_link_step", null, "string");808      Bot.run({ command: "/set_update_link", options: { params: msgText.trim() } });809      return;810    }811 812    var setPaymentUpiStep = User.getProperty("set_payment_upi_step");813    if (setPaymentUpiStep === "waiting_input" && msgText) {814      User.setProperty("set_payment_upi_step", null, "string");815      Bot.run({ command: "/set_payment_upi", options: { params: msgText.trim() } });816      return;817    }818 819    var setHowLinkStep = User.getProperty("set_how_link_step");820    if (setHowLinkStep === "waiting_input" && msgText) {821      var howLinkInput = msgText.trim();822      if (!/^https?:\/\//i.test(howLinkInput)) {823        Bot.sendMessage("โŒ Link http:// ya https:// se shuru honi chahiye!", {parse_mode:"HTML"});824        return;825      }826      Bot.setProperty("how_to_use_link", howLinkInput, "string");827      User.setProperty("set_how_link_step", null, "string");828      // Do not let an old demo-video upload session consume this text message.829      User.setProperty("demo_video_add_product", null, "string");830      Bot.sendMessage("โœ… <b>How To Use URL saved.</b>\n\n<code>" + howLinkInput.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") + "</code>",{parse_mode:"HTML",reply_markup:JSON.stringify({inline_keyboard:[[{text:"โฌ…๏ธ Admin Panel",callback_data:"/admin",style:"primary"}]]})});831      return;832    }833 834    var setSupportLinkStep = User.getProperty("set_support_link_step");835    if (setSupportLinkStep === "waiting_input" && msgText) {836      User.setProperty("set_support_link_step", null, "string");837      Bot.run({ command: "/set_support_link", options: { params: msgText.trim() } });838      return;839    }840  }841 842  // ==========================================843  // ๐ŸŽŸ MODULE 3: ADMIN COUPON GENERATOR (step-by-step wizard)844  // ==========================================845  if (userId === adminId && couponGenStep) {846 847    if (couponGenStep === "code") {848      if (!msgText) { Bot.sendMessage("โš ๏ธ Kripya ek valid coupon code bhejein."); return; }849      var couponCodeUpper = msgText.trim().toUpperCase();850      if (Bot.getProperty("coupon_" + couponCodeUpper)) {851        Bot.sendMessage("โŒ Ye coupon code pehle se exist karta hai! Doosra naam try karein.");852        return;853      }854      User.setProperty("coupon_gen_code", couponCodeUpper, "string");855      User.setProperty("coupon_gen_step", "maxclaims", "string");856      Bot.sendMessage("<tg-emoji emoji-id='6091571559233755994'>๐Ÿ‘ฅ</tg-emoji> <b>Kitne users ye coupon use (claim) kar sakte hain?</b>\n<i>Sirf number bhejein, jaise: 50</i>", { parse_mode: "HTML" });857      return;858    }859 860    if (couponGenStep === "maxclaims") {861      var maxClaimsVal = parseInt(msgText.trim());862      if (isNaN(maxClaimsVal) || maxClaimsVal <= 0) { Bot.sendMessage("โŒ Kripya ek valid number bhejein (jaise 50)."); return; }863      User.setProperty("coupon_gen_maxclaims", maxClaimsVal, "number");864      User.setProperty("coupon_gen_step", "discount", "string");865      Bot.sendMessage("<tg-emoji emoji-id='6093591495237967001'>๐Ÿ’ธ</tg-emoji> <b>Kitne % discount dena hai?</b>\n<i>Sirf number bhejein (1-100), jaise: 10</i>", { parse_mode: "HTML" });866      return;867    }868 869    if (couponGenStep === "discount") {870      var discountVal = parseFloat(msgText.trim());871      if (isNaN(discountVal) || discountVal <= 0 || discountVal > 100) { Bot.sendMessage("โŒ Discount 1 se 100 ke beech honi chahiye."); return; }872      User.setProperty("coupon_gen_discount", discountVal, "number");873      User.setProperty("coupon_gen_step", "scope", "string");874      Bot.sendMessage(875        "<tg-emoji emoji-id='6093677128295914531'>๐ŸŽฏ</tg-emoji> <b>Scope batayein:</b>\n\n" +876        "โ€ข Sabhi products/plans ke liye: <code>global</code> likh kar bhejein\n" +877        "โ€ข Sirf ek specific product+plan ke liye: <code>Product Name | Duration</code>\n" +878        "  <i>Example:</i> <code>Atomic Habits (Book) | 1d</code>",879        { parse_mode: "HTML" }880      );881      return;882    }883 884    if (couponGenStep === "scope") {885      var scopeInput = msgText.trim();886      var couponData = {887        code: User.getProperty("coupon_gen_code"),888        maxClaims: User.getProperty("coupon_gen_maxclaims"),889        discountPercent: User.getProperty("coupon_gen_discount"),890        claimedBy: [],891        isPaused: false,892        createdAt: new Date().toLocaleDateString()893      };894 895      if (scopeInput.toLowerCase() === "global") {896        couponData.scope = "global";897      } else if (scopeInput.indexOf("|") > -1) {898        var scopeParts = scopeInput.split("|");899        couponData.scope = "specific";900        couponData.productName = scopeParts[0].trim();901        couponData.duration = scopeParts[1].trim();902      } else {903        Bot.sendMessage("โŒ Galat format! 'global' likhein ya 'Product Name | Duration' format me bhejein.");904        return;905      }906 907      Bot.setProperty("coupon_" + couponData.code, couponData, "json");908 909      // โœ… NEW: master list me bhi add karo, taaki /coupons admin command sabko list kar sake910      var couponList = Bot.getProperty("coupon_list") || [];911      if (couponList.indexOf(couponData.code) === -1) {912        couponList.push(couponData.code);913        Bot.setProperty("coupon_list", couponList, "json");914      }915 916      // Cleanup wizard state917      User.setProperty("coupon_gen_step", null, "string");918      User.setProperty("coupon_gen_code", null, "string");919      User.setProperty("coupon_gen_maxclaims", null, "number");920      User.setProperty("coupon_gen_discount", null, "number");921 922      Bot.sendMessage(923        "<blockquote>๐ŸŽŸ <b>COUPON CREATED SUCCESSFULLY!</b></blockquote>\n\n" +924        "๐Ÿท <b>Code:</b> <code>" + couponData.code + "</code>\n" +925        "๐Ÿ‘ฅ <b>Max Claims:</b> " + couponData.maxClaims + "\n" +926        "๐Ÿ’ธ <b>Discount:</b> " + couponData.discountPercent + "%\n" +927        "๐ŸŽฏ <b>Scope:</b> " + (couponData.scope === "global" ? "๐ŸŒ Global (All Plans)" : "๐Ÿ“ฆ " + couponData.productName + " (" + couponData.duration + ")"),928        { parse_mode: "HTML" }929      );930      return;931    }932  }933 934  // ==========================================935  // ๐ŸŽŸ MODULE 4: USER โ€” APPLY COUPON CODE TEXT ENTRY936  // ==========================================937  if (awaitingCouponFor) {938    var enteredCode = msgText.trim().toUpperCase();939    var couponRec = Bot.getProperty("coupon_" + enteredCode);940 941    User.setProperty("awaiting_coupon_for", null, "string");942 943    if (!couponRec) {944      Bot.sendMessage("โŒ <b>Invalid Coupon Code!</b>", { parse_mode: "HTML" });945      return;946    }947    if (couponRec.isPaused) {948      Bot.sendMessage("โธ Ye coupon abhi paused hai, thodi der baad try karein.", { parse_mode: "HTML" });949      return;950    }951    if (!Array.isArray(couponRec.claimedBy)) { couponRec.claimedBy = []; }952    if (couponRec.claimedBy.indexOf(userId) > -1) {953      Bot.sendMessage("โš ๏ธ Aapne ye coupon already use kar liya hai!", { parse_mode: "HTML" });954      return;955    }956    if (couponRec.claimedBy.length >= couponRec.maxClaims) {957      Bot.sendMessage("โŒ Is coupon ki claim limit khatam ho gayi hai!", { parse_mode: "HTML" });958      return;959    }960 961    var couponTargetParts = awaitingCouponFor.split(" ");962    var cTargetProdIdx = couponTargetParts[0];963    var cTargetPlanIdx = couponTargetParts[1];964 965    if (couponRec.scope === "specific") {966      var cProductList = Bot.getProperty("stored_products") || [];967      var cProduct = cProductList[Number(cTargetProdIdx)];968      var cPlan = cProduct ? cProduct.plans[Number(cTargetPlanIdx)] : null;969      var cDurationDisplay = cPlan ? (cPlan.durationDisplay || (cPlan.days + " Days")) : "";970      var matchesProduct = cProduct && cProduct.name.trim().toLowerCase() === couponRec.productName.trim().toLowerCase();971      var matchesDuration = cDurationDisplay.toLowerCase().indexOf(String(couponRec.duration).toLowerCase().replace(/[^a-z0-9]/g, "")) > -1 ||972                             String(couponRec.duration).replace(/[^0-9]/g, "") === String(cPlan ? cPlan.days : "");973      if (!matchesProduct) {974        Bot.sendMessage("โŒ Ye coupon is product ke liye valid nahi hai!", { parse_mode: "HTML" });975        return;976      }977    }978 979    // โœ… Valid โ€” apply and mark claimed980    couponRec.claimedBy.push(userId);981    Bot.setProperty("coupon_" + enteredCode, couponRec, "json");982    User.setProperty("applied_coupon_" + cTargetProdIdx + "_" + cTargetPlanIdx, enteredCode, "string");983 984    Bot.sendMessage("๐ŸŽ‰ <b>Coupon Applied!</b> -" + couponRec.discountPercent + "% discount added.", { parse_mode: "HTML" });985 986    Bot.run({987      command: "buyitem",988      options: { params: cTargetProdIdx + " " + cTargetPlanIdx }989    });990    return;991  }992 993  // ==========================================994  // ๐Ÿ“ข MODULE 2: PREMIUM BROADCAST SYSTEM995  // ==========================================996  if (userId === adminId && isAwaitingBroadcast) {997    User.setProperty("awaiting_broadcast_data", false, "boolean");998    var userList = Bot.getProperty("all_users_list") || [];999 1000    if (userList.length === 0) {1001      Bot.sendMessage("โŒ Bot mein abhi tak koi bhi user registered nahi hai.");1002      return;1003    }1004 1005    var targetMessageId = null;1006    if (request) {1007      if (request.message_id) { targetMessageId = request.message_id; }1008      else if (request.message && request.message.message_id) { targetMessageId = request.message.message_id; }1009    }1010 1011    if (!targetMessageId) {1012      Bot.sendMessage("โŒ Unable to fetch message ID for broadcast.");1013      return;1014    }1015 1016    Bot.sendMessage("โณ Sending premium broadcast to " + userList.length + " users... Please wait.");1017 1018    // โœ… FIXED: pehle ek bhi blocked/invalid user Api.copyMessage() ko throw karwa deta1019    // tha, jo bahar wale catch() tak chala jaata tha โ€” isse loop beech me hi ruk jaata1020    // tha (baaki users ko broadcast nahi jaata tha) aur admin ko scary "Error in handling"1021    // dikhta tha, jabki zyada tar users ko message mil chuka hota tha. Ab har send apne1022    // try/catch me hai, aur end me accurate success/fail count milega.1023    var sentCount = 0;1024    var failedCount = 0;1025    for (var i = 0; i < userList.length; i++) {1026      try {1027        Api.copyMessage({1028          chat_id: String(userList[i]),1029          from_chat_id: adminId,1030          message_id: Number(targetMessageId)1031        });1032        sentCount++;1033      } catch (perUserErr) {1034        failedCount++;1035      }1036    }1037    Bot.sendMessage(1038      "โœ… <b>Broadcast Complete!</b>\n" +1039      "๐Ÿ“ค <b>Sent:</b> " + sentCount + " users\n" +1040      (failedCount > 0 ? "โš ๏ธ <b>Failed/Blocked:</b> " + failedCount + " users" : "๐ŸŽ‰ <b>No failures!</b>"),1041      { parse_mode: "HTML" }1042    );1043  }1044 1045} catch (err) {1046  Bot.sendMessage("Error in handling: " + err.message);1047}