/** * RAGnarok 2.0 - Serverless Webhook Worker (Google Apps Script) * * Instructions: * 1. Go to https://script.google.com/ and create a new project. * 2. Paste this entire file into Code.gs. * 3. Replace 'YOUR_ADMIN_PASSWORD_HERE' with your actual backend admin password. * 4. IMPORTANT: Click "Deploy" -> "New Deployment" -> Select "Web App". * - Execute as: "Me" * - Who has access: "Anyone" * - Click "Deploy", authorize the app, and COPY the Web App URL. * 5. Paste the Web App URL into your Hugging Face Space .env file as: * APPS_SCRIPT_WEBHOOK_URL="https://script.google.com/macros/s/.../exec" * 6. Set up a Time-Driven Trigger (clock icon) to run `runAllScrapers` daily! */ const HF_MESS_MENU_URL = "https://iotacluster-rag-narok-backend.hf.space/api/admin/worker/upload-base64-pdf"; const HF_EMAILS_URL = "https://iotacluster-rag-narok-backend.hf.space/api/admin/worker/upload-emails"; const ADMIN_PASSWORD = "123456789"; /** * Web App Endpoint: This allows your Command Center's "Trigger Now" * button to send an HTTP GET request to Google to instantly run the scrapers! */ function doGet(e) { Logger.log("Received GET request from Command Center. Starting scrapers..."); runAllScrapers(); return ContentService.createTextOutput(JSON.stringify({ "status": "success", "message": "Scrapers executed successfully." })).setMimeType(ContentService.MimeType.JSON); } function runAllScrapers() { pushUnreadEmailsToHuggingFace(); pushMessMenuToHuggingFace(); } function pushUnreadEmailsToHuggingFace() { Logger.log("Scanning for general unread emails..."); // Search for up to 5 unread emails that are NOT Mess Menus const threads = GmailApp.search('is:unread -subject:"Mess Menu"', 0, 5); if (threads.length === 0) { Logger.log("No new unread general emails found."); return; } let emailsPayload = []; const blocklist = ["no-reply@accounts.google.com", "security alert", "unstop", "linkedin", "kaggle", "team unstop", "canva", "noreply@github.com", "noreply", "feed", "huggingface", "instagram", "udacity", "udemy", "supabase", "vercel"]; for (let i = 0; i < threads.length; i++) { let messages = threads[i].getMessages(); let message = messages[messages.length - 1]; // Get latest message in thread let subject = message.getSubject() || ""; let sender = message.getFrom() || ""; let date = message.getDate().toISOString(); let body = message.getPlainBody() || ""; // Check blocklist let isBlocked = false; let senderAndSub = (sender + " " + subject).toLowerCase(); for (let b of blocklist) { if (senderAndSub.includes(b)) { isBlocked = true; break; } } if (!isBlocked && body.trim() !== "") { emailsPayload.push({ "id": message.getId(), "subject": subject, "sender": sender, "date": date, "body": body }); Logger.log("Prepared to send: " + subject); } // Mark as read so we don't process it again tomorrow message.markRead(); } if (emailsPayload.length === 0) { Logger.log("No valid non-blocklisted emails found."); return; } const payload = { "emails": emailsPayload }; const options = { "method": "post", "contentType": "application/json", "headers": { "Authorization": "Bearer " + ADMIN_PASSWORD }, "payload": JSON.stringify(payload), "muteHttpExceptions": true }; Logger.log("Pushing " + emailsPayload.length + " emails to Hugging Face..."); const response = UrlFetchApp.fetch(HF_EMAILS_URL, options); Logger.log("Response Code: " + response.getResponseCode()); Logger.log("Response Body: " + response.getContentText()); } function pushMessMenuToHuggingFace() { Logger.log("Scanning for Mess Menu PDF..."); const threads = GmailApp.search('subject:"Mess Menu" has:attachment', 0, 1); if (threads.length === 0) { Logger.log("No Mess Menu emails found."); return; } const messages = threads[0].getMessages(); const latestMessage = messages[messages.length - 1]; const attachments = latestMessage.getAttachments(); let pdfAttachment = null; for (let i = 0; i < attachments.length; i++) { if (attachments[i].getContentType() === "application/pdf" || attachments[i].getName().toLowerCase().endsWith(".pdf")) { pdfAttachment = attachments[i]; break; } } if (!pdfAttachment) { Logger.log("Found Mess Menu email, but no PDF attachment was found."); return; } Logger.log("Found PDF: " + pdfAttachment.getName()); const pdfBytes = pdfAttachment.getBytes(); const base64Data = Utilities.base64Encode(pdfBytes); const payload = { "filename": pdfAttachment.getName(), "base64_data": base64Data }; const options = { "method": "post", "contentType": "application/json", "headers": { "Authorization": "Bearer " + ADMIN_PASSWORD }, "payload": JSON.stringify(payload), "muteHttpExceptions": true }; Logger.log("Pushing to Hugging Face webhook..."); const response = UrlFetchApp.fetch(HF_MESS_MENU_URL, options); Logger.log("Response Code: " + response.getResponseCode()); Logger.log("Response Body: " + response.getContentText()); }