devbro468/Dev_x_store_botPublic · Bot Template
AIThis bot operates a digital storefront (DEV X STORE) selling subscription-based products — likely game hacks, accounts, or access keys — categorized by platform (Android Root, Non-Root, iPhone). It features a reseller program with discounted pricing, a dual-currency wallet (INR balance + Telegram Stars/XTR), and a full admin/co-admin panel for managing products, plans, per-plan pricing, stock (keys/accounts), coupons, and API endpoints. Purchases flow through a plan selection screen offering wallet payment, Stars invoices (sendInvoice with XTR currency), and coupon application. Successful Stars payments are handled via successful_payment webhook, crediting wallet or delivering keys directly. Admin tools include user listing with chunked messaging, stock viewing/deletion with inline keyboards, co-admin management, and API registry updates. The bot registers users on first interaction and
commands/_start.js
javascript · 676 lines
1/**#command2name: /start3answer: 4keyboard: 5parse_mode: markdown6aliases: /START,/Start,/STArt,/stARt7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12try { 13 var adminId = Bot.getProperty("owner_id") || "8875810358";14 var userId = String(user.telegramid);15 16 // ⭐ TELEGRAM STARS — fallback event detection (payment events may route here17 // generically depending on the platform, so we check and delegate explicitly)18 if (request && request.pre_checkout_query) {19 Bot.run({ command: "/onPreCheckoutQuery" });20 return;21 }22 if (request && request.message && request.message.successful_payment) {23 Bot.run({ command: "/onSuccessfulPayment" });24 return;25 }26 27 // Safe variable fallbacks for BJS environment28 var msgText = (typeof message !== 'undefined' && message) ? message.trim() : "";29 // ✅ FIXED: pehle "data" naam ka ek undefined global variable padha ja raha tha, jo hamesha30 // empty rehta tha — isliye koi bhi callback button jo "/start" call karta tha (jaise "Back to31 // Menu"), silently fail ho jaata tha aur user ko koi response hi nahi milta tha.32 var callbackData = (request && request.callback_query && request.callback_query.data) ? request.callback_query.data : "";33 34 // =====================================================35 // 🛠 MAINTENANCE MODE GATE (✅ NEW)36 // Owner/Co-Admins hamesha through jaate hain; baaki sabko premium screen dikhta hai.37 // =====================================================38 var isMaintenanceOn = Bot.getProperty("maintenance_mode") || false;39 var isOwnerOrCoAdmin = (userId === adminId) || Bot.getProperty("co_admin_" + userId);40 41 if (isMaintenanceOn && !isOwnerOrCoAdmin) {42 Bot.sendMessage(43 "<blockquote><tg-emoji emoji-id='6100657257605763582'>🛠</tg-emoji> <b>BOT UNDER MAINTENANCE</b></blockquote>\n\n" +44 "<i>Hum kuch premium improvements kar rahe hain! Kripya thodi der baad wapas try karein.</i>\n\n" +45 "<tg-emoji emoji-id='6100170496077204999'>👑</tg-emoji> <i>Dhanyawad for your patience!</i>",46 { parse_mode: "HTML" }47 );48 return;49 }50 51 // ✅ NEW: Maintenance abhi-abhi hata hai — is user ko ek baar premium "We're Back!" welcome do52 var maintenanceRemovedAt = Bot.getProperty("maintenance_removed_at");53 var userSeenMaintenanceRemoved = User.getProperty("seen_maintenance_removed_at");54 if (!isMaintenanceOn && maintenanceRemovedAt && userSeenMaintenanceRemoved !== maintenanceRemovedAt) {55 User.setProperty("seen_maintenance_removed_at", maintenanceRemovedAt, "number");56 Api.sendMessage({57 chat_id: chat.chatid,58 text: "<blockquote><tg-emoji emoji-id='6102856637343600044'>✅</tg-emoji> <b>MAINTENANCE REMOVED — WE'RE BACK!</b></blockquote>\n\n" +59 "<tg-emoji emoji-id='6091571559233755994'>🚀</tg-emoji> <i>Bot fully automated system ke saath phir se live hai!</i>\n" +60 "<i>Tap /start to continue, or Buy Now to grab your keys instantly.</i>",61 parse_mode: "HTML",62 reply_markup: JSON.stringify({63 inline_keyboard: [[64 { text: "Buy Now", callback_data: "/buy_hack", style: "success", icon_custom_emoji_id: "6312263493051489212" }65 ]]66 })67 });68 }69 70 var currentStep = User.getProperty("add_product_step");71 var isAwaitingBroadcast = User.getProperty("awaiting_broadcast_data");72 73 // 🎨 PREMIUM CUSTOM EMOJIS DEFINITION (Fixed with escaped double quotes)74 var EMJ_VERIFIED_CHECK = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";75 var EMJ_CROWN = "<tg-emoji emoji-id=\"6311975081702597046\">👑</tg-emoji>";76 var EMJ_DROP = "<tg-emoji emoji-id=\"6080228009439141516\">💧</tg-emoji>";77 var EMJ_CHECK = "<tg-emoji emoji-id=\"6080214566191505147\">✅</tg-emoji>";78 var EMJ_ROCKET = "<tg-emoji emoji-id=\"6091571559233755994\">🚀</tg-emoji>";79 var EMJ_RADAR = "<tg-emoji emoji-id=\"6093591495237967001\">📡</tg-emoji>";80 var EMJ_STAR = "<tg-emoji emoji-id=\"6093677128295914531\">✨</tg-emoji>";81 var EMJ_RED_DOT = "<tg-emoji emoji-id=\"6093854128193152827\">🔴</tg-emoji>";82 83 // Access Granted ke liye aapka requested special premium custom emoji84 var EMJ_NEW_ACCESS = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";85 86 // ==========================================87 // 🏠 HELPER: DIRECTLY SEND MAIN SHOP MENU88 // (Bot.runCommand("/menu") is unreliable in BJS -> inline it instead)89 // ==========================================90 function sendMainMenu() {91 try {92 // ✅ FIXED: ab same wallet store se read hoga jo purchase flows use karte hain93 // (Libs.ResourcesLib "balance" resource + admin bonus balance), taaki balance sab jagah same dikhe.94 var userBal = (function() {95 var resBal = 0;96 try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}97 var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);98 return (resBal + bonusBal).toFixed(2);99 })();100 101 var EMJ_HEADER_ROCKET = "<tg-emoji emoji-id='5217822164362739968'>🚀</tg-emoji>";102 var EMJ_HEADER_NEW = "<tg-emoji emoji-id='6082603117763894396'>✨</tg-emoji>";103 var EMJ_HEADER_SHIELD = "<tg-emoji emoji-id='6113743082358841933'>🔰</tg-emoji>";104 105 var MSG_EMJ_STORE = "<tg-emoji emoji-id='5866053971960929280'>🛒</tg-emoji>";106 var MSG_EMJ_FFID = "<tg-emoji emoji-id='5334890573281114250'>🎮</tg-emoji>";107 var MSG_EMJ_PROFILE = "<tg-emoji emoji-id='5260399854500191689'>🔰</tg-emoji>";108 var MSG_EMJ_ADDBAL = "<tg-emoji emoji-id='6147815702163102310'>✨</tg-emoji>";109 var MSG_EMJ_HISTORY = "<tg-emoji emoji-id='6113743082358841933'>🔰</tg-emoji>";110 var MSG_EMJ_LUDO = "<tg-emoji emoji-id='5371043439020353782'>🎲</tg-emoji>";111 var MSG_EMJ_TUTORIAL = "<tg-emoji emoji-id='5258077307985207053'>📹</tg-emoji>";112 var MSG_EMJ_PROOF = "<tg-emoji emoji-id='5330237710655306682'>✅</tg-emoji>";113 var MSG_EMJ_SUPPORT = "<tg-emoji emoji-id='5436113877181941026'>🔰</tg-emoji>";114 115 var EMJ_PREMIUM_MENU = "<tg-emoji emoji-id='5406745015365943482'>✨</tg-emoji>";116 var EMJ_YOUR_BALANCE = "<tg-emoji emoji-id='5231200819986047254'>💰</tg-emoji>";117 var EMJ_GET_STARTED = "<tg-emoji emoji-id='6057415823222379852'>👇</tg-emoji>";118 119 var welcomeMessage =120 "<tg-emoji emoji-id=\"6266967801580231067\">💎</tg-emoji> <tg-emoji emoji-id=\"5866053971960929280\">🏪</tg-emoji> <b>— DEV MODZ STORE —</b> <tg-emoji emoji-id=\"5866053971960929280\">🏪</tg-emoji> <tg-emoji emoji-id=\"6266967801580231067\">💎</tg-emoji>\n\n" +121 "<tg-emoji emoji-id=\"6102856637343600044\">🎉</tg-emoji> <b>Hello, " + ((user && user.first_name) ? user.first_name.toUpperCase() : "RESELLER") + "!</b>\n\n" +122 "<tg-emoji emoji-id=\"6080228009439141516\">💧</tg-emoji> <b>Genuine, limited-stock books. Instant delivery.</b>\n\n" +123 "<tg-emoji emoji-id=\"6147767796097884213\">📦</tg-emoji> Wide product catalog\n" +124 "<tg-emoji emoji-id=\"6215386799133433653\">🔒</tg-emoji> Instant delivery on payment\n" +125 "<tg-emoji emoji-id=\"6267068789146260253\">💰</tg-emoji> Multiple payment gateways\n" +126 "<tg-emoji emoji-id=\"6100170496077204999\">👑</tg-emoji> 24/7 admin support\n\n" +127 "<i>" + EMJ_YOUR_BALANCE + " Balance: ₹" + userBal + "</i>\n\n" +128 "<i>Tap any button below to begin:</i> " + EMJ_GET_STARTED;129 130 var multiColorKeyboard = [131 [{ text: "Shop Now", callback_data: "/buy_hack", style: "primary", icon_custom_emoji_id: "5866053971960929280" }],132 [133 { text: "Profile", callback_data: "/profile", style: "primary", icon_custom_emoji_id: "6145572393499762737" },134 { text: "Add Balance", callback_data: "/addfund", style: "success", icon_custom_emoji_id: "5409048419211682843" }135 ],136 [137 { text: "My Keys", callback_data: "/mykey", style: "primary", icon_custom_emoji_id: "6215386799133433653" },138 { text: "How to use", callback_data: "/how", style: "danger", icon_custom_emoji_id: "6192842983948162969" }139 ],140 [141 { text: "Support", callback_data: "/support", style: "danger", icon_custom_emoji_id: "6267129592998270736" }142 ],143 [{ text: "Payment Proofs", url: (Bot.getProperty("payment_proof_link") || "https://t.me/DevModz_Proof"), style: "success", icon_custom_emoji_id: "5330237710655306682" }]144 ];145 146 if (Bot.getProperty("reseller_system_enabled") && !Bot.getProperty("is_reseller_" + userId)) {147 multiColorKeyboard.push([148 { text: "Reseller Upgrade", callback_data: "/reseller_upgrade", style: "success", icon_custom_emoji_id: "6102856637343600044" }149 ]);150 }151 152 Api.sendMessage({153 chat_id: chat.chatid,154 text: welcomeMessage,155 parse_mode: "HTML",156 reply_markup: JSON.stringify({ inline_keyboard: multiColorKeyboard })157 });158 } catch (menuErr) {159 Bot.sendMessage("🛑 <b>Menu Send Error:</b> <code>" + menuErr.message + "</code>", { parse_mode: "HTML" });160 }161 }162 163 // [Auto-Track User] List me user track karne ke liye164 var trackedUsers = Bot.getProperty("all_users_list") || [];165 if (!trackedUsers.includes(userId)) {166 trackedUsers.push(userId);167 Bot.setProperty("all_users_list", trackedUsers, "json");168 }169 170 // 🛡️ [ANTI-DUPLICATE CHECK] Agar user already verified hai toh seedhe menu par bhejein171 // ✅ FIXED: pehle sirf exact "msgText === '/start'" ya "callbackData === '/trigger_contact_popup'"172 // match hone par hi menu bhejta tha. Kisi bhi button jo callback_data "/start" call karta tha173 // (jaise cancel-order ke baad "Back to Menu"), us case me match fail ho jaata tha aur user ko174 // koi response nahi milta tha. Ab ye check robust hai — jab tak ye genuinely ek contact-share175 // event nahi hai ya admin ek mid-flow step me nahi hai, verified user ko hamesha menu milega.176 var couponGenStep = User.getProperty("coupon_gen_step");177 var awaitingCouponFor = User.getProperty("awaiting_coupon_for");178 var isAlreadyVerified = Bot.getProperty("verified_" + userId);179 var isContactShareEvent = !!(request && request.contact && request.contact.user_id);180 var isAdminMidFlow = (userId === adminId && (currentStep || isAwaitingBroadcast || couponGenStep ||181 User.getProperty("addbal_step") || User.getProperty("addbalall_step") || User.getProperty("rembal_step") || User.getProperty("checkbal_step") ||182 User.getProperty("set_payment_upi_step") ||183 User.getProperty("set_how_link_step") || User.getProperty("set_proof_link_step") || User.getProperty("set_support_link_step")));184 var isUserMidFlow = !!awaitingCouponFor;185 186 // ✅ NEW: User ne jo bhi "/start"/"/START"/"/Start" type kiya, menu aane ke187 // baad us typed command-message ko vanish (delete) kar do — chat clean rahe.188 if (msgText.toLowerCase() === "/start" && request && request.message_id) {189 try { Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (delStartErr) {}190 }191 192 if (isAlreadyVerified && !isContactShareEvent && !isAdminMidFlow && !isUserMidFlow) {193 sendMainMenu();194 return;195 }196 197 // ==========================================198 // ⚡ MODULE: LIVE CONTACT RECEIVER & VERIFIER199 // ==========================================200 if (request && request.contact && request.contact.user_id) {201 if (String(request.contact.user_id) === userId) {202 203 var phoneNumber = request.contact.phone_number;204 var fullName = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";205 var username = user.username ? "@" + user.username : "No Username";206 207 // Permanently mark user as verified globally208 Bot.setProperty("verified_" + userId, true, "boolean");209 Bot.setProperty("phone_" + userId, phoneNumber, "string");210 // ✅ NEW: Joined date save karo (Profile section me dikhane ke liye)211 if (!Bot.getProperty("joined_date_" + userId)) {212 Bot.setProperty("joined_date_" + userId, new Date().toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" }), "string");213 }214 215 // 1. USER DETAILS TO ADMIN216 var adminNotification = 217 "<blockquote><b>" + EMJ_CROWN + " NEW USER VERIFIED " + EMJ_VERIFIED_CHECK + "</b></blockquote>\n" +218 "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +219 "<b>👤 Name:</b> " + fullName + "\n" +220 "<b>🆔 User ID:</b> <code>" + userId + "</code>\n" +221 "<b>🌐 Username:</b> " + username + "\n" +222 "<b>📞 Number:</b> <code>" + phoneNumber + "</code>\n" +223 "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>";224 225 Api.sendMessage({226 chat_id: adminId,227 text: adminNotification,228 parse_mode: "HTML"229 });230 231 // 2. USER SUCCESS MESSAGE (With your exact requested custom emojis)232 var successMessage = 233 "<blockquote><b>" + EMJ_NEW_ACCESS + " ACCESS GRANTED " + EMJ_NEW_ACCESS + "</b></blockquote>\n" +234 "<b>" + EMJ_VERIFIED_CHECK + " Verification Successful!</b>\n" +235 "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +236 "<b>Welcome to DEV MODZ STORE PANEL </b>\n" +237 "<b>Your profile is now securely fully verified.</b>\n\n" +238 "<b>" + EMJ_ROCKET + " Store Loaded Successfully Use Now! " + EMJ_CROWN + "</b>";239 240 Api.sendMessage({241 chat_id: chat.chatid,242 text: successMessage,243 parse_mode: "HTML",244 reply_markup: JSON.stringify({ remove_keyboard: true }) 245 });246 247 // ✅ FIX: Direct inline menu instead of unreliable Bot.runCommand("/menu")248 sendMainMenu();249 return; 250 } else {251 Bot.sendMessage("❌ <b>Verification Failed!</b> Please share your own contact number only.", { parse_mode: "HTML" });252 return;253 }254 }255 256 // ==========================================257 // 📱 MODULE 0: VERIFICATION CALLBACK HANDLER258 // ==========================================259 if (msgText.toLowerCase() === "/start" || callbackData === "/trigger_contact_popup") {260 261 var verifyMessage = 262 "<blockquote><b>" + EMJ_ROCKET + " DEV MODZ STORE " + EMJ_RADAR + "</b></blockquote>\n" +263 "<b>" + EMJ_STAR + " Welcome, " + (user.first_name || "User") + " " + EMJ_DROP + "</b>\n" +264 "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +265 "<b>" + EMJ_RED_DOT + " VERIFICATION REQUIRED " + EMJ_CHECK + "</b>\n" +266 "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +267 "<b>" + EMJ_RADAR + " To start shopping, please verify your phone number.</b>\n\n" +268 "<b>" + EMJ_ROCKET + " Why we need this:</b>\n" +269 "<b> • Secure your purchases " + EMJ_CHECK + "</b>\n" +270 "<b> • Deliver your books to you " + EMJ_DROP + "</b>\n" +271 "<b> • Protect your account " + EMJ_STAR + "</b>\n\n" +272 "<b>" + EMJ_RED_DOT + " Tap the blue button below to verify your account:</b>";273 274 // Standard native reply keyboard because contact sharing works securely here275 var nativeKeyboard = {276 keyboard: [277 [{ text: "✅ Verify Account", request_contact: true }]278 ],279 resize_keyboard: true,280 one_time_keyboard: true281 };282 283 Api.sendMessage({284 chat_id: chat.chatid,285 text: verifyMessage,286 parse_mode: "HTML",287 reply_markup: JSON.stringify(nativeKeyboard)288 });289 return; 290 }291 292 // ==========================================293 // 📦 MODULE 1: STEP-BY-STEP PRODUCT CREATION (UPDATED FOR WEBSITE API ID)294 // ==========================================295 if (userId === adminId && currentStep) {296 if (currentStep === "waiting_for_name") {297 if (!msgText) {298 Bot.sendMessage("⚠️ Invalid name. Please type a valid Product Name:");299 return;300 }301 User.setProperty("temp_product_name", msgText, "string");302 User.setProperty("add_product_step", "waiting_for_emoji", "string");303 Bot.sendMessage("💎 Great! Now send the <b>Premium Emoji ID</b> for this product:", { parse_mode: "HTML" });304 return; 305 }306 307 if (currentStep === "waiting_for_emoji") {308 if (!msgText) {309 Bot.sendMessage("⚠️ Invalid Emoji ID. Please send a valid Telegram Premium Emoji ID:");310 return;311 }312 User.setProperty("temp_product_emoji", msgText, "string");313 User.setProperty("add_product_step", "waiting_for_pid", "string");314 Bot.sendMessage("🔑 Nice! Now please enter the <b>Website API Product ID (PID)</b> for this item:", { parse_mode: "HTML" });315 return;316 }317 318 if (currentStep === "waiting_for_pid") {319 if (!msgText) {320 Bot.sendMessage("⚠️ Invalid Product ID. Please type a valid Website PID:");321 return;322 }323 324 var savedName = User.getProperty("temp_product_name");325 var savedEmoji = User.getProperty("temp_product_emoji");326 var savedPid = msgText; // User ne jo PID abhi bheja327 328 var productList = Bot.getProperty("stored_products") || [];329 if (!Array.isArray(productList)) { productList = []; }330 331 // Saving Name, Emoji and Website API ID (id) inside database object332 productList.push({ 333 name: savedName, 334 emoji: savedEmoji, 335 id: savedPid, 336 plans: [] 337 });338 339 Bot.setProperty("stored_products", productList, "json");340 341 // Cleanup temporary states342 User.setProperty("add_product_step", null, "string");343 User.setProperty("temp_product_name", null, "string");344 User.setProperty("temp_product_emoji", null, "string");345 346 var successMsg = "✅ <b>Product Added Successfully!</b>\n\n" +347 "📦 <b>Name:</b> " + savedName + "\n" +348 "💎 <b>Emoji ID:</b> <code>" + savedEmoji + "</code>\n" +349 "🔑 <b>API Product ID (PID):</b> <code>" + savedPid + "</code>\n\n" +350 "<i>Aap is product ke andar plans baad me configure kar sakte hain. Automatically website se integration ho gaya hai!</i>";351 352 Bot.sendMessage(successMsg, { parse_mode: "HTML" });353 return; 354 }355 }356 357 // ==========================================358 // 💵 MODULE 5: ADMIN BALANCE TOOLS (Add Bal / Remove Bal / Check Bal359 // button-click continuation — fixes buttons that previously just360 // showed a "Wrong Format" error with no way to actually complete it)361 // ==========================================362 if (userId === adminId) {363 var addbalStep = User.getProperty("addbal_step");364 var addbalAllStep = User.getProperty("addbalall_step");365 var rembalStep = User.getProperty("rembal_step");366 var checkbalStep = User.getProperty("checkbal_step");367 368 if (addbalStep === "waiting_input" && msgText) {369 User.setProperty("addbal_step", null, "string");370 371 // ✅ FIXED: pehle sirf Bot.run(...) se /addbal ko dobara call kiya jaata tha —372 // agar us re-run me "message" text sahi se forward nahi hota tha (jo wildcard373 // "*" -> /start delegation ke through hone par silently fail ho sakta tha),374 // toh balance kabhi credit hi nahi hota tha aur admin ko koi error bhi nahi375 // dikhta tha. Ab balance yahin, isi jagah, seedha add hota hai — kisi doosre376 // command re-run par depend nahi karta. Bot.run wala call sirf backup ke377 // taur par neeche rakha hai.378 var addbalData = msgText.trim();379 380 if (addbalData.indexOf("|") === -1) {381 Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });382 return;383 }384 385 var addbalParts = addbalData.split("|");386 var addbalTargetId = addbalParts[0].trim();387 var addbalAmount = parseFloat(addbalParts[1].trim());388 389 if (!addbalTargetId || isNaN(addbalAmount) || addbalAmount <= 0) {390 Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });391 return;392 }393 394 try {395 // Primary wallet resource (same store the rest of the bot reads for purchases)396 try {397 Libs.ResourcesLib.anotherUserRes("balance", addbalTargetId).add(addbalAmount);398 } catch (resErr) {}399 400 // ✅ Bonus-balance property — this is the SAME property /menu reads and adds401 // on top of the resource balance. Writing it here too guarantees the credited402 // amount always shows up for the user even if the resource write above fails403 // silently for a user who never triggered it before.404 var prevBonus = Number(Bot.getProperty("balance" + addbalTargetId) || 0);405 Bot.setProperty("balance" + addbalTargetId, (prevBonus + addbalAmount).toFixed(2), "string");406 407 Bot.sendMessage("✅ Success! Added " + addbalAmount + " to user " + addbalTargetId, { parse_mode: "HTML" });408 409 try {410 Api.sendMessage({411 chat_id: addbalTargetId,412 text: "<blockquote>" +413 "<tg-emoji emoji-id='6192822213486321961'>🗣</tg-emoji> Admin Added: " + addbalAmount + "\n" +414 "<tg-emoji emoji-id='6266967801580231067'>💎</tg-emoji> Balance Credited!\n" +415 "<tg-emoji emoji-id='6267068789146260253'>💰</tg-emoji> Wallet Updated\n" +416 "<tg-emoji emoji-id='5866053971960929280'>🛒</tg-emoji> /start TO SHOP NOW" +417 "</blockquote>",418 parse_mode: "HTML"419 });420 } catch (notifyErr) {}421 } catch (addbalErr) {422 Bot.sendMessage("⚠️ *Error:* " + addbalErr.message, { parse_mode: "Markdown" });423 }424 return;425 }426 if (addbalAllStep === "waiting_input" && msgText) {427 User.setProperty("addbalall_step", null, "string");428 Bot.run({ command: "/addbal_all", options: { message: "/addbal_all " + msgText.trim() } });429 return;430 }431 if (rembalStep === "waiting_input" && msgText) {432 User.setProperty("rembal_step", null, "string");433 Bot.run({ command: "/rembal", options: { message: "/rembal " + msgText.trim() } });434 return;435 }436 if (checkbalStep === "waiting_input" && msgText) {437 User.setProperty("checkbal_step", null, "string");438 Bot.run({ command: "/checkbal", options: { params: msgText.trim() } });439 return;440 }441 442 var setPaymentUpiStep = User.getProperty("set_payment_upi_step");443 if (setPaymentUpiStep === "waiting_input" && msgText) {444 User.setProperty("set_payment_upi_step", null, "string");445 Bot.run({ command: "/set_payment_upi", options: { params: msgText.trim() } });446 return;447 }448 449 var setHowLinkStep = User.getProperty("set_how_link_step");450 if (setHowLinkStep === "waiting_input" && msgText) {451 User.setProperty("set_how_link_step", null, "string");452 Bot.run({ command: "/set_how_link", options: { params: msgText.trim() } });453 return;454 }455 456 var setProofLinkStep = User.getProperty("set_proof_link_step");457 if (setProofLinkStep === "waiting_input" && msgText) {458 User.setProperty("set_proof_link_step", null, "string");459 Bot.run({ command: "/set_proof_link", options: { params: msgText.trim() } });460 return;461 }462 463 var setSupportLinkStep = User.getProperty("set_support_link_step");464 if (setSupportLinkStep === "waiting_input" && msgText) {465 User.setProperty("set_support_link_step", null, "string");466 Bot.run({ command: "/set_support_link", options: { params: msgText.trim() } });467 return;468 }469 }470 471 // ==========================================472 // 🎟 MODULE 3: ADMIN COUPON GENERATOR (step-by-step wizard)473 // ==========================================474 if (userId === adminId && couponGenStep) {475 476 if (couponGenStep === "code") {477 if (!msgText) { Bot.sendMessage("⚠️ Kripya ek valid coupon code bhejein."); return; }478 var couponCodeUpper = msgText.trim().toUpperCase();479 if (Bot.getProperty("coupon_" + couponCodeUpper)) {480 Bot.sendMessage("❌ Ye coupon code pehle se exist karta hai! Doosra naam try karein.");481 return;482 }483 User.setProperty("coupon_gen_code", couponCodeUpper, "string");484 User.setProperty("coupon_gen_step", "maxclaims", "string");485 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" });486 return;487 }488 489 if (couponGenStep === "maxclaims") {490 var maxClaimsVal = parseInt(msgText.trim());491 if (isNaN(maxClaimsVal) || maxClaimsVal <= 0) { Bot.sendMessage("❌ Kripya ek valid number bhejein (jaise 50)."); return; }492 User.setProperty("coupon_gen_maxclaims", maxClaimsVal, "number");493 User.setProperty("coupon_gen_step", "discount", "string");494 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" });495 return;496 }497 498 if (couponGenStep === "discount") {499 var discountVal = parseFloat(msgText.trim());500 if (isNaN(discountVal) || discountVal <= 0 || discountVal > 100) { Bot.sendMessage("❌ Discount 1 se 100 ke beech honi chahiye."); return; }501 User.setProperty("coupon_gen_discount", discountVal, "number");502 User.setProperty("coupon_gen_step", "scope", "string");503 Bot.sendMessage(504 "<tg-emoji emoji-id='6093677128295914531'>🎯</tg-emoji> <b>Scope batayein:</b>\n\n" +505 "• Sabhi products/plans ke liye: <code>global</code> likh kar bhejein\n" +506 "• Sirf ek specific product+plan ke liye: <code>Product Name | Duration</code>\n" +507 " <i>Example:</i> <code>Atomic Habits (Book) | 1d</code>",508 { parse_mode: "HTML" }509 );510 return;511 }512 513 if (couponGenStep === "scope") {514 var scopeInput = msgText.trim();515 var couponData = {516 code: User.getProperty("coupon_gen_code"),517 maxClaims: User.getProperty("coupon_gen_maxclaims"),518 discountPercent: User.getProperty("coupon_gen_discount"),519 claimedBy: [],520 isPaused: false,521 createdAt: new Date().toLocaleDateString()522 };523 524 if (scopeInput.toLowerCase() === "global") {525 couponData.scope = "global";526 } else if (scopeInput.indexOf("|") > -1) {527 var scopeParts = scopeInput.split("|");528 couponData.scope = "specific";529 couponData.productName = scopeParts[0].trim();530 couponData.duration = scopeParts[1].trim();531 } else {532 Bot.sendMessage("❌ Galat format! 'global' likhein ya 'Product Name | Duration' format me bhejein.");533 return;534 }535 536 Bot.setProperty("coupon_" + couponData.code, couponData, "json");537 538 // ✅ NEW: master list me bhi add karo, taaki /coupons admin command sabko list kar sake539 var couponList = Bot.getProperty("coupon_list") || [];540 if (couponList.indexOf(couponData.code) === -1) {541 couponList.push(couponData.code);542 Bot.setProperty("coupon_list", couponList, "json");543 }544 545 // Cleanup wizard state546 User.setProperty("coupon_gen_step", null, "string");547 User.setProperty("coupon_gen_code", null, "string");548 User.setProperty("coupon_gen_maxclaims", null, "number");549 User.setProperty("coupon_gen_discount", null, "number");550 551 Bot.sendMessage(552 "<blockquote>🎟 <b>COUPON CREATED SUCCESSFULLY!</b></blockquote>\n\n" +553 "🏷 <b>Code:</b> <code>" + couponData.code + "</code>\n" +554 "👥 <b>Max Claims:</b> " + couponData.maxClaims + "\n" +555 "💸 <b>Discount:</b> " + couponData.discountPercent + "%\n" +556 "🎯 <b>Scope:</b> " + (couponData.scope === "global" ? "🌍 Global (All Plans)" : "📦 " + couponData.productName + " (" + couponData.duration + ")"),557 { parse_mode: "HTML" }558 );559 return;560 }561 }562 563 // ==========================================564 // 🎟 MODULE 4: USER — APPLY COUPON CODE TEXT ENTRY565 // ==========================================566 if (awaitingCouponFor) {567 var enteredCode = msgText.trim().toUpperCase();568 var couponRec = Bot.getProperty("coupon_" + enteredCode);569 570 User.setProperty("awaiting_coupon_for", null, "string");571 572 if (!couponRec) {573 Bot.sendMessage("❌ <b>Invalid Coupon Code!</b>", { parse_mode: "HTML" });574 return;575 }576 if (couponRec.isPaused) {577 Bot.sendMessage("⏸ Ye coupon abhi paused hai, thodi der baad try karein.", { parse_mode: "HTML" });578 return;579 }580 if (!Array.isArray(couponRec.claimedBy)) { couponRec.claimedBy = []; }581 if (couponRec.claimedBy.indexOf(userId) > -1) {582 Bot.sendMessage("⚠️ Aapne ye coupon already use kar liya hai!", { parse_mode: "HTML" });583 return;584 }585 if (couponRec.claimedBy.length >= couponRec.maxClaims) {586 Bot.sendMessage("❌ Is coupon ki claim limit khatam ho gayi hai!", { parse_mode: "HTML" });587 return;588 }589 590 var couponTargetParts = awaitingCouponFor.split(" ");591 var cTargetProdIdx = couponTargetParts[0];592 var cTargetPlanIdx = couponTargetParts[1];593 594 if (couponRec.scope === "specific") {595 var cProductList = Bot.getProperty("stored_products") || [];596 var cProduct = cProductList[Number(cTargetProdIdx)];597 var cPlan = cProduct ? cProduct.plans[Number(cTargetPlanIdx)] : null;598 var cDurationDisplay = cPlan ? (cPlan.durationDisplay || (cPlan.days + " Days")) : "";599 var matchesProduct = cProduct && cProduct.name.trim().toLowerCase() === couponRec.productName.trim().toLowerCase();600 var matchesDuration = cDurationDisplay.toLowerCase().indexOf(String(couponRec.duration).toLowerCase().replace(/[^a-z0-9]/g, "")) > -1 ||601 String(couponRec.duration).replace(/[^0-9]/g, "") === String(cPlan ? cPlan.days : "");602 if (!matchesProduct) {603 Bot.sendMessage("❌ Ye coupon is product ke liye valid nahi hai!", { parse_mode: "HTML" });604 return;605 }606 }607 608 // ✅ Valid — apply and mark claimed609 couponRec.claimedBy.push(userId);610 Bot.setProperty("coupon_" + enteredCode, couponRec, "json");611 User.setProperty("applied_coupon_" + cTargetProdIdx + "_" + cTargetPlanIdx, enteredCode, "string");612 613 Bot.sendMessage("🎉 <b>Coupon Applied!</b> -" + couponRec.discountPercent + "% discount added.", { parse_mode: "HTML" });614 615 Bot.run({616 command: "buyitem",617 options: { params: cTargetProdIdx + " " + cTargetPlanIdx }618 });619 return;620 }621 622 // ==========================================623 // 📢 MODULE 2: PREMIUM BROADCAST SYSTEM624 // ==========================================625 if (userId === adminId && isAwaitingBroadcast) {626 User.setProperty("awaiting_broadcast_data", false, "boolean");627 var userList = Bot.getProperty("all_users_list") || [];628 629 if (userList.length === 0) {630 Bot.sendMessage("❌ Bot mein abhi tak koi bhi user registered nahi hai.");631 return;632 }633 634 var targetMessageId = null;635 if (request) {636 if (request.message_id) { targetMessageId = request.message_id; }637 else if (request.message && request.message.message_id) { targetMessageId = request.message.message_id; }638 }639 640 if (!targetMessageId) {641 Bot.sendMessage("❌ Unable to fetch message ID for broadcast.");642 return;643 }644 645 Bot.sendMessage("⏳ Sending premium broadcast to " + userList.length + " users... Please wait.");646 647 // ✅ FIXED: pehle ek bhi blocked/invalid user Api.copyMessage() ko throw karwa deta648 // tha, jo bahar wale catch() tak chala jaata tha — isse loop beech me hi ruk jaata649 // tha (baaki users ko broadcast nahi jaata tha) aur admin ko scary "Error in handling"650 // dikhta tha, jabki zyada tar users ko message mil chuka hota tha. Ab har send apne651 // try/catch me hai, aur end me accurate success/fail count milega.652 var sentCount = 0;653 var failedCount = 0;654 for (var i = 0; i < userList.length; i++) {655 try {656 Api.copyMessage({657 chat_id: String(userList[i]),658 from_chat_id: adminId,659 message_id: Number(targetMessageId)660 });661 sentCount++;662 } catch (perUserErr) {663 failedCount++;664 }665 }666 Bot.sendMessage(667 "✅ <b>Broadcast Complete!</b>\n" +668 "📤 <b>Sent:</b> " + sentCount + " users\n" +669 (failedCount > 0 ? "⚠️ <b>Failed/Blocked:</b> " + failedCount + " users" : "🎉 <b>No failures!</b>"),670 { parse_mode: "HTML" }671 );672 }673 674} catch (err) {675 Bot.sendMessage("Error in handling: " + err.message);676}