Worker Dashboard Backend Script✅

var token = '8923324846:AAGsoQwXwP8HhNzrykRHg1QUDDSKMnv4hiY'; var sheetId = '1JYYWCWfFiK4QKRQfuZAbSCTfd1Fn5JPB2Bri2eXI3K4'; var adminChatId = '966116673'; function getPendingAmount(ss, tgId) { var reqSheet = ss.getSheetByName("Withdrawal_Requests"); if (!reqSheet) return 0; var reqData = reqSheet.getDataRange().getValues(); var pending = 0; for (var i = 1; i < reqData.length; i++) { if (reqData[i][1] == tgId && reqData[i][5] === "Pending") { pending += parseFloat(reqData[i][3]) || 0; } } return pending; } function getPendingReviewsCount(ss, tgId) { var logSheet = ss.getSheetByName("MessagesLog"); if (!logSheet) return 0; var data = logSheet.getDataRange().getValues(); var count = 0; for (var i = 1; i < data.length; i++) { if (data[i][2] == tgId && data[i][6] === "Pending") { count++; } } return count; } function getWithdrawHistory(ss, tgId) { var sheet = ss.getSheetByName("Withdrawal_Requests"); if (!sheet) return []; var data = sheet.getDataRange().getValues(); var history = []; for (var i = data.length - 1; i >= 1; i--) { if (data[i][1] == tgId) { history.push({ date: data[i][0], amount: data[i][3], status: data[i][5] }); } } return history; } function doPost(e) { try { var contents = JSON.parse(e.postData.contents); // 1. ADMIN ACTION VIA TELEGRAM if (contents.callback_query) { var callbackData = contents.callback_query.data; var messageId = contents.callback_query.message.message_id; if (callbackData.startsWith("approve_") || callbackData.startsWith("reject_")) { var parts = callbackData.split("_"); var action = parts[0]; var row = parseInt(parts[1]); var ss = SpreadsheetApp.openById(sheetId); var logSheet = ss.getSheetByName("MessagesLog"); var userId = logSheet.getRange(row, 3).getValue(); if (action === "approve") { logSheet.getRange(row, 7).setValue("Approved"); editMessageText(adminChatId, messageId, "✅ Approved by Admin"); sendReply(userId, "🎉 Badhai ho! Aapka review approve ho gaya hai aur paise wallet mein add ho gaye hain."); } else { logSheet.getRange(row, 7).setValue("Rejected"); editMessageText(adminChatId, messageId, "❌ Rejected by Admin"); sendReply(userId, "😔 Maaf kijiye, aapka review reject kar diya gaya hai. Kripya rules follow karke bhejein."); } answerCallbackQuery(contents.callback_query.id, "Status Updated!"); } return ContentService.createTextOutput("OK"); } // 2. USER SENDS REVIEW if (contents.message) { var chatID = contents.message.chat.id; var name = ((contents.message.from.first_name || "") + " " + (contents.message.from.last_name || "")).trim(); var text = contents.message.text || contents.message.caption || "Media without text"; var lowerText = text.trim().toLowerCase(); if (lowerText === "/start") { return sendReply(chatID, "Welcome to TECH X Ray! 🚀\n\nHame apna gadget review yahan bhejein. Approve hone par aapke wallet me paise add ho gaye hain.\n\nApna Password janne ke liye /myid type karein."); } if (lowerText === "/myid") { return sendReply(chatID, "Aapka Login ID/Password hai: " + chatID + "\n\nIs ID aur apne Mobile Number ka use karke hamari website par login karein."); } var ss = SpreadsheetApp.openById(sheetId); var logSheet = ss.getSheetByName("MessagesLog"); var date = new Date(); logSheet.appendRow([Utilities.formatDate(date, "GMT+05:30", "dd/MM/yyyy"), Utilities.formatDate(date, "GMT+05:30", "HH:mm:ss"), chatID, name, "", text, "Pending"]); var lastRow = logSheet.getLastRow(); // AUTO FORMAT & DROPDOWN COPY LOGIC FOR REVIEWS if (lastRow > 2) { var sourceRange = logSheet.getRange(lastRow - 1, 1, 1, logSheet.getLastColumn()); var targetRange = logSheet.getRange(lastRow, 1, 1, logSheet.getLastColumn()); sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_DATA_VALIDATION, false); sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } forwardToAdmin(chatID, contents.message.message_id, lastRow, name); return sendReply(chatID, "✅ Hame aapka review mil gaya hai! Quality check ke baad status update kar diya jayega."); } } catch (error) {} return ContentService.createTextOutput("OK"); } function sendReply(chatID, text) { UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/sendMessage", { method: "post", payload: { "chat_id": chatID, "text": text, "parse_mode": "HTML" }, muteHttpExceptions: true }); } function editMessageText(chatId, messageId, newText) { UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/editMessageText", { method: "post", payload: { "chat_id": chatId, "message_id": messageId, "text": newText }, muteHttpExceptions: true }); } function answerCallbackQuery(callbackQueryId, text) { UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/answerCallbackQuery", { method: "post", payload: { "callback_query_id": callbackQueryId, "text": text }, muteHttpExceptions: true }); } function forwardToAdmin(fromChatId, messageId, rowNumber, userName) { if(!adminChatId) return; UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/forwardMessage", { method: "post", payload: { "chat_id": adminChatId, "from_chat_id": fromChatId, "message_id": messageId }, muteHttpExceptions: true }); var keyboard = { "inline_keyboard": [ [ { "text": "✅ Approve", "callback_data": "approve_" + rowNumber }, { "text": "❌ Reject", "callback_data": "reject_" + rowNumber } ] ] }; UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/sendMessage", { method: "post", payload: { "chat_id": adminChatId, "text": "Review from: " + userName + "\nDatabase Row: " + rowNumber + "\nAction required:", "reply_markup": JSON.stringify(keyboard) }, muteHttpExceptions: true }); } function doGet(e) { var action = e.parameter.action; var ss = SpreadsheetApp.openById(sheetId); var walletSheet = ss.getSheetByName("User_Wallets"); var data = walletSheet.getDataRange().getValues(); if (action === "auth") { var mobile = e.parameter.mobile; var tgId = e.parameter.tgId; var name = e.parameter.name; var sessionToken = Utilities.getUuid(); for (var i = 1; i < data.length; i++) { if (data[i][2] == tgId) { if (data[i][1] == mobile) { walletSheet.getRange(i + 1, 10).setValue(sessionToken); var pendingAmount = getPendingAmount(ss, tgId); var realBalance = (parseFloat(data[i][8]) || 0) - pendingAmount; var rate = parseFloat(data[i][4]) || 0.10; var currentUnpaidPosts = rate > 0 ? Math.floor(realBalance / rate) : 0; var pendingReviews = getPendingReviewsCount(ss, tgId); var historyData = getWithdrawHistory(ss, tgId); return ContentService.createTextOutput(JSON.stringify({ status: "success", sessionToken: sessionToken, name: data[i][3], rate: rate, approvedPosts: data[i][5], totalEarnings: data[i][6], totalWithdrawn: data[i][7], availableBalance: realBalance, currentUnpaidPosts: currentUnpaidPosts, pendingReviews: pendingReviews, history: historyData })).setMimeType(ContentService.MimeType.JSON); } else { return ContentService.createTextOutput(JSON.stringify({status: "error", message: "Yeh Telegram ID kisi aur Mobile number ke sath link hai!"})).setMimeType(ContentService.MimeType.JSON); } } if (data[i][1] == mobile && data[i][2] != tgId) { return ContentService.createTextOutput(JSON.stringify({status: "error", message: "Yeh Mobile number kisi aur Telegram ID ke sath link hai!"})).setMimeType(ContentService.MimeType.JSON); } } if (!name || name === "User" || name.trim() === "") { return ContentService.createTextOutput(JSON.stringify({status: "error", message: "Account nahi mila! Kripya 'New Member' tab se register karein."})).setMimeType(ContentService.MimeType.JSON); } var newRow = data.length + 1; var date = new Date(); var defaultRate = 0.10; var approvedPostsFormula = '=COUNTIFS(MessagesLog!C:C, C' + newRow + ', MessagesLog!G:G, "Approved")'; var totalEarningsFormula = '=F' + newRow + ' * E' + newRow; var totalWithdrawnFormula = '=SUMIFS(Withdrawal_Requests!D:D, Withdrawal_Requests!B:B, C' + newRow + ', Withdrawal_Requests!F:F, "Paid")'; var availableBalanceFormula = '=G' + newRow + ' - H' + newRow; walletSheet.appendRow([Utilities.formatDate(date, "GMT+05:30", "dd/MM/yyyy"), mobile, tgId, name, defaultRate, approvedPostsFormula, totalEarningsFormula, totalWithdrawnFormula, availableBalanceFormula, sessionToken]); var uLastRow = walletSheet.getLastRow(); // AUTO FORMAT COPY LOGIC FOR NEW USERS if (uLastRow > 2) { var sourceRange = walletSheet.getRange(uLastRow - 1, 1, 1, walletSheet.getLastColumn()); var targetRange = walletSheet.getRange(uLastRow, 1, 1, walletSheet.getLastColumn()); sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } return ContentService.createTextOutput(JSON.stringify({ status: "success", sessionToken: sessionToken, name: name, rate: defaultRate, approvedPosts: 0, totalEarnings: 0, totalWithdrawn: 0, availableBalance: 0, currentUnpaidPosts: 0, pendingReviews: 0, history: [] })).setMimeType(ContentService.MimeType.JSON); } if (action === "withdraw") { var lock = LockService.getScriptLock(); try { lock.waitLock(5000); var tgId = e.parameter.tgId; var amount = parseFloat(e.parameter.amount); var clientToken = e.parameter.sessionToken; if (amount <= 0 || isNaN(amount)) return ContentService.createTextOutput(JSON.stringify({status: "error", message: "Invalid Amount!"})).setMimeType(ContentService.MimeType.JSON); data = walletSheet.getDataRange().getValues(); var hasBalance = false; for (var i = 1; i < data.length; i++) { if (data[i][2] == tgId) { var dbToken = data[i][9]; if (dbToken && clientToken && dbToken !== clientToken) { return ContentService.createTextOutput(JSON.stringify({status: "logout", message: "Security Alert: Aapka account kisi dusre device/tab me login hua hai. Auto Logout ho raha hai."})).setMimeType(ContentService.MimeType.JSON); } var pendingAmount = getPendingAmount(ss, tgId); var realBalance = (parseFloat(data[i][8]) || 0) - pendingAmount; if (realBalance >= amount) hasBalance = true; break; } } if (!hasBalance) return ContentService.createTextOutput(JSON.stringify({status: "error", message: "System Block: Insufficient Balance!"})).setMimeType(ContentService.MimeType.JSON); var withdrawSheet = ss.getSheetByName("Withdrawal_Requests"); withdrawSheet.appendRow([Utilities.formatDate(new Date(), "GMT+05:30", "dd/MM/yyyy"), tgId, e.parameter.name, amount, e.parameter.upi, "Pending"]); var wLastRow = withdrawSheet.getLastRow(); // AUTO FORMAT & DROPDOWN COPY LOGIC FOR WITHDRAWALS if (wLastRow > 2) { var sourceRange = withdrawSheet.getRange(wLastRow - 1, 1, 1, withdrawSheet.getLastColumn()); var targetRange = withdrawSheet.getRange(wLastRow, 1, 1, withdrawSheet.getLastColumn()); sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_DATA_VALIDATION, false); sourceRange.copyTo(targetRange, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } return ContentService.createTextOutput(JSON.stringify({status: "success"})).setMimeType(ContentService.MimeType.JSON); } catch (err) { return ContentService.createTextOutput(JSON.stringify({status: "error", message: "Server busy, please try after 10 seconds!"})).setMimeType(ContentService.MimeType.JSON); } finally { lock.releaseLock(); } } }