ashoksarande3/ASHOK_HACK_STORE_BOTPublic ยท Bot Template
AIThis bot operates as a commercial storefront for selling Free Fire game hacks and cheats via UPI QR code payments. It features a dynamic pricing system with separate normal and reseller prices, product plans with flexible durations (days, hours, minutes), and a reseller program requiring a one-time upgrade fee. The bot handles payment verification through QR code generation and expiry tracking, user verification via Telegram contact sharing, and admin tools for stock management, plan creation, and ownership transfer. It includes a balance system, maintenance mode, and Telegram Stars payment fallback. The codebase uses TeleBotHost's TBL JavaScript APIs (Bot, Api, HTTP, db properties, Libs) for all logic.
commands/_onWebKeyReceive.js
javascript ยท 257 lines
1/**#command2name: /onWebKeyReceive3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12try { 13 // Parse response safely only if content exists14 var response = null;15 if (typeof content === "string" && content.trim() !== "") {16 try {17 response = JSON.parse(content);18 } catch (e) {19 // Keep response as null if JSON parsing fails20 }21 }22 23 var userId = user.telegramid;24 var chatId = chat.chatid;25 26 // ๐ PRODUCT DATA ACCURACY CORE (DYNAMIC)27 var dataOptions = options || {}; 28 29 // ๐ 1. PRODUCT ID LAYER (Added for flawless API requests)30 var prodId = dataOptions.prod_id || dataOptions.id || dataOptions.product_id || User.getProperty("last_pending_prod_id") || null;31 32 // 2. Raw options fallback mechanisms33 var rawProdName = dataOptions.prod_name || dataOptions.product || dataOptions.name || User.getProperty("last_pending_prod_name") || "Product";34 var planDays = String(dataOptions.plan_days || dataOptions.days || User.getProperty("last_pending_plan_days") || "1");35 var pDaysNumOnly = planDays.replace(/[^0-9]/g, "").trim(); 36 var planUnit = dataOptions.plan_unit || User.getProperty("last_pending_plan_unit") || "day";37 var unitLabelWordW = (planUnit === "hour") ? (Number(pDaysNumOnly) === 1 ? "Hour" : "Hours") :38 (planUnit === "minute") ? (Number(pDaysNumOnly) === 1 ? "Minute" : "Minutes") :39 (Number(pDaysNumOnly) === 1 ? "Day" : "Days");40 var durationDisplayW = pDaysNumOnly + " " + unitLabelWordW;41 42 // 3. Database validation layer to completely kill the "Product" fallback string bug43 var productList = Bot.getProperty("stored_products") || [];44 var prodName = rawProdName.trim(); 45 46 // โก DEEP ADVANCED DATABASE SEARCH MATCH (Matches by ID first if available, then name)47 if (productList.length > 0) {48 var checkTerm = prodName.toLowerCase();49 var foundMatch = false;50 51 for (var i = 0; i < productList.length; i++) {52 var dbItem = productList[i];53 var dbName = dbItem.name ? dbItem.name.trim() : "";54 var dbId = dbItem.id || null;55 56 // If ID matches directly, use it!57 if (prodId && dbId && String(prodId) === String(dbId)) {58 prodName = dbName;59 foundMatch = true;60 break;61 }62 63 if (!dbName) continue;64 65 if (dbName.toLowerCase() === checkTerm || 66 (checkTerm !== "product" && (checkTerm.indexOf(dbName.toLowerCase()) > -1 || dbName.toLowerCase().indexOf(checkTerm) > -1))) {67 prodName = dbName; 68 if (dbId) { prodId = dbId; } // Backfill ID if name matched69 foundMatch = true;70 break;71 }72 }73 74 if (!foundMatch || prodName.toLowerCase() === "product") {75 var lastPending = User.getProperty("last_pending_prod_name");76 if (lastPending && lastPending.toLowerCase() !== "product") {77 prodName = lastPending.trim();78 } else if (productList.length === 1) {79 prodName = productList[0].name.trim();80 if (productList[0].id) { prodId = productList[0].id; }81 }82 }83 }84 85 var price = Number(dataOptions.price) || Number(User.getProperty("last_pending_price")) || 0;86 var firstName = dataOptions.first_name || user.first_name || "User";87 var usernameText = user.username ? "@" + user.username : "No Username";88 var currentWalletBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);89 90 var generatedKey = null;91 var isApiDelivery = false;92 var isBackupUsed = false;93 94 var cleanProdNameUpper = prodName.trim().toUpperCase();95 var manualKeysStorageKey = "manual_keys_" + cleanProdNameUpper + "_" + pDaysNumOnly;96 var backupStockKey = "stock_" + prodName.trim() + "_" + pDaysNumOnly + "_Day";97 98 // โก STEP 1: FORCE CHECK MANUAL STOCK (CRITICAL OVERRIDE)99 var manualStock = Bot.getProperty(manualKeysStorageKey);100 101 if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {102 manualStock = Bot.getProperty(backupStockKey);103 isBackupUsed = true;104 }105 106 if (typeof manualStock === "string" && manualStock.trim() !== "") {107 try {108 manualStock = JSON.parse(manualStock);109 } catch(err) {110 manualStock = manualStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean);111 }112 }113 114 if (Array.isArray(manualStock) && manualStock.length > 0) {115 generatedKey = manualStock.shift(); 116 117 if (isBackupUsed) {118 Bot.setProperty(backupStockKey, manualStock, "json");119 var mainStock = Bot.getProperty(manualKeysStorageKey) || [];120 if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }121 if (Array.isArray(mainStock)) {122 var idx = mainStock.indexOf(generatedKey);123 if (idx > -1) { mainStock.splice(idx, 1); }124 Bot.setProperty(manualKeysStorageKey, mainStock, "json");125 }126 } else {127 Bot.setProperty(manualKeysStorageKey, manualStock, "json");128 var backupStock = Bot.getProperty(backupStockKey) || [];129 if (typeof backupStock === "string") { backupStock = backupStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }130 if (Array.isArray(backupStock)) {131 var idx = backupStock.indexOf(generatedKey);132 if (idx > -1) { backupStock.splice(idx, 1); }133 Bot.setProperty(backupStockKey, backupStock, "json");134 }135 }136 }137 138 // โก STEP 2: FALLBACK TO API KEYS (IF NO MANUAL STOCK WAS FOUND)139 if (!generatedKey && response && response.status === "success") {140 generatedKey = response.key || response.code || response.serial;141 if (generatedKey) {142 isApiDelivery = true;143 }144 }145 146 // STEP 3: SUCCESS DELIVERY MECHANICS147 if (generatedKey) {148 Libs.ResourcesLib.userRes("balance").add(-price);149 150 var pastSpent = Bot.getProperty("total_spent_by_" + userId) || 0;151 Bot.setProperty("total_spent_by_" + userId, Number(pastSpent) + price, "number");152 153 var userKeysHistory = User.getProperty("my_purchased_keys") || [];154 userKeysHistory.push({155 product: prodName,156 product_id: prodId,157 days: pDaysNumOnly,158 price: price,159 key: generatedKey,160 date: new Date().toLocaleDateString()161 });162 User.setProperty("my_purchased_keys", userKeysHistory, "json");163 164 var remainingBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);165 166 var updateLinkForKey = Bot.getProperty("update_channel_link");167 var keyDeliveryButtons = [[{ text: "๐ Copy Key", copy_text: { text: generatedKey } }]];168 if (updateLinkForKey) {169 keyDeliveryButtons.push([{ text: "๐ฅ Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);170 }171 keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]);172 var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });173 174 var deliverText = "<blockquote>" +175 "<tg-emoji emoji-id='5350447674971660988'>โ
</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +176 "<tg-emoji emoji-id='6147767796097884213'>๐ฆ</tg-emoji> <b>Product:</b> <code>" + prodName + "</code>\n" +177 "<tg-emoji emoji-id='6284816251143331422'>๐</tg-emoji> <b>Validity:</b> <code>" + durationDisplayW + "</code>\n" +178 "<tg-emoji emoji-id='5352825278672412291'>๐</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +179 "โโโโโ <tg-emoji emoji-id='6147934084346682063'>#โฃ</tg-emoji> <b>BALANCE DETAILS</b> โโโโโ\n" +180 "<tg-emoji emoji-id='6195037488898121775'>โจ</tg-emoji> <b>Total Invest:</b> โน" + price.toFixed(2) + "\n" +181 "<tg-emoji emoji-id='5409048419211682843'>๐ต</tg-emoji> <b>New Wallet Balance:</b> โน" + remainingBal + "\n\n" +182 "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>๐ฅณ</tg-emoji></i>" +183 "</blockquote>";184 185 // โ
FIX: "Processing your order..." wala purana message ab delete ho jaata186 // hai, taaki chat me sirf final key-delivery message rahe.187 try {188 var procMsgId = Bot.getProperty("gen_msg_id_" + userId) || User.getProperty("gen_msg_id_" + userId);189 if (procMsgId) {190 Api.deleteMessage({ chat_id: chatId, message_id: Number(procMsgId) });191 Bot.setProperty("gen_msg_id_" + userId, null, "string");192 User.setProperty("gen_msg_id_" + userId, null, "string");193 }194 } catch (cleanupErr) {}195 196 Api.sendMessage({197 chat_id: chatId,198 text: deliverText,199 parse_mode: "HTML",200 reply_markup: keyDeliveryMarkup201 });202 203 var adminId = "8154859186"; 204 var deliveryMethodLabel = isApiDelivery ? "API" : "MANUAL STOCK";205 var adminMsg = "๐ <b>NEW PURCHASE DELIVERED (" + deliveryMethodLabel + ")</b> โ๏ธ\n\n" +206 "๐ค <b>Buyer:</b> " + firstName + " (<code>" + userId + "</code>)\n" +207 "๐ฆ <b>Product:</b> " + prodName + " (ID: " + (prodId || "N/A") + ")\n" +208 "โณ <b>Plan:</b> " + durationDisplayW + "\n" +209 "๐ธ <b>Price Deducted:</b> โน" + price.toFixed(2) + "\n" +210 "๐ณ <b>User Remaining Bal:</b> โน" + remainingBal + "\n" +211 "๐ <b>Key:</b> <code>" + generatedKey + "</code>";212 213 Api.sendMessage({ chat_id: adminId, text: adminMsg, parse_mode: "HTML" });214 215 User.setProperty("last_pending_price", null);216 User.setProperty("last_pending_prod_name", null);217 User.setProperty("last_pending_plan_days", null);218 User.setProperty("last_pending_prod_id", null);219 User.setProperty("last_pending_plan_unit", null);220 221 } else {222 // STEP 4: BOTH FAILED (System goes into error notification mode)223 Api.sendMessage({224 chat_id: chatId,225 text: "โณ <b>Wait some time admin will stock refill soon</b>\n<i>Your funds were not deducted.</i>",226 parse_mode: "HTML"227 });228 229 var webBalance = "Low/Empty";230 var websiteErrorReason = "Website API Empty Response / Down";231 232 if (response) {233 webBalance = response.balance || response.website_balance || "Low/Empty";234 websiteErrorReason = response.msg || response.message || "Low Balance / Out of Stock";235 }236 237 var alertAdminId = "8660373585";238 var lowBalanceAdminMsg = "โ ๏ธ <b>LOW BALANCE IN WEBSITE / API ERROR</b>\n" +239 "โโโโโโโโโโโโโโโโโโโโโโโโโโ\n\n" +240 "๐ <b>PRODUCT DETAILS:</b>\n" +241 "๐ฆ <b>Product Name:</b> <code>" + prodName + "</code>\n" +242 "๐ <b>Product ID:</b> <code>" + (prodId || "Not Passed") + "</code>\n" +243 "โณ <b>Days:</b> <code>" + pDaysNumOnly + " Days</code>\n" +244 "๐ฐ <b>Your Balance Website:</b> <code>" + webBalance + "</code>\n" +245 "โน๏ธ <b>API Reason:</b> <code>" + websiteErrorReason + "</code>\n\n" +246 "๐ค <b>USER DETAILS:</b>\n" +247 "๐ฃ <b>User Name:</b> " + usernameText + "\n" +248 "๐ <b>Name:</b> " + firstName + "\n" +249 "๐ <b>User ID:</b> <code>" + userId + "</code>\n" +250 "๐ณ <b>Available Balance (User Wallet):</b> โน" + currentWalletBal + "\n\n" +251 "๐ <i>Action Required: Please refill your website API or add/deliver the key manually to this user!</i>";252 253 Api.sendMessage({ chat_id: alertAdminId, text: lowBalanceAdminMsg, parse_mode: "HTML" });254 }255} catch (e) {256 Bot.sendMessage("โ Error executing delivery pipeline: " + e.message);257}