Files
openclaw-backups/skills/imap-smtp-email/scripts/check-anthonymau-email.js.bak

215 lines
5.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Check anthonymau@gmail.com for new AI-related emails
* Fetches full email content for summarization
*/
const Imap = require('imap');
const config = {
user: 'anthonymau@gmail.com',
password: 'wfux qjhw eqjo jswm',
host: 'imap.gmail.com',
port: 993,
tls: true,
tlsOptions: { rejectUnauthorized: false }
};
// AI newsletter patterns to match
const AI_PATTERNS = [
'ai valley',
'the rundown',
'ai secret',
'byte-sized',
'bytesized',
'myclaw',
'openai global',
'deep view',
'khoj',
'synthetic',
'openhands',
'artificial intelligence',
'ai newsletter',
'benevolent',
'tldr',
'benedict'
];
function isAINewsletter(from, subject) {
const text = (from + ' ' + subject).toLowerCase();
return AI_PATTERNS.some(pattern => text.includes(pattern.toLowerCase()));
}
const imap = new Imap(config);
imap.once('ready', () => {
imap.openBox('INBOX', false, (err, box) => {
if (err) {
console.log('STATUS:error');
console.log('ERROR:open_box:' + err.message);
imap.end();
process.exit(1);
}
imap.search(['ALL'], (err, results) => {
if (err) {
console.log('STATUS:error');
console.log('ERROR:search:' + err.message);
imap.end();
process.exit(1);
}
const total = results.length;
const recent = results.slice(-200); // Get last 200 emails (covers ~2 days for most inboxes)
const lastUid = recent.length > 0 ? recent[recent.length - 1] : 0;
console.log('STATUS:connected');
console.log('TOTAL:' + total);
console.log('LAST_UID:' + lastUid);
console.log('RECENT:' + recent.join(','));
if (recent.length > 0) {
// Fetch headers with UID
const fetch = imap.fetch(recent, {
bodies: 'HEADER.FIELDS (FROM SUBJECT DATE)',
struct: false,
uid: true
});
const aiEmails = [];
fetch.on('message', (msg) => {
let headers = '';
let uid = null;
msg.on('body', (stream, info) => {
stream.on('data', (chunk) => {
headers += chunk.toString('utf8');
});
});
msg.once('attributes', (attrs) => {
uid = attrs.uid;
});
msg.once('end', () => {
const fromMatch = headers.match(/From: (.+)/i);
const subjectMatch = headers.match(/Subject: (.+)/i);
const dateMatch = headers.match(/Date: (.+)/i);
const from = fromMatch ? fromMatch[1].trim() : '';
const subject = subjectMatch ? subjectMatch[1].trim() : '';
const dateStr = dateMatch ? dateMatch[1].trim() : '';
// Only include emails from the last 36 hours
let isRecent = true;
if (dateStr) {
try {
const emailDate = new Date(dateStr);
const cutoff = new Date(Date.now() - 36 * 60 * 60 * 1000);
isRecent = emailDate > cutoff;
} catch(e) {}
}
if (isRecent && isAINewsletter(from, subject)) {
aiEmails.push({ uid, from, subject });
}
});
});
fetch.once('end', () => {
console.log('AI_COUNT:' + aiEmails.length);
if (aiEmails.length === 0) {
imap.end();
process.exit(0);
}
// Get UIDs for body fetch
const aiUids = aiEmails.map(e => e.uid).filter(u => u);
if (aiUids.length === 0) {
imap.end();
process.exit(0);
}
// Fetch full body for AI emails
const bodyFetch = imap.fetch(aiUids, {
bodies: ['1'],
struct: false,
uid: true
});
let processed = 0;
bodyFetch.on('message', (msg, seqno) => {
let body = '';
let uid = null;
msg.on('body', (stream) => {
stream.on('data', (chunk) => {
body += chunk.toString('utf8');
});
});
msg.once('attributes', (attrs) => {
uid = attrs.uid;
});
msg.once('end', () => {
processed++;
// Find matching email metadata
const meta = aiEmails.find(e => e.uid === uid) || aiEmails[processed - 1];
// Clean content
let content = body;
try {
// Decode quoted-printable soft line breaks FIRST
content = content.replace(/=\r?\n/g, '');
// Decode quoted-printable hex codes
content = content.replace(/=([0-9A-F]{2})/gi, (m, p) =>
String.fromCharCode(parseInt(p, 16)));
// Strip HTML
content = content.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
} catch (e) {}
const truncated = content.substring(0, 3000).trim();
console.log(`AI_EMAIL:${meta.from} | ${meta.subject}`);
console.log(`AI_CONTENT:${truncated}`);
if (processed === aiUids.length) {
imap.end();
process.exit(0);
}
});
});
bodyFetch.once('error', (err) => {
console.log('ERROR:body_fetch:' + err.message);
imap.end();
process.exit(1);
});
});
} else {
console.log('AI_COUNT:0');
imap.end();
process.exit(0);
}
});
});
});
imap.once('error', (err) => {
console.log('STATUS:error');
console.log('ERROR:connect:' + err.message);
process.exit(1);
});
imap.once('end', () => {
process.exit(0);
});
imap.connect();