indrajitghosh20006/Igstore_01botPublic ยท Bot Template
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 8h agoCreated Oct 30, 2026
commands/_start.js
javascript ยท 1047 lines
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, "&").replace(/</g, "<").replace(/>/g, ">");291 storeName = storeName.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");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,"&").replace(/</g,"<").replace(/>/g,">") + "</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,"&").replace(/</g,"<").replace(/>/g,">") + "</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}