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();
}
}
}