tarunpoonia905/OfcDevShopBotPublic · Bot Template
AIDEV SHOP appears to be a Telegram automation bot. Commands include /confirm_delete_stock, /addstock_id, /extkey_menu, /partner_api, /apidelete, /buy_hack_cat, /admin_manage_products, /check_buy. Observed in code: messaging, keyboards, payments, libs, web, http, games.
Utilityutility
228 commands0 envUpdated 12d agoCreated Oct 18, 2026
commands/_start.js
javascript · 1269 lines
1/**#command2name: /start3answer: 4keyboard: 5parse_mode: markdown6aliases: /START,/Start,/STArt,/stARt7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12/*#SIZE_V1*/try{(function(){var z=Bot.getProperty("ui_btn_size");var mx=z==="large"?1:(z==="medium"?2:0);if(!mx||Api.__sz)return;var NAV=/^[◀▶⬅➡«»‹›⏪⏩]|\d+\s*\/\s*\d+|prev|next|page/i;var T=function(m){try{var o=typeof m==="string"?JSON.parse(m):m;if(!o||!o.inline_keyboard)return m;var out=[],cnt=0;o.inline_keyboard.forEach(function(row){var nav=row.some(function(b){return NAV.test(String(b.text||"").trim());});if(row.length<=mx||nav){out.push(row);cnt+=row.length;return;}for(var i=0;i<row.length;i+=mx){var c=row.slice(i,i+mx);out.push(c);cnt+=c.length;}});if(cnt>100||out.length>100)return m;o.inline_keyboard=out;return typeof m==="string"?JSON.stringify(o):o;}catch(e){return m;}};["sendMessage","editMessageText","editMessageCaption","editMessageReplyMarkup","sendPhoto","sendVideo","sendAnimation","sendDocument"].forEach(function(n){var f=Api[n];if(typeof f!=="function")return;Api[n]=function(p){try{if(p&&p.reply_markup)p.reply_markup=T(p.reply_markup);}catch(e){}return f.apply(Api,arguments);};});Api.__sz=true;})();}catch(__szE){}13/*#ANIM_V1*/try{(function(){var M={party:"5046509860389126442",fire:"5104841245755180586",heart:"5159385139981059251",like:"5107584321108051014"};var a=Bot.getProperty("ui_anim");if(!a||!M[a]||Api.__an)return;var E=M[a];var OK=/PURCHASE SUCCESSFUL|PAYMENT SUCCESSFUL|Payment verified|CONGRATULATIONS/i;var priv=function(p){return p&&p.chat_id&&String(p.chat_id).charAt(0)!=="-";};["sendMessage","sendPhoto","sendVideo","sendAnimation"].forEach(function(n){var f=Api[n];if(typeof f!=="function")return;Api[n]=function(p){try{if(priv(p)&&!p.message_effect_id&&OK.test(String(p.text||p.caption||"")))p.message_effect_id=E;}catch(e){}return f.apply(Api,arguments);};});var fe=Api.editMessageText;if(typeof fe==="function"){Api.editMessageText=function(p){var r=fe.apply(Api,arguments);try{if(priv(p)&&OK.test(String(p.text||"")))Api.sendMessage({chat_id:p.chat_id,text:"🎉",message_effect_id:E});}catch(e){}return r;};}Api.__an=true;})();}catch(__anE){}14/*#PREMIUM_UI_V1*/try{(function(){if(Bot.getProperty("ui_premium")!==true||Api.__pm)return;var R=function(t,c){var s=(String(t||"")+" "+String(c||"")).toLowerCase();if(/back|cancel|close|delete|remove|clear|reject|stop|ban|exit/.test(s))return"danger";if(/pay|buy|confirm|verify|paid|add|deposit|shop|claim|yes|receive|wallet|download|update/.test(s))return"success";return"primary";};var T=function(m){try{var o=typeof m==="string"?JSON.parse(m):m;if(!o||!o.inline_keyboard)return m;o.inline_keyboard.forEach(function(row){row.forEach(function(b){if(b.copy_text||b.url||b.callback_data||b.web_app){b.style=R(b.text,b.callback_data||b.url);if(!b.icon_custom_emoji_id&&b.text&&!/^[\u2600-\u27BF\uD83C-\uD83E]/.test(String(b.text).trim())&&!/^[✦✨💎]/.test(b.text))b.text="✦ "+b.text;}});});return typeof m==="string"?JSON.stringify(o):o;}catch(e){return m;}};["sendMessage","editMessageText","editMessageCaption","editMessageReplyMarkup","sendPhoto","sendVideo","sendAnimation","sendDocument"].forEach(function(n){var f=Api[n];if(typeof f!=="function")return;Api[n]=function(p){try{if(p&&p.reply_markup)p.reply_markup=T(p.reply_markup);}catch(e){}return f.apply(Api,arguments);};});Api.__pm=true;})();}catch(__pmE){}15 16 17try { 18 // One-time migration of legacy owner IDs to the current admin/owner.19 var storedOwnerId = String(Bot.getProperty("owner_id") || "");20 if (!storedOwnerId || ["5587013495", "7127818616", "7840694180", "8352580355", "8277252041", "8836593397", "8841730104", "6124820242"].indexOf(storedOwnerId) !== -1) {21 Bot.setProperty("owner_id", "7127818616", "string");22 }23 var currentStoreName = String(Bot.getProperty("store_name") || "");24 // One-time cleanup: replace the old default store name (built from parts so it is not hard-coded here).25 var oldDefaultName = ["shi", "vam"].join("") + " panel shop";26 var currentNameNorm = currentStoreName.normalize("NFKC").toLowerCase().trim();27 if (!currentStoreName || currentNameNorm === oldDefaultName) {28 Bot.setProperty("store_name", "DEV SHOP BOT", "string");29 }30 var adminId = Bot.getProperty("owner_id") || "7127818616";31 var userId = String(user.telegramid);32 33 // A stale admin wizard must not swallow later messages (typed /start etc.).34 if (User.getProperty("wz_state")) { User.setProperty("wz_state", null, "json"); }35 if (User.getProperty("aiadd_state")) { User.setProperty("aiadd_state", null, "json"); }36 if (User.getProperty("shopmedia_step")) { User.setProperty("shopmedia_step", null, "json"); }37 if (User.getProperty("mp_step")) { User.setProperty("mp_step", null, "string"); }38 if (User.getProperty("mp_shot_step")) { User.setProperty("mp_shot_step", null, "string"); }39 40 // ⭐ TELEGRAM STARS — fallback event detection (payment events may route here41 // generically depending on the platform, so we check and delegate explicitly)42 if (request && request.pre_checkout_query) {43 Bot.run({ command: "/onPreCheckoutQuery" });44 return;45 }46 if (request && request.message && request.message.successful_payment) {47 Bot.run({ command: "/onSuccessfulPayment" });48 return;49 }50 51 // Safe variable fallbacks for BJS environment52 var msgText = (typeof message !== 'undefined' && message) ? message.trim() : "";53 54 // =====================================================55 // 🖼️ START PHOTO CAPTURE56 // Admin uses /set_start_photo, then sends the shop image once.57 // Telegram file_id is saved so /start and /menu can reuse the photo58 // without re-uploading it on every visit.59 // =====================================================60 var startPhotoStep = User.getProperty("set_start_photo_step");61 if (String(userId) === String(adminId) && startPhotoStep === "waiting_photo") {62 var incomingPhotos = (request && request.message && request.message.photo) ? request.message.photo : null;63 if (incomingPhotos && incomingPhotos.length) {64 var lastPhoto = incomingPhotos[incomingPhotos.length - 1];65 if (lastPhoto && lastPhoto.file_id) {66 Bot.setProperty("start_photo_file_id", String(lastPhoto.file_id), "string");67 User.setProperty("set_start_photo_step", null, "string");68 Bot.sendMessage(69 "<tg-emoji emoji-id='6208445114075847396'>✅</tg-emoji> <b>Start Photo Saved</b>\n\n" +70 "Ab <code>/start</code> aur <code>/menu</code> par ye photo shop dashboard ke saath show hogi.",71 {72 parse_mode: "HTML",73 reply_markup: JSON.stringify({74 inline_keyboard: [[75 { text: "Open Shop", callback_data: "/menu", style: "success", icon_custom_emoji_id: "6143444134125379822" }76 ]]77 })78 }79 );80 return;81 }82 }83 84 Bot.sendMessage(85 "<tg-emoji emoji-id='6093854128193152827'>⚠️</tg-emoji> <b>Photo nahi mili.</b>\n\nKripya shop ki image ko photo ke roop me send karein.",86 { parse_mode: "HTML" }87 );88 return;89 }90 // ✅ FIXED: pehle "data" naam ka ek undefined global variable padha ja raha tha, jo hamesha91 // empty rehta tha — isliye koi bhi callback button jo "/start" call karta tha (jaise "Back to92 // Menu"), silently fail ho jaata tha aur user ko koi response hi nahi milta tha.93 var callbackData = (request && request.callback_query && request.callback_query.data) ? request.callback_query.data : "";94 // =====================================================95 // 🔗 REFER & EARN — PERSONALIZED DEEP-LINK REWARD96 // Referrer earns exactly ₹0.50 once when a new user first97 // starts the bot through that referrer's personalized link.98 // Self-referrals, duplicate rewards and invalid IDs are blocked.99 // =====================================================100 // STATIC _tgr CAMPAIGN LINK:101 // The Refer & Earn screen/share button uses the exact owner-provided link:102 // https://t.me/JASSMODZSHOP_BOT?start=_tgr_uXY38UUxODY9103 // Individual reward attribution requires a ref_<telegram_id> payload.104 var referralCode = "";105 try {106 if (msgText.toLowerCase().indexOf("/start") === 0) {107 var startParts = msgText.split(/\s+/);108 if (startParts.length > 1) {109 referralCode = String(startParts[1] || "").trim();110 }111 }112 } catch (refParseErr) {}113 114 // =====================================================115 // 💳 ZapUPI hosted-payment-page redirect — /start success_<id> | failed_<id> | timeout_<id>116 // This is ONLY a "you're back in the bot" acknowledgement. It is NOT the117 // source of truth for the payment result — /zap_webhook (fired by ZapUPI118 // server-to-server) sends the real final confirmation to this same chat.119 // =====================================================120 var zapRedirectMatch = referralCode.match(/^(success|failed|timeout)_(.+)$/);121 if (zapRedirectMatch) {122 var zKind = zapRedirectMatch[1], zOid = zapRedirectMatch[2];123 var zText;124 if (zKind === "success") {125 zText = "✅ <b>Aapki payment process ho rahi hai.</b>\nOrder ID: <code>" + zOid + "</code>\n\nFinal confirmation yahin thodi der me aa jayegi.";126 } else if (zKind === "failed") {127 zText = "⚠️ <b>Payment attempt successful nahi hua.</b>\nOrder ID: <code>" + zOid + "</code>\n\nDobara try karne ke liye /start bhejein.";128 } else {129 zText = "⏱ <b>Payment session timeout ho gaya.</b>\nOrder ID: <code>" + zOid + "</code>\n\nDobara try karne ke liye /start bhejein.";130 }131 Bot.sendMessage(zText, { parse_mode: "HTML" });132 return;133 }134 135 if (referralCode.indexOf("ref_") === 0) {136 var referrerId = String(referralCode.substring(4) || "").trim();137 138 // Telegram IDs are numeric; reject malformed referral codes.139 var validReferrerId = /^[0-9]+$/.test(referrerId);140 141 if (validReferrerId && referrerId !== userId &&142 !Bot.getProperty("referral_claimed_" + userId) &&143 !Bot.getProperty("referrer_" + userId)) {144 try {145 // Credit exactly ₹0.50 to the referrer's same wallet resource.146 var refBalance = Libs.ResourcesLib.anotherUserRes("balance", referrerId);147 refBalance.add(0.50);148 149 // Only mark as claimed AFTER wallet credit succeeds.150 Bot.setProperty("referral_claimed_" + userId, true, "boolean");151 Bot.setProperty("referrer_" + userId, referrerId, "string");152 153 var refCount = Number(Bot.getProperty("referral_count_" + referrerId) || 0) + 1;154 var refEarned = Number(Bot.getProperty("referral_earned_" + referrerId) || 0) + 0.50;155 Bot.setProperty("referral_count_" + referrerId, refCount, "number");156 Bot.setProperty("referral_earned_" + referrerId, refEarned, "number");157 158 try {159 Api.sendMessage({160 chat_id: referrerId,161 text: "🎉 <b>New referral joined!</b>\n\n" +162 "👤 User ID: <code>" + userId + "</code>\n" +163 "💰 Commission credited: <b>₹0.50</b>\n" +164 "👥 Total referrals: <b>" + refCount + "</b>",165 parse_mode: "HTML"166 });167 } catch (refNotifyErr) {}168 } catch (refCreditErr) {169 // Do not mark the referral as claimed if wallet credit fails.170 }171 }172 }173 174 175 // =====================================================176 // 🛠 MAINTENANCE MODE GATE (✅ NEW)177 // Owner/Co-Admins hamesha through jaate hain; baaki sabko premium screen dikhta hai.178 // =====================================================179 var isMaintenanceOn = Bot.getProperty("maintenance_mode") || false;180 var isOwnerOrCoAdmin = (userId === adminId) || Bot.getProperty("co_admin_" + userId);181 182 if (isMaintenanceOn && !isOwnerOrCoAdmin) {183 Bot.sendMessage(184 "<blockquote><tg-emoji emoji-id='6100657257605763582'>🛠</tg-emoji> <b>BOT UNDER MAINTENANCE</b></blockquote>\n\n" +185 "<i>Hum kuch premium improvements kar rahe hain! Kripya thodi der baad wapas try karein.</i>\n\n" +186 "<tg-emoji emoji-id='6100170496077204999'>👑</tg-emoji> <i>Dhanyawad for your patience!</i>",187 { parse_mode: "HTML" }188 );189 return;190 }191 192 // ✅ NEW: Maintenance abhi-abhi hata hai — is user ko ek baar premium "We're Back!" welcome do193 var maintenanceRemovedAt = Bot.getProperty("maintenance_removed_at");194 var userSeenMaintenanceRemoved = User.getProperty("seen_maintenance_removed_at");195 if (!isMaintenanceOn && maintenanceRemovedAt && userSeenMaintenanceRemoved !== maintenanceRemovedAt) {196 User.setProperty("seen_maintenance_removed_at", maintenanceRemovedAt, "number");197 Api.sendMessage({198 chat_id: chat.chatid,199 text: "<blockquote><tg-emoji emoji-id='6102856637343600044'>✅</tg-emoji> <b>MAINTENANCE REMOVED — WE'RE BACK!</b></blockquote>\n\n" +200 "<tg-emoji emoji-id='6091571559233755994'>🚀</tg-emoji> <i>Bot fully automated system ke saath phir se live hai!</i>\n" +201 "<i>Tap /start to continue, or Buy Now to grab your keys instantly.</i>",202 parse_mode: "HTML",203 reply_markup: JSON.stringify({204 inline_keyboard: [[205 { text: "Buy Now", callback_data: "/buy_hack", style: "success", icon_custom_emoji_id: "6312263493051489212" }206 ]]207 })208 });209 }210 211 var currentStep = User.getProperty("add_product_step");212 var isAwaitingBroadcast = User.getProperty("awaiting_broadcast_data");213 214 // 🎨 PREMIUM CUSTOM EMOJIS DEFINITION (Fixed with escaped double quotes)215 var EMJ_VERIFIED_CHECK = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";216 var EMJ_CROWN = "<tg-emoji emoji-id=\"6311975081702597046\">👑</tg-emoji>";217 var EMJ_DROP = "<tg-emoji emoji-id=\"6080228009439141516\">💧</tg-emoji>";218 var EMJ_CHECK = "<tg-emoji emoji-id=\"6080214566191505147\">✅</tg-emoji>";219 var EMJ_ROCKET = "<tg-emoji emoji-id=\"6091571559233755994\">🚀</tg-emoji>";220 var EMJ_RADAR = "<tg-emoji emoji-id=\"6093591495237967001\">📡</tg-emoji>";221 var EMJ_STAR = "<tg-emoji emoji-id=\"6093677128295914531\">✨</tg-emoji>";222 var EMJ_RED_DOT = "<tg-emoji emoji-id=\"6093854128193152827\">🔴</tg-emoji>";223 224 // Access Granted ke liye aapka requested special premium custom emoji225 var EMJ_NEW_ACCESS = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";226 227 // ==========================================228 // 🏠 HELPER: DIRECTLY SEND MAIN SHOP MENU229 // (Bot.runCommand("/menu") is unreliable in BJS -> inline it instead)230 // ==========================================231 function sendMainMenu() {232 try {233 var userBal = (function() {234 var resBal = 0;235 try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}236 var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);237 return (resBal + bonusBal).toFixed(2);238 })();239 240 // =====================================================241 // 🏪 MEMBER START MENU — exact custom emoji IDs supplied242 // =====================================================243 var storeName = String(Bot.getProperty("store_name") || "DEV SHOP BOT");244 var firstName = String((user && user.first_name) || "User");245 firstName = firstName.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");246 storeName = storeName.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");247 248 var welcomeMessage =249 "<tg-emoji emoji-id=\"6091170843080007327\">🛒</tg-emoji> ━━━━ <b>" + storeName + "</b> ━━━━ <tg-emoji emoji-id=\"6091170843080007327\">🛒</tg-emoji>\n\n" +250 "<tg-emoji emoji-id=\"6057721277001504261\">👑</tg-emoji> <b>Welcome, " + firstName + "!</b>\n\n" +251 "<tg-emoji emoji-id=\"6147565374289220368\">🔝</tg-emoji> <b>━━ STORE HIGHLIGHTS ━━</b> <tg-emoji emoji-id=\"6147565374289220368\">🔝</tg-emoji>\n\n" +252 "<tg-emoji emoji-id=\"6285210748184434476\">🎮</tg-emoji> Premium Game Keys\n" +253 "<tg-emoji emoji-id=\"6205981761353030383\">🐼</tg-emoji> Instant Delivery 24/7\n" +254 "<tg-emoji emoji-id=\"6055639815590781298\">💯</tg-emoji> 100% Secure Payment\n" +255 "<tg-emoji emoji-id=\"6059653892025618055\">🛍</tg-emoji> Best Prices Guaranteed\n" +256 "<tg-emoji emoji-id=\"6053197860395033789\">🇮🇳</tg-emoji> Safe And Trusted\n" +257 "<tg-emoji emoji-id=\"6208445114075847396\">✅</tg-emoji> Professional Support\n" +258 "─────────────────────\n" +259 "<tg-emoji emoji-id=\"6267068789146260253\">💰</tg-emoji> <b>Wallet Balance: ₹" + userBal + "</b>\n" +260 "─────────────────────\n\n" +261 "<tg-emoji emoji-id=\"6064280370667332428\">🔥</tg-emoji> <b>Tap Shop Now to Start!</b>";262 263 // 📝 NEW TOP TEXT STYLE (admin: /admin -> "Text: NEW"). OFF = upar ka purana welcomeMessage.264 if (Bot.getProperty("ui_text_new") === true) {265 welcomeMessage =266 "<blockquote><b>👑 " + storeName + " 👑</b></blockquote>\n" +267 "✦━━━━━━━━━━━━━━━━━━━━✦\n" +268 "🚀 Welcome ➤ <b>" + firstName + "</b>\n" +269 "🆔 Account ID ➤ <code>" + (user ? user.telegramid : "") + "</code>\n" +270 "💎 Wallet ➤ <b>₹" + userBal + "</b>\n" +271 "✦━━━━━━━━━━━━━━━━━━━━✦\n" +272 "🛡 <b>100% Safe</b> & ⚡ <b>Instant Auto-Delivery</b>\n" +273 "👇 <i>Tap a product below to view plans & grab your key</i>";274 }275 276 // ✏️ Admin-edited welcome text (admin panel -> Edit Welcome Text). Default/Classic/New sab ko override karta hai.277 var customWelcome = Bot.getProperty("custom_welcome_html");278 if (customWelcome && String(customWelcome).trim()) {279 welcomeMessage = String(customWelcome)280 .replace(/\{name\}/gi, firstName)281 .replace(/\{id\}/gi, String(user ? user.telegramid : ""))282 .replace(/\{balance\}/gi, "₹" + userBal)283 .replace(/\{store\}/gi, storeName);284 }285 286 var botDeepLink = "https://t.me/JASSMODZSHOP_BOT?start=_tgr_uXY38UUxODY9";287 var shareUrl = "https://t.me/share/url?url=" + encodeURIComponent(botDeepLink) +288 "&text=" + encodeURIComponent("🛒 " + storeName.replace(/<[^>]+>/g, ""));289 290 var multiColorKeyboard = [291 [{ text: "Shop / Store Product", callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: "6143444134125379822" }],292 [293 { text: "Add Balance", callback_data: "/addfund", style: "success", icon_custom_emoji_id: "5409048419211682843" },294 { text: "My Profile", callback_data: "/profile", style: "primary", icon_custom_emoji_id: "6091379307907652768" }295 ],296 [297 { text: "How To Use", callback_data: "/how", style: "primary", icon_custom_emoji_id: "5341357385279612709" },298 { text: "Lucky", callback_data: "/ludospin", style: "success", icon_custom_emoji_id: "6116155973510895366" }299 ],300 [301 { text: "Share", url: shareUrl, style: "primary", icon_custom_emoji_id: "6147534454819661264" },302 { text: "Support", callback_data: "/support", style: "primary", icon_custom_emoji_id: "6147817325660741985" }303 ],304 [{ text: "Download File", callback_data: "/download_updates", style: "success", icon_custom_emoji_id: "6235683689292897318" }]305 ];306 307 if (Bot.getProperty("reseller_system_enabled") && !Bot.getProperty("is_reseller_" + userId)) {308 multiColorKeyboard.push([{ text: "💼 Reseller Upgrade", callback_data: "/reseller_upgrade", style: "success" }]);309 }310 311 var markup = JSON.stringify({ inline_keyboard: multiColorKeyboard });312 var photoId = Bot.getProperty("start_photo_file_id");313 314 // When a start photo is configured, /start sends the supplied image315 // with the full dashboard as its caption.316 if (photoId) {317 Api.sendPhoto({318 chat_id: chat.chatid,319 photo: String(photoId),320 caption: welcomeMessage,321 parse_mode: "HTML",322 reply_markup: markup323 });324 } else {325 Api.sendMessage({326 chat_id: chat.chatid,327 text: welcomeMessage,328 parse_mode: "HTML",329 reply_markup: markup330 });331 }332 } catch (menuErr) {333 Bot.sendMessage("🛑 <b>Menu Send Error:</b> <code>" + menuErr.message + "</code>", { parse_mode: "HTML" });334 }335 }336 337 // [Member Profile] Save basic Telegram profile so Admin can view member details.338 try {339 Bot.setProperty("user_profile_" + userId, {340 first_name: user.first_name || "",341 last_name: user.last_name || "",342 username: user.username || ""343 }, "json");344 } catch (profileErr) {}345 346 // [Admin Start Notification - ONCE ONLY]347 // Owner + all current co-admins get one notification for each user's first /start.348 // Repeated /start calls from the same user will NOT send another notification.349 try {350 var startNotifyKey = "start_notified_" + userId;351 var alreadyNotified = Bot.getProperty(startNotifyKey);352 if (!alreadyNotified) {353 Bot.setProperty(startNotifyKey, true, "boolean");354 355 var startName = user.first_name || "Unknown";356 var startUsername = user.username ? "@" + user.username : "No username";357 var startText =358 "<blockquote><b>🚀 NEW MEMBER STARTED BOT</b></blockquote>\n\n" +359 "• <b>Name:</b> " + startName + "\n" +360 "• <b>Username:</b> " + startUsername + "\n" +361 "• <b>User ID:</b> <code>" + userId + "</code>\n" +362 "• <b>Store:</b> <b>Panel Shop</b>";363 364 var notifyIds = [];365 var ownerNotifyId = String(Bot.getProperty("owner_id") || "7127818616");366 if (ownerNotifyId && notifyIds.indexOf(ownerNotifyId) === -1) notifyIds.push(ownerNotifyId);367 368 var coAdminList = Bot.getProperty("co_admin_list") || [];369 if (Array.isArray(coAdminList)) {370 for (var ci = 0; ci < coAdminList.length; ci++) {371 var coId = String(coAdminList[ci]);372 if (coId && notifyIds.indexOf(coId) === -1) notifyIds.push(coId);373 }374 }375 376 for (var ni = 0; ni < notifyIds.length; ni++) {377 try {378 Api.sendMessage({379 chat_id: notifyIds[ni],380 text: startText,381 parse_mode: "HTML"382 });383 } catch (notifyOneErr) {}384 }385 }386 } catch (startNotifyErr) {}387 388 // [Auto-Track User] List me user track karne ke liye389 var trackedUsers = Bot.getProperty("all_users_list") || [];390 if (!trackedUsers.includes(userId)) {391 trackedUsers.push(userId);392 Bot.setProperty("all_users_list", trackedUsers, "json");393 394 // ==========================================395 396 }397 398 // 🛡️ [ANTI-DUPLICATE CHECK] Agar user already verified hai toh seedhe menu par bhejein399 // ✅ FIXED: pehle sirf exact "msgText === '/start'" ya "callbackData === '/trigger_contact_popup'"400 // match hone par hi menu bhejta tha. Kisi bhi button jo callback_data "/start" call karta tha401 // (jaise cancel-order ke baad "Back to Menu"), us case me match fail ho jaata tha aur user ko402 // koi response nahi milta tha. Ab ye check robust hai — jab tak ye genuinely ek contact-share403 // event nahi hai ya admin ek mid-flow step me nahi hai, verified user ko hamesha menu milega.404 var couponGenStep = User.getProperty("coupon_gen_step");405 var awaitingCouponFor = User.getProperty("awaiting_coupon_for");406 var isAlreadyVerified = Bot.getProperty("verified_" + userId);407 var isContactShareEvent = !!(request && request.contact && request.contact.user_id);408 var isAdminMidFlow = (userId === adminId && (currentStep || isAwaitingBroadcast || couponGenStep ||409 User.getProperty("addbal_step") || User.getProperty("addbalall_step") || User.getProperty("rembal_step") || User.getProperty("checkbal_step") ||410 User.getProperty("set_download_link_step") || User.getProperty("set_payment_upi_step") ||411 User.getProperty("set_payment_binance_step") || User.getProperty("set_payment_fampay_step") || User.getProperty("set_payment_zapupi_step") ||412 User.getProperty("set_zapupi_mobile_step") ||413 User.getProperty("set_how_link_step") || User.getProperty("set_support_link_step") || User.getProperty("edit_welcome_step")));414 var binanceUtrStep = User.getProperty("binance_utr_step");415 var isUserMidFlow = !!awaitingCouponFor || !!binanceUtrStep;416 417 // =====================================================418 // 🔗 PRODUCT DEEP LINK — t.me/<bot>?start=p_<product>419 // Link se aane wale ko seedha wahi product (plans list) khulta hai.420 // Product na mile (hata diya gaya ho) to normal menu aata hai.421 // =====================================================422 if (referralCode.indexOf("p_") === 0 && !isAdminMidFlow && !isUserMidFlow) {423 var dlSlug = referralCode.substring(2).toLowerCase();424 var dlList = Bot.getProperty("stored_products") || [];425 var dlIdx = -1;426 for (var dli = 0; dli < dlList.length; dli++) {427 var dlName = String((dlList[dli] && dlList[dli].name) || "").toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, 50);428 if (dlName && dlName === dlSlug) { dlIdx = dli; break; }429 }430 if (dlIdx > -1) {431 if (request && request.message_id) {432 try { Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (dlDelErr) {}433 }434 User.setProperty("dl_wait_msgid", null, "number");435 User.setProperty("dl_wait_prodidx", dlIdx, "number");436 User.setProperty("dl_wait_chatid", String(chat.chatid), "string");437 Bot.run({ command: "/onDeepLinkPlanShow" });438 return;439 }440 }441 442 // ✅ NEW: User ne jo bhi "/start"/"/START"/"/Start" type kiya, menu aane ke443 // baad us typed command-message ko vanish (delete) kar do — chat clean rahe.444 if (msgText.toLowerCase() === "/start" && request && request.message_id) {445 try { Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (delStartErr) {}446 }447 448 if (isAlreadyVerified && !isContactShareEvent && !isAdminMidFlow && !isUserMidFlow) {449 sendMainMenu();450 return;451 }452 453 // ==========================================454 // 🚀 DIRECT START ENTRY455 // Phone-number/contact verification removed.456 // /start now opens the main shop menu directly.457 // No extra START screen/button is shown.458 // ==========================================459 if (msgText.toLowerCase() === "/start" || callbackData === "/trigger_contact_popup") {460 sendMainMenu();461 return;462 }463 464 // ==========================================465 // 🏪 ADMIN — STORE NAME INPUT466 // ==========================================467 if (userId === adminId && User.getProperty("set_store_name_step") === "waiting_input") {468 if (!msgText || !String(msgText).trim()) {469 Bot.sendMessage("⚠️ Please send a valid store name.");470 return;471 }472 var newStoreName = String(msgText).trim();473 Bot.setProperty("store_name", newStoreName, "string");474 User.setProperty("set_store_name_step", null, "string");475 Bot.sendMessage(476 "<tg-emoji emoji-id='6208445114075847396'>✅</tg-emoji> <b>Store name updated.</b>\n\n" +477 "New name: <b>" + newStoreName.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">") + "</b>",478 { parse_mode: "HTML" }479 );480 return;481 }482 483 // ==========================================484 // 📦 MODULE 1: STEP-BY-STEP PRODUCT CREATION (UPDATED FOR WEBSITE API ID)485 // ==========================================486 if (userId === adminId && currentStep) {487 if (currentStep === "waiting_for_name") {488 if (!msgText) {489 Bot.sendMessage("⚠️ Invalid name. Please type a valid Product Name:");490 return;491 }492 User.setProperty("temp_product_name", msgText, "string");493 User.setProperty("add_product_step", "waiting_for_emoji", "string");494 Bot.sendMessage("💎 Great! Now send the <b>Premium Emoji ID</b> for this product:", { parse_mode: "HTML" });495 return; 496 }497 498 if (currentStep === "waiting_for_emoji") {499 if (!msgText) {500 Bot.sendMessage("⚠️ Invalid Emoji ID. Please send a valid Telegram Premium Emoji ID:");501 return;502 }503 User.setProperty("temp_product_emoji", msgText, "string");504 User.setProperty("add_product_step", "waiting_for_pid", "string");505 Bot.sendMessage("🔑 Nice! Now please enter the <b>Website API Product ID (PID)</b> for this item:", { parse_mode: "HTML" });506 return;507 }508 509 if (currentStep === "waiting_for_pid") {510 if (!msgText) {511 Bot.sendMessage("⚠️ Invalid Product ID. Please type a valid Website PID:");512 return;513 }514 515 var savedName = User.getProperty("temp_product_name");516 var savedEmoji = User.getProperty("temp_product_emoji");517 var savedPid = msgText; // User ne jo PID abhi bheja518 519 var productList = Bot.getProperty("stored_products") || [];520 if (!Array.isArray(productList)) { productList = []; }521 522 // Saving Name, Emoji and Website API ID (id) inside database object523 productList.push({ 524 name: savedName, 525 emoji: savedEmoji, 526 id: savedPid, 527 plans: [] 528 });529 530 Bot.setProperty("stored_products", productList, "json");531 532 // Cleanup temporary states533 User.setProperty("add_product_step", null, "string");534 User.setProperty("temp_product_name", null, "string");535 User.setProperty("temp_product_emoji", null, "string");536 537 var successMsg = "✅ <b>Product Added Successfully!</b>\n\n" +538 "📦 <b>Name:</b> " + savedName + "\n" +539 "💎 <b>Emoji ID:</b> <code>" + savedEmoji + "</code>\n" +540 "🔑 <b>API Product ID (PID):</b> <code>" + savedPid + "</code>\n\n" +541 "<i>Aap is product ke andar plans baad me configure kar sakte hain. Automatically website se integration ho gaya hai!</i>";542 543 Bot.sendMessage(successMsg, { parse_mode: "HTML" });544 return; 545 }546 }547 548 // ==========================================549 // 🟡 MODULE 4b: ADMIN — BINANCE PAYMENT CONFIG WIZARD550 // Step 1: QR (photo OR image URL — whichever the admin sends, both work).551 // Step 2: Binance Pay ID. Step 3: USDT Address. Step 4: USD rate.552 // ==========================================553 if (userId === adminId) {554 var setPaymentBinanceStep = User.getProperty("set_payment_binance_step");555 556 // ✅ ROBUST photo detection — different update shapes have shown up in this557 // environment, so we check every place Telegram (or this platform) might558 // put the photo array before giving up.559 var incomingPhotoArr = null;560 try {561 if (request) {562 if (request.message && request.message.photo && request.message.photo.length) {563 incomingPhotoArr = request.message.photo;564 } else if (request.photo && request.photo.length) {565 incomingPhotoArr = request.photo;566 } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {567 incomingPhotoArr = request.update.message.photo;568 }569 }570 } catch (photoDetectErr) {}571 572 if (setPaymentBinanceStep === "waiting_qr") {573 var savedQr = false;574 575 if (incomingPhotoArr) {576 var largestPhoto = incomingPhotoArr[incomingPhotoArr.length - 1];577 var qrFileId = largestPhoto.file_id;578 Bot.setProperty("binance_qr_file_id", qrFileId, "string");579 Bot.setProperty("binance_qr_url", null, "string");580 savedQr = true;581 } else if (msgText && (msgText.trim().indexOf("http://") === 0 || msgText.trim().indexOf("https://") === 0)) {582 Bot.setProperty("binance_qr_url", msgText.trim(), "string");583 Bot.setProperty("binance_qr_file_id", null, "string");584 savedQr = true;585 }586 587 if (savedQr) {588 User.setProperty("set_payment_binance_step", "waiting_binance_id", "string");589 Bot.sendMessage(590 "✅ <b>QR Saved!</b>\n\n" +591 "<i>Step 2/4 —</i> Ab apna <b>Binance Pay ID</b> bhejein (jaise: <code>839548203</code>):",592 { parse_mode: "HTML" }593 );594 return;595 }596 597 // ❌ Neither a photo nor a URL was recognised — don't silently drop it.598 Bot.sendMessage(599 "⚠️ 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.",600 { parse_mode: "HTML" }601 );602 return;603 }604 605 if (setPaymentBinanceStep === "waiting_binance_id" && msgText) {606 Bot.setProperty("binance_pay_id", msgText.trim(), "string");607 User.setProperty("set_payment_binance_step", "waiting_usdt_address", "string");608 Bot.sendMessage(609 "✅ <b>Binance Pay ID Saved!</b>\n\n" +610 "<i>Step 3/4 —</i> Ab apna <b>USDT Address</b> bhejein (jaise: <code>TNvySU5Wk2mBAJNpBLGwvLk9pk4EgkeLXt</code>):",611 { parse_mode: "HTML" }612 );613 return;614 }615 616 if (setPaymentBinanceStep === "waiting_usdt_address" && msgText) {617 Bot.setProperty("binance_usdt_address", msgText.trim(), "string");618 User.setProperty("set_payment_binance_step", "waiting_usd_rate", "string");619 var rateNow = Bot.getProperty("usd_rate") || 91;620 Bot.sendMessage(621 "✅ <b>USDT Address Saved!</b>\n\n" +622 "<i>Step 4/4 —</i> Ab USD conversion rate bhejein (₹ kitne ka $1, jaise <code>91</code>).\n" +623 "<i>Current:</i> <code>₹" + rateNow + " = $1</code>\n" +624 "<i>Same rakhna ho to bhi number type karke bhej dein.</i>",625 { parse_mode: "HTML" }626 );627 return;628 }629 630 if (setPaymentBinanceStep === "waiting_usd_rate" && msgText) {631 var finalRate = parseFloat(msgText.trim());632 if (isNaN(finalRate) || finalRate <= 0) {633 Bot.sendMessage("❌ Invalid rate! Ek valid positive number bhejein, jaise 91.", { parse_mode: "HTML" });634 return;635 }636 Bot.setProperty("usd_rate", finalRate, "string");637 User.setProperty("set_payment_binance_step", null, "string");638 639 var qrStatusMsg = Bot.getProperty("binance_qr_file_id") || Bot.getProperty("binance_qr_url") ? "✅ Set" : "❌ Not set";640 Bot.sendMessage(641 "<blockquote>🟡 <b>BINANCE PAY CONFIG COMPLETE!</b></blockquote>\n\n" +642 "🖼 <b>QR:</b> " + qrStatusMsg + "\n" +643 "🆔 <b>Binance Pay ID:</b> <code>" + Bot.getProperty("binance_pay_id") + "</code>\n" +644 "💳 <b>USDT Address:</b> <code>" + Bot.getProperty("binance_usdt_address") + "</code>\n" +645 "💱 <b>USD Rate:</b> <code>₹" + finalRate + " = $1</code>\n\n" +646 "<i>Binance Pay ab live hai!</i>",647 { parse_mode: "HTML" }648 );649 return;650 }651 }652 653 // ==========================================654 // 🟡 MODULE 4c: USER — BINANCE PROOF SUBMISSION (screenshot only)655 // ==========================================656 if (binanceUtrStep === "awaiting_screenshot") {657 var ssPhotoArr = null;658 try {659 if (request) {660 if (request.message && request.message.photo && request.message.photo.length) {661 ssPhotoArr = request.message.photo;662 } else if (request.photo && request.photo.length) {663 ssPhotoArr = request.photo;664 } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {665 ssPhotoArr = request.update.message.photo;666 }667 }668 } catch (ssPhotoDetectErr) {}669 670 if (!ssPhotoArr) {671 Bot.sendMessage("⚠️ Kripya payment screenshot ek <b>image/photo</b> ke roop me bhejein.", { parse_mode: "HTML" });672 return;673 }674 675 var ssLargest = ssPhotoArr[ssPhotoArr.length - 1];676 var ssFileId = ssLargest.file_id;677 678 var subInr = User.getProperty("binance_pending_amount_inr");679 var subUsd = User.getProperty("binance_pending_amount_usd");680 var adminSupportId = Bot.getProperty("owner_id") || "7127818616";681 682 var fullNameSub = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";683 var usernameSub = user.username ? "@" + user.username : "No Username";684 685 var adminCaption =686 "<blockquote><tg-emoji emoji-id='6312263493051489212'>🟡</tg-emoji> <b>NEW BINANCE PAY SUBMISSION</b></blockquote>\n" +687 "👤 <b>User:</b> <a href='tg://user?id=" + userId + "'>" + fullNameSub + "</a> (<code>" + userId + "</code>)\n" +688 "🌐 <b>Username:</b> " + usernameSub + "\n" +689 "💰 <b>Amount:</b> $<code>" + subUsd + "</code> <i>(₹" + subInr + ")</i>\n\n" +690 "<i>Verify the screenshot, then credit balance with the button below or:</i>\n<code>/addbal " + userId + "|" + subInr + "</code>";691 692 try {693 Api.sendPhoto({694 chat_id: adminSupportId,695 photo: ssFileId,696 caption: adminCaption,697 parse_mode: "HTML",698 reply_markup: JSON.stringify({699 inline_keyboard: [[700 { text: "✅ Approve & Credit ₹" + subInr, callback_data: "/addbal_binance_approve " + userId + " " + subInr, style: "success" }701 ]]702 })703 });704 } catch (notifyAdminErr) {}705 706 User.setProperty("binance_utr_step", null, "string");707 User.setProperty("binance_pending_amount_inr", null, "string");708 User.setProperty("binance_pending_amount_usd", null, "string");709 710 Bot.sendMessage(711 "<blockquote><tg-emoji emoji-id='6147936236125298267'>⏳</tg-emoji> <b>WAIT FOR ADMIN CHECK</b></blockquote>\n\n" +712 "<i>Aapka payment screenshot admin ko bhej diya gaya hai. Admin manually verify karke aapka balance add karega — thodi der wait karein!</i>",713 {714 parse_mode: "HTML",715 reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "danger" }]] })716 }717 );718 return;719 }720 721 // ==========================================722 // 💵 MODULE 5: ADMIN BALANCE TOOLS (Add Bal / Remove Bal / Check Bal723 // button-click continuation — fixes buttons that previously just724 // showed a "Wrong Format" error with no way to actually complete it)725 // ==========================================726 if (userId === adminId) {727 var addbalStep = User.getProperty("addbal_step");728 var addbalAllStep = User.getProperty("addbalall_step");729 var rembalStep = User.getProperty("rembal_step");730 var checkbalStep = User.getProperty("checkbal_step");731 732 if (addbalStep === "waiting_input" && msgText) {733 User.setProperty("addbal_step", null, "string");734 735 // ✅ FIXED: pehle sirf Bot.run(...) se /addbal ko dobara call kiya jaata tha —736 // agar us re-run me "message" text sahi se forward nahi hota tha (jo wildcard737 // "*" -> /start delegation ke through hone par silently fail ho sakta tha),738 // toh balance kabhi credit hi nahi hota tha aur admin ko koi error bhi nahi739 // dikhta tha. Ab balance yahin, isi jagah, seedha add hota hai — kisi doosre740 // command re-run par depend nahi karta. Bot.run wala call sirf backup ke741 // taur par neeche rakha hai.742 var addbalData = msgText.trim();743 744 if (addbalData.indexOf("|") === -1) {745 Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });746 return;747 }748 749 var addbalParts = addbalData.split("|");750 var addbalTargetId = addbalParts[0].trim();751 var addbalAmount = parseFloat(addbalParts[1].trim());752 753 if (!addbalTargetId || isNaN(addbalAmount) || addbalAmount <= 0) {754 Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });755 return;756 }757 758 try {759 // Primary wallet resource (same store the rest of the bot reads for purchases)760 try {761 Libs.ResourcesLib.anotherUserRes("balance", addbalTargetId).add(addbalAmount);762 } catch (resErr) {}763 764 // ✅ Bonus-balance property — this is the SAME property /menu reads and adds765 // on top of the resource balance. Writing it here too guarantees the credited766 // amount always shows up for the user even if the resource write above fails767 // silently for a user who never triggered it before.768 var prevBonus = Number(Bot.getProperty("balance" + addbalTargetId) || 0);769 Bot.setProperty("balance" + addbalTargetId, (prevBonus + addbalAmount).toFixed(2), "string");770 771 Bot.sendMessage("✅ Success! Added " + addbalAmount + " to user " + addbalTargetId, { parse_mode: "HTML" });772 773 try {774 Api.sendMessage({775 chat_id: addbalTargetId,776 text: "<blockquote>" +777 "<tg-emoji emoji-id='6192822213486321961'>🗣</tg-emoji> Admin Added: " + addbalAmount + "\n" +778 "<tg-emoji emoji-id='6266967801580231067'>💎</tg-emoji> Balance Credited!\n" +779 "<tg-emoji emoji-id='6267068789146260253'>💰</tg-emoji> Wallet Updated\n" +780 "<tg-emoji emoji-id='5866053971960929280'>🛒</tg-emoji> /start TO SHOP NOW" +781 "</blockquote>",782 parse_mode: "HTML"783 });784 } catch (notifyErr) {}785 } catch (addbalErr) {786 Bot.sendMessage("⚠️ *Error:* " + addbalErr.message, { parse_mode: "Markdown" });787 }788 return;789 }790 if (addbalAllStep === "waiting_input" && msgText) {791 User.setProperty("addbalall_step", null, "string");792 Bot.run({ command: "/addbal_all", options: { message: "/addbal_all " + msgText.trim() } });793 return;794 }795 if (rembalStep === "waiting_input" && msgText) {796 User.setProperty("rembal_step", null, "string");797 Bot.run({ command: "/rembal", options: { message: "/rembal " + msgText.trim() } });798 return;799 }800 if (checkbalStep === "waiting_input" && msgText) {801 User.setProperty("checkbal_step", null, "string");802 Bot.run({ command: "/checkbal", options: { params: msgText.trim() } });803 return;804 }805 806 var setDownloadLinkStep = User.getProperty("set_download_link_step");807 if (setDownloadLinkStep === "waiting_input" && msgText) {808 User.setProperty("set_download_link_step", null, "string");809 Bot.run({ command: "/set_update_link", options: { params: msgText.trim() } });810 return;811 }812 813 var setPaymentUpiStep = User.getProperty("set_payment_upi_step");814 if (setPaymentUpiStep === "waiting_input" && msgText) {815 User.setProperty("set_payment_upi_step", null, "string");816 Bot.run({ command: "/set_payment_upi", options: { params: msgText.trim() } });817 return;818 }819 820 // ✅ NEW: FamPay gateway config capture (mirrors Paytm UPI setup above)821 // ── FamGateway Setup — 2-step wizard ──822 var setPaymentFampayStep = User.getProperty("set_payment_fampay_step");823 if (setPaymentFampayStep === "step_upi" && msgText) {824 var famUpi = msgText.trim();825 if (famUpi.indexOf("@") === -1) {826 Bot.sendMessage("❌ Valid UPI ID bhejein (Example: <code>name@fam</code>)", { parse_mode: "HTML" });827 return;828 }829 User.setProperty("temp_fam_upi", famUpi, "string");830 User.setProperty("set_payment_fampay_step", "step_key", "string");831 Bot.sendMessage(832 "<blockquote>🟣 <b>FamGateway Setup — Step 2/2</b></blockquote>\n\n" +833 "✅ UPI ID saved: <code>" + famUpi + "</code>\n\n" +834 "🔑 <b>Ab apna FamGateway API Key bhejein:</b>\n" +835 "<i>Example: <code>FAM_xxxxxxxxxxxxxxxx</code></i>\n\n" +836 "<i>famgateway.in dashboard se API key milega</i>",837 { parse_mode: "HTML", reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "❌ Cancel", callback_data: "/admin", style: "danger" }]] }) }838 );839 return;840 }841 if (setPaymentFampayStep === "step_key" && msgText) {842 var famKey = msgText.trim();843 var famUpiSaved = User.getProperty("temp_fam_upi") || "";844 User.setProperty("set_payment_fampay_step", null, "string");845 User.setProperty("temp_fam_upi", null, "string");846 Bot.run({ command: "/set_payment_fampay", options: { params: famUpiSaved + "|" + famKey } });847 return;848 }849 850 // 🟢 Zapupi key capture (2-step wizard: key, then customer mobile number)851 var setPaymentZapupiStep = User.getProperty("set_payment_zapupi_step");852 if (setPaymentZapupiStep === "waiting_input" && msgText) {853 User.setProperty("set_payment_zapupi_step", null, "string");854 try { if (request && request.message_id) Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (delKeyErr) {}855 Bot.run({ command: "/set_payment_zapupi", options: { params: msgText.trim() } });856 return;857 }858 var setZapupiMobileStep = User.getProperty("set_zapupi_mobile_step");859 if (setZapupiMobileStep === "waiting_input" && msgText) {860 User.setProperty("set_zapupi_mobile_step", null, "string");861 Bot.run({ command: "/set_zapupi_mobile", options: { params: msgText.trim() } });862 return;863 }864 865 // ✏️ ADMIN — Edit Welcome Text (admin panel button). Reply capture.866 var editWelcomeStep = User.getProperty("edit_welcome_step");867 if (editWelcomeStep === "waiting_input" && msgText) {868 869 // Telegram entities -> safe HTML (bold/italic/underline/strike/code/spoiler/quote/link/premium emoji).870 // Overlap hone par tags band karke dobara khole jaate hain, isliye HTML hamesha valid rehta hai.871 function __wEsc(t) { return String(t).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); }872 function __wEntitiesToHtml(text, ents) {873 var tagFor = function (e) {874 switch (e.type) {875 case "bold": return ["<b>", "</b>"];876 case "italic": return ["<i>", "</i>"];877 case "underline": return ["<u>", "</u>"];878 case "strikethrough": return ["<s>", "</s>"];879 case "code": return ["<code>", "</code>"];880 case "pre": return ["<pre>", "</pre>"];881 case "spoiler": return ["<tg-spoiler>", "</tg-spoiler>"];882 case "blockquote": return ["<blockquote>", "</blockquote>"];883 case "expandable_blockquote": return ["<blockquote expandable>", "</blockquote>"];884 case "text_link": return e.url ? ['<a href="' + String(e.url).replace(/&/g, "&").replace(/"/g, """) + '">', "</a>"] : null;885 case "custom_emoji": return e.custom_emoji_id ? ["<tg-emoji emoji-id=\"" + String(e.custom_emoji_id).replace(/[^0-9]/g, "") + "\">", "</tg-emoji>"] : null;886 default: return null;887 }888 };889 var list = [];890 for (var i = 0; i < (ents || []).length; i++) {891 var t = tagFor(ents[i]);892 if (t) list.push({ s: ents[i].offset, e: ents[i].offset + ents[i].length, o: t[0], c: t[1], n: i });893 }894 if (!list.length) return __wEsc(text);895 var cuts = {};896 cuts[0] = 1; cuts[text.length] = 1;897 list.forEach(function (x) { cuts[x.s] = 1; cuts[x.e] = 1; });898 var points = Object.keys(cuts).map(Number).filter(function (p) { return p >= 0 && p <= text.length; }).sort(function (a, b) { return a - b; });899 var out = "", prevActive = "";900 for (var pi = 0; pi < points.length - 1; pi++) {901 var a = points[pi], b = points[pi + 1];902 var active = list.filter(function (x) { return x.s <= a && x.e >= b; })903 .sort(function (x, y) { return (y.e - y.s) - (x.e - x.s) || x.n - y.n; });904 var sig = active.map(function (x) { return x.n; }).join(",");905 if (sig !== prevActive) {906 // close previous (reverse), open new907 var prevList = prevActive ? prevActive.split(",").map(function (n) { return list.filter(function (x) { return String(x.n) === n; })[0]; }) : [];908 for (var ci = prevList.length - 1; ci >= 0; ci--) out += prevList[ci].c;909 active.forEach(function (x) { out += x.o; });910 prevActive = sig;911 }912 out += __wEsc(text.substring(a, b));913 }914 if (prevActive) {915 var lastList = prevActive.split(",").map(function (n) { return list.filter(function (x) { return String(x.n) === n; })[0]; });916 for (var li = lastList.length - 1; li >= 0; li--) out += lastList[li].c;917 }918 return out;919 }920 921 var rawWelcome = (typeof message !== "undefined" && message) ? String(message) : msgText;922 if (rawWelcome.length > 850) {923 Bot.sendMessage("❌ Text bahut lamba hai (" + rawWelcome.length + " characters). 850 se kam rakhein.");924 return;925 }926 var wEnts = (request && (request.entities || (request.message && request.message.entities))) || [];927 var wHtml;928 try { wHtml = __wEntitiesToHtml(rawWelcome, wEnts); } catch (wErr) { wHtml = __wEsc(rawWelcome); }929 User.setProperty("edit_welcome_step", null, "string");930 Bot.setProperty("custom_welcome_html", wHtml, "string");931 Bot.sendMessage("✅ <b>Welcome text save ho gaya.</b> Neeche preview hai:", { parse_mode: "HTML" });932 Bot.run({ command: "/menu" });933 return;934 }935 936 var setHowLinkStep = User.getProperty("set_how_link_step");937 if (setHowLinkStep === "waiting_input" && msgText) {938 User.setProperty("set_how_link_step", null, "string");939 Bot.run({ command: "/set_how_link", options: { params: msgText.trim() } });940 return;941 }942 943 var setSupportLinkStep = User.getProperty("set_support_link_step");944 if (setSupportLinkStep === "waiting_input" && msgText) {945 User.setProperty("set_support_link_step", null, "string");946 Bot.run({ command: "/set_support_link", options: { params: msgText.trim() } });947 return;948 }949 950 var extkeyUrlStep = User.getProperty("extkey_url_step");951 if (extkeyUrlStep === "waiting_input" && msgText) {952 User.setProperty("extkey_url_step", null, "string");953 Bot.run({ command: "/extkey_save_url", options: { params: msgText.trim() } });954 return;955 }956 var extkeyApikeyStep = User.getProperty("extkey_apikey_step");957 if (extkeyApikeyStep === "waiting_input" && msgText) {958 User.setProperty("extkey_apikey_step", null, "string");959 Bot.run({ command: "/extkey_save_apikey", options: { params: msgText.trim() } });960 return;961 }962 var extkeyMasterStep = User.getProperty("extkey_master_step");963 if (extkeyMasterStep === "waiting_input" && msgText) {964 User.setProperty("extkey_master_step", null, "string");965 Bot.run({ command: "/extkey_save_master", options: { params: msgText.trim() } });966 return;967 }968 }969 970 // ==========================================971 // 🎟 MODULE 3: ADMIN COUPON GENERATOR (step-by-step wizard)972 // ==========================================973 if (userId === adminId && couponGenStep) {974 975 if (couponGenStep === "code") {976 if (!msgText) { Bot.sendMessage("⚠️ Kripya ek valid coupon code bhejein."); return; }977 var couponCodeUpper = msgText.trim().toUpperCase();978 if (Bot.getProperty("coupon_" + couponCodeUpper)) {979 Bot.sendMessage("❌ Ye coupon code pehle se exist karta hai! Doosra naam try karein.");980 return;981 }982 User.setProperty("coupon_gen_code", couponCodeUpper, "string");983 User.setProperty("coupon_gen_step", "maxclaims", "string");984 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" });985 return;986 }987 988 if (couponGenStep === "maxclaims") {989 var maxClaimsVal = parseInt(msgText.trim());990 if (isNaN(maxClaimsVal) || maxClaimsVal <= 0) { Bot.sendMessage("❌ Kripya ek valid number bhejein (jaise 50)."); return; }991 User.setProperty("coupon_gen_maxclaims", maxClaimsVal, "number");992 User.setProperty("coupon_gen_step", "type", "string");993 Bot.sendMessage(994 "<tg-emoji emoji-id='6093677128295914531'>🎟</tg-emoji> <b>Coupon ka type kya hoga?</b>\n\n" +995 "• Purchase par % chhut ke liye: <code>discount</code>\n" +996 "• Wallet me seedha balance dene ke liye: <code>balance</code>",997 { parse_mode: "HTML" }998 );999 return;1000 }1001 1002 if (couponGenStep === "type") {1003 var typeInput = (msgText || "").trim().toLowerCase();1004 if (typeInput === "discount") {1005 User.setProperty("coupon_gen_step", "discount", "string");1006 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" });1007 } else if (typeInput === "balance") {1008 User.setProperty("coupon_gen_step", "balanceamt", "string");1009 Bot.sendMessage("<tg-emoji emoji-id='6312263493051489212'>💰</tg-emoji> <b>Har user ko kitna balance (₹) milega?</b>\n<i>Sirf number bhejein, jaise: 10</i>", { parse_mode: "HTML" });1010 } else {1011 Bot.sendMessage("❌ Sirf <code>discount</code> ya <code>balance</code> likhein.", { parse_mode: "HTML" });1012 }1013 return;1014 }1015 1016 if (couponGenStep === "balanceamt") {1017 var balAmt = parseFloat((msgText || "").trim());1018 if (isNaN(balAmt) || balAmt <= 0) { Bot.sendMessage("❌ Kripya valid amount bhejein (jaise 10)."); return; }1019 balAmt = Number(balAmt.toFixed(2));1020 var balCoupon = {1021 code: User.getProperty("coupon_gen_code"),1022 maxClaims: User.getProperty("coupon_gen_maxclaims"),1023 type: "balance",1024 balanceAmount: balAmt,1025 scope: "balance",1026 claimedBy: [],1027 isPaused: false,1028 createdAt: new Date().toLocaleDateString()1029 };1030 Bot.setProperty("coupon_" + balCoupon.code, balCoupon, "json");1031 var balCouponList = Bot.getProperty("coupon_list") || [];1032 if (balCouponList.indexOf(balCoupon.code) === -1) {1033 balCouponList.push(balCoupon.code);1034 Bot.setProperty("coupon_list", balCouponList, "json");1035 }1036 User.setProperty("coupon_gen_step", null, "string");1037 User.setProperty("coupon_gen_code", null, "string");1038 User.setProperty("coupon_gen_maxclaims", null, "number");1039 User.setProperty("coupon_gen_discount", null, "number");1040 Bot.sendMessage(1041 "<blockquote>🎟 <b>BALANCE COUPON CREATED!</b></blockquote>\n\n" +1042 "🏷 <b>Code:</b> <code>" + balCoupon.code + "</code>\n" +1043 "👥 <b>Max Claims:</b> " + balCoupon.maxClaims + "\n" +1044 "💰 <b>Balance:</b> ₹" + balAmt.toFixed(2) + " per user",1045 { parse_mode: "HTML" }1046 );1047 return;1048 }1049 1050 if (couponGenStep === "discount") {1051 var discountVal = parseFloat(msgText.trim());1052 if (isNaN(discountVal) || discountVal <= 0 || discountVal > 100) { Bot.sendMessage("❌ Discount 1 se 100 ke beech honi chahiye."); return; }1053 User.setProperty("coupon_gen_discount", discountVal, "number");1054 User.setProperty("coupon_gen_step", "scope", "string");1055 Bot.sendMessage(1056 "<tg-emoji emoji-id='6093677128295914531'>🎯</tg-emoji> <b>Scope batayein:</b>\n\n" +1057 "• Sabhi products/plans ke liye: <code>global</code> likh kar bhejein\n" +1058 "• Sirf ek specific product+plan ke liye: <code>Product Name | Duration</code>\n" +1059 " <i>Example:</i> <code>Atomic Habits (Book) | 1d</code>",1060 { parse_mode: "HTML" }1061 );1062 return;1063 }1064 1065 if (couponGenStep === "scope") {1066 var scopeInput = msgText.trim();1067 var couponData = {1068 code: User.getProperty("coupon_gen_code"),1069 maxClaims: User.getProperty("coupon_gen_maxclaims"),1070 discountPercent: User.getProperty("coupon_gen_discount"),1071 claimedBy: [],1072 isPaused: false,1073 createdAt: new Date().toLocaleDateString()1074 };1075 1076 if (scopeInput.toLowerCase() === "global") {1077 couponData.scope = "global";1078 } else if (scopeInput.indexOf("|") > -1) {1079 var scopeParts = scopeInput.split("|");1080 couponData.scope = "specific";1081 couponData.productName = scopeParts[0].trim();1082 couponData.duration = scopeParts[1].trim();1083 } else {1084 Bot.sendMessage("❌ Galat format! 'global' likhein ya 'Product Name | Duration' format me bhejein.");1085 return;1086 }1087 1088 Bot.setProperty("coupon_" + couponData.code, couponData, "json");1089 1090 // ✅ NEW: master list me bhi add karo, taaki /coupons admin command sabko list kar sake1091 var couponList = Bot.getProperty("coupon_list") || [];1092 if (couponList.indexOf(couponData.code) === -1) {1093 couponList.push(couponData.code);1094 Bot.setProperty("coupon_list", couponList, "json");1095 }1096 1097 // Cleanup wizard state1098 User.setProperty("coupon_gen_step", null, "string");1099 User.setProperty("coupon_gen_code", null, "string");1100 User.setProperty("coupon_gen_maxclaims", null, "number");1101 User.setProperty("coupon_gen_discount", null, "number");1102 1103 Bot.sendMessage(1104 "<blockquote>🎟 <b>COUPON CREATED SUCCESSFULLY!</b></blockquote>\n\n" +1105 "🏷 <b>Code:</b> <code>" + couponData.code + "</code>\n" +1106 "👥 <b>Max Claims:</b> " + couponData.maxClaims + "\n" +1107 "💸 <b>Discount:</b> " + couponData.discountPercent + "%\n" +1108 "🎯 <b>Scope:</b> " + (couponData.scope === "global" ? "🌍 Global (All Plans)" : "📦 " + couponData.productName + " (" + couponData.duration + ")"),1109 { parse_mode: "HTML" }1110 );1111 return;1112 }1113 }1114 1115 // ==========================================1116 // 🎟 MODULE 4: USER — APPLY COUPON CODE TEXT ENTRY1117 // ==========================================1118 if (awaitingCouponFor) {1119 var enteredCode = msgText.trim().toUpperCase();1120 var couponRec = Bot.getProperty("coupon_" + enteredCode);1121 1122 User.setProperty("awaiting_coupon_for", null, "string");1123 1124 if (!couponRec) {1125 Bot.sendMessage("❌ <b>Invalid Coupon Code!</b>", { parse_mode: "HTML" });1126 return;1127 }1128 if (couponRec.isPaused) {1129 Bot.sendMessage("⏸ Ye coupon abhi paused hai, thodi der baad try karein.", { parse_mode: "HTML" });1130 return;1131 }1132 if (!Array.isArray(couponRec.claimedBy)) { couponRec.claimedBy = []; }1133 if (couponRec.claimedBy.indexOf(userId) > -1) {1134 Bot.sendMessage("⚠️ Aapne ye coupon already use kar liya hai!", { parse_mode: "HTML" });1135 return;1136 }1137 if (couponRec.claimedBy.length >= couponRec.maxClaims) {1138 Bot.sendMessage("❌ Is coupon ki claim limit khatam ho gayi hai!", { parse_mode: "HTML" });1139 return;1140 }1141 1142 // 💰 BALANCE COUPON: koi bhi jagah se redeem ho, wallet me turant credit + claim.1143 if (couponRec.type === "balance") {1144 var balCredit = Number(couponRec.balanceAmount || 0);1145 if (!(balCredit > 0)) {1146 Bot.sendMessage("❌ Ye coupon sahi se set nahi hai, admin se contact karein.", { parse_mode: "HTML" });1147 return;1148 }1149 couponRec.claimedBy.push(String(userId));1150 Bot.setProperty("coupon_" + enteredCode, couponRec, "json");1151 Libs.ResourcesLib.userRes("balance").add(balCredit);1152 var newBalAfterCoupon = 0;1153 try { newBalAfterCoupon = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (nbErr) {}1154 newBalAfterCoupon += Number(Bot.getProperty("balance" + userId) || 0);1155 Bot.sendMessage(1156 "<blockquote>🎉 <b>COUPON REDEEMED!</b></blockquote>\n\n" +1157 "💰 <b>Balance Added:</b> ₹" + balCredit.toFixed(2) + "\n" +1158 "💵 <b>New Balance:</b> ₹" + newBalAfterCoupon.toFixed(2),1159 { parse_mode: "HTML" }1160 );1161 var cpnOwner = String(Bot.getProperty("owner_id") || "7127818616");1162 if (String(userId) !== cpnOwner) {1163 try {1164 Api.sendMessage({ chat_id: cpnOwner, parse_mode: "HTML",1165 text: "🎟 <b>Balance coupon redeemed</b>\n👤 <code>" + userId + "</code>\n🏷 <code>" + enteredCode + "</code> → ₹" + balCredit.toFixed(2) });1166 } catch (adErr) {}1167 }1168 Bot.run({ command: "/profile" });1169 return;1170 }1171 1172 // 👤 Profile se aaya coupon: sirf account me save karo; claim purchase par hota hai.1173 if (awaitingCouponFor === "PROFILE") {1174 User.setProperty("profile_coupon", enteredCode, "string");1175 var scopeNote = couponRec.scope === "specific"1176 ? ("\n📦 <i>Sirf " + (couponRec.productName || "selected product") + " par valid.</i>")1177 : "\n🌍 <i>Sab plans par valid.</i>";1178 Bot.sendMessage("🎉 <b>Coupon Saved!</b> -" + couponRec.discountPercent + "% discount next purchase par lagega." + scopeNote, { parse_mode: "HTML" });1179 Bot.run({ command: "/profile" });1180 return;1181 }1182 1183 var couponTargetParts = awaitingCouponFor.split(" ");1184 var cTargetProdIdx = couponTargetParts[0];1185 var cTargetPlanIdx = couponTargetParts[1];1186 1187 if (couponRec.scope === "specific") {1188 var cProductList = Bot.getProperty("stored_products") || [];1189 var cProduct = cProductList[Number(cTargetProdIdx)];1190 var cPlan = cProduct ? cProduct.plans[Number(cTargetPlanIdx)] : null;1191 var cDurationDisplay = cPlan ? (cPlan.durationDisplay || (cPlan.days + " Days")) : "";1192 var matchesProduct = cProduct && cProduct.name.trim().toLowerCase() === couponRec.productName.trim().toLowerCase();1193 var matchesDuration = cDurationDisplay.toLowerCase().indexOf(String(couponRec.duration).toLowerCase().replace(/[^a-z0-9]/g, "")) > -1 ||1194 String(couponRec.duration).replace(/[^0-9]/g, "") === String(cPlan ? cPlan.days : "");1195 if (!matchesProduct) {1196 Bot.sendMessage("❌ Ye coupon is product ke liye valid nahi hai!", { parse_mode: "HTML" });1197 return;1198 }1199 }1200 1201 // ✅ Valid — apply and mark claimed1202 couponRec.claimedBy.push(userId);1203 Bot.setProperty("coupon_" + enteredCode, couponRec, "json");1204 User.setProperty("applied_coupon_" + cTargetProdIdx + "_" + cTargetPlanIdx, enteredCode, "string");1205 1206 Bot.sendMessage("🎉 <b>Coupon Applied!</b> -" + couponRec.discountPercent + "% discount added.", { parse_mode: "HTML" });1207 1208 Bot.run({1209 command: "buyitem",1210 options: { params: cTargetProdIdx + " " + cTargetPlanIdx }1211 });1212 return;1213 }1214 1215 // ==========================================1216 // 📢 MODULE 2: PREMIUM BROADCAST SYSTEM1217 // ==========================================1218 if (userId === adminId && isAwaitingBroadcast) {1219 User.setProperty("awaiting_broadcast_data", false, "boolean");1220 var userList = Bot.getProperty("all_users_list") || [];1221 1222 if (userList.length === 0) {1223 Bot.sendMessage("❌ Bot mein abhi tak koi bhi user registered nahi hai.");1224 return;1225 }1226 1227 var targetMessageId = null;1228 if (request) {1229 if (request.message_id) { targetMessageId = request.message_id; }1230 else if (request.message && request.message.message_id) { targetMessageId = request.message.message_id; }1231 }1232 1233 if (!targetMessageId) {1234 Bot.sendMessage("❌ Unable to fetch message ID for broadcast.");1235 return;1236 }1237 1238 Bot.sendMessage("⏳ Sending premium broadcast to " + userList.length + " users... Please wait.");1239 1240 // ✅ FIXED: pehle ek bhi blocked/invalid user Api.copyMessage() ko throw karwa deta1241 // tha, jo bahar wale catch() tak chala jaata tha — isse loop beech me hi ruk jaata1242 // tha (baaki users ko broadcast nahi jaata tha) aur admin ko scary "Error in handling"1243 // dikhta tha, jabki zyada tar users ko message mil chuka hota tha. Ab har send apne1244 // try/catch me hai, aur end me accurate success/fail count milega.1245 var sentCount = 0;1246 var failedCount = 0;1247 for (var i = 0; i < userList.length; i++) {1248 try {1249 Api.copyMessage({1250 chat_id: String(userList[i]),1251 from_chat_id: adminId,1252 message_id: Number(targetMessageId)1253 });1254 sentCount++;1255 } catch (perUserErr) {1256 failedCount++;1257 }1258 }1259 Bot.sendMessage(1260 "✅ <b>Broadcast Complete!</b>\n" +1261 "📤 <b>Sent:</b> " + sentCount + " users\n" +1262 (failedCount > 0 ? "⚠️ <b>Failed/Blocked:</b> " + failedCount + " users" : "🎉 <b>No failures!</b>"),1263 { parse_mode: "HTML" }1264 );1265 }1266 1267} catch (err) {1268 Bot.sendMessage("Error in handling: " + err.message);1269}