// Code.gs — Google Apps Script Web App // Deploy as: Web app, Execute as "Me", Who has access: "Anyone" // ============================================ // CONFIGURATION — change these two, then create a NEW deployment version // ============================================ var SECRET_KEY = '5f5bd4c1751f7582f870954da60cafe2'; // e.g. output of: openssl rand -hex 16 var ALLOWED_EMAIL = 'justiceawudi@outlook.com'; // must match "Login Email" in extension Settings function doPost(e) { try { var data = JSON.parse(e.postData.contents); if (!data.key || data.key !== SECRET_KEY) { Logger.log('Unauthorized request - invalid key'); return ContentService.createTextOutput( JSON.stringify({ error: 'Unauthorized' }), ).setMimeType(ContentService.MimeType.JSON); } if (data.email !== ALLOWED_EMAIL) { Logger.log('Unauthorized request - invalid email: ' + data.email); return ContentService.createTextOutput( JSON.stringify({ error: 'Unauthorized email' }), ).setMimeType(ContentService.MimeType.JSON); } if (data.action === 'pollForLoginLink') { var result = pollForMagicLink(data.requestId); return ContentService.createTextOutput( JSON.stringify(result), ).setMimeType(ContentService.MimeType.JSON); } return ContentService.createTextOutput( JSON.stringify({ error: 'Unknown action' }), ).setMimeType(ContentService.MimeType.JSON); } catch (err) { Logger.log('Error in doPost: ' + err.message); return ContentService.createTextOutput( JSON.stringify({ error: err.message }), ).setMimeType(ContentService.MimeType.JSON); } } // ============================================ // Poll for magic login link. // // No "to:" filter — the email is sent to your Outlook address and // lands in Gmail via a forwarding rule, so its To/Delivered-To headers // may still reference Outlook rather than Gmail. from + subject + // newer_than + is:unread is specific enough since this only ever // searches your own mailbox. // ============================================ function pollForMagicLink(requestId) { var maxAttempts = 4; var pollInterval = 15000; Logger.log('[' + requestId + '] Starting poll for login link...'); for (var attempt = 1; attempt <= maxAttempts; attempt++) { Logger.log('[' + requestId + '] Attempt ' + attempt + '/' + maxAttempts); var searchQuery = 'from:talent.andela.com subject:"Andela Login Link" newer_than:5m is:unread'; var threads = GmailApp.search(searchQuery, 0, 5); Logger.log( '[' + requestId + '] Found ' + threads.length + ' matching threads', ); if (threads.length > 0) { var allMessages = []; for (var i = 0; i < threads.length; i++) { var messages = threads[i].getMessages(); for (var j = 0; j < messages.length; j++) allMessages.push(messages[j]); } allMessages.sort(function (a, b) { return b.getDate().getTime() - a.getDate().getTime(); }); var latestMessage = allMessages[0]; var body = latestMessage.getBody(); Logger.log( '[' + requestId + '] Processing email from: ' + latestMessage.getDate(), ); var accessAccountPattern = /]*href=["']([^"']+)["'][^>]*>\s*Access account\s*<\/a>/i; var match = body.match(accessAccountPattern); if (match && match[1]) { var link = match[1] .replace(/&/g, '&') .replace(/=/g, '=') .replace(/=/g, '=') .replace(/&/g, '&'); Logger.log('[' + requestId + '] Found Access account link: ' + link); latestMessage.markRead(); return { success: true, loginLink: link, emailDate: latestMessage.getDate().toISOString(), attempt: attempt, }; } Logger.log( '[' + requestId + '] Email found but no Access account link detected', ); } if (attempt < maxAttempts) { Logger.log('[' + requestId + '] Waiting ' + pollInterval / 1000 + 's...'); Utilities.sleep(pollInterval); } } Logger.log( '[' + requestId + '] No login link found after ' + maxAttempts + ' attempts', ); return { success: false, error: 'No login link found within timeout', attempts: maxAttempts, }; } // ============================================ // Debug helpers — run manually from the Apps Script editor's function // dropdown, then check the Executions log // ============================================ function debugLoginEmails() { var searchQuery = 'from:talent.andela.com subject:"Andela Login Link" newer_than:7d'; var threads = GmailApp.search(searchQuery, 0, 5); Logger.log('Found ' + threads.length + ' emails'); for (var i = 0; i < threads.length; i++) { var messages = threads[i].getMessages(); for (var j = 0; j < messages.length; j++) { var msg = messages[j]; Logger.log('---'); Logger.log('Subject: ' + msg.getSubject()); Logger.log('From: ' + msg.getFrom()); Logger.log('To: ' + msg.getTo()); Logger.log('Date: ' + msg.getDate()); var body = msg.getBody(); var pattern = /]*href=["']([^"']+)["'][^>]*>\s*Access account\s*<\/a>/i; var match = body.match(pattern); if (match) { Logger.log('Link found: ' + match[1].substring(0, 100)); } else { Logger.log('Access account link not found'); } } } } function testExtraction() { var result = pollForMagicLink('test-' + Date.now()); Logger.log(JSON.stringify(result, null, 2)); }