- Reset master to upstream/main (16,697 commits) - Overlay 2,271 local-only files (skills, tools, workspace, configs, apps) - Restore IDENTITY.md and USER.md templates - Build verified, gateway running, Discord working Co-Authored-By: Claude Opus 4.6 <[email protected]>
152 lines
4.5 KiB
JavaScript
152 lines
4.5 KiB
JavaScript
const { execSync } = require("child_process");
|
|
const path = require("path");
|
|
|
|
// Configuration
|
|
const LIMIT = 50; // Process max 50 emails per account per run
|
|
const OUTLOOK_SCRIPTS_DIR = "/home/alex/clawd/skills/outlook/scripts";
|
|
const OUTLOOK_PROFILES = [
|
|
{ name: "Personal", dir: process.env.HOME + "/.outlook-mcp-personal" },
|
|
{ name: "Work", dir: process.env.HOME + "/.outlook-mcp-o365" },
|
|
];
|
|
|
|
function log(msg) {
|
|
console.log(`[${new Date().toISOString()}] ${msg}`);
|
|
}
|
|
|
|
function execCmd(cmd, env = {}) {
|
|
try {
|
|
return execSync(cmd, { encoding: "utf8", env: { ...process.env, ...env }, stdio: "pipe" });
|
|
} catch (e) {
|
|
log(`Error executing command: ${cmd}`);
|
|
log(e.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// --- Gmail ---
|
|
function processGmail() {
|
|
log("Checking Gmail...");
|
|
try {
|
|
const res = execCmd(
|
|
`npx -y mcporter call --server google-workspace --tool "gmail.search" --args '{"query":"is:unread", "maxResults":${LIMIT}}' --output json`,
|
|
);
|
|
if (!res) {
|
|
return;
|
|
}
|
|
|
|
const data = JSON.parse(res);
|
|
if (!data.messages || data.messages.length === 0) {
|
|
log("Gmail: No unread messages.");
|
|
return;
|
|
}
|
|
|
|
log(`Gmail: Found ${data.messages.length} unread messages.`);
|
|
|
|
for (const msgStub of data.messages) {
|
|
// Get details for summary
|
|
const detailsJson = execCmd(
|
|
`npx -y mcporter call --server google-workspace --tool "gmail.get" --args '{"messageId":"${msgStub.id}"}' --output json`,
|
|
);
|
|
if (detailsJson) {
|
|
let details;
|
|
try {
|
|
details = JSON.parse(detailsJson);
|
|
} catch (err) {
|
|
log(`Gmail: Failed to parse details JSON for ${msgStub.id}: ${err.message}`);
|
|
continue;
|
|
}
|
|
|
|
let subject = "(No Subject)";
|
|
let from = "(Unknown)";
|
|
|
|
// Handle mcporter simplified object
|
|
if (details.subject) {
|
|
subject = details.subject;
|
|
}
|
|
if (details.from) {
|
|
from = details.from;
|
|
}
|
|
|
|
// Handle raw Gmail API object
|
|
if (details.payload && details.payload.headers) {
|
|
subject = details.payload.headers.find((h) => h.name === "Subject")?.value || subject;
|
|
from = details.payload.headers.find((h) => h.name === "From")?.value || from;
|
|
} else if (!details.subject && !details.from) {
|
|
log(
|
|
`Gmail: Unexpected structure for ${msgStub.id}. Keys: ${Object.keys(details).join(", ")}`,
|
|
);
|
|
}
|
|
|
|
log(`[Gmail] ${from}: ${subject}`);
|
|
}
|
|
|
|
// Mark as read
|
|
execCmd(
|
|
`npx -y mcporter call --server google-workspace --tool "gmail.modify" --args '{"messageId":"${msgStub.id}","removeLabelIds":["UNREAD"]}' --output json`,
|
|
);
|
|
}
|
|
} catch (e) {
|
|
log(`Gmail Error: ${e.message}`);
|
|
}
|
|
}
|
|
|
|
// --- Outlook ---
|
|
function processOutlook(profile) {
|
|
log(`Checking Outlook (${profile.name})...`);
|
|
|
|
// Get token
|
|
const tokenScript = path.join(OUTLOOK_SCRIPTS_DIR, "outlook-token.sh");
|
|
|
|
// Ensure token is fresh
|
|
execCmd(`${tokenScript} refresh`, { OUTLOOK_CONFIG_DIR: profile.dir });
|
|
|
|
const token = execCmd(`${tokenScript} get`, { OUTLOOK_CONFIG_DIR: profile.dir })?.trim();
|
|
if (!token) {
|
|
log(`Outlook (${profile.name}): Could not get token.`);
|
|
return;
|
|
}
|
|
|
|
// Fetch unread
|
|
const url = `https://graph.microsoft.com/v1.0/me/messages?$filter=isRead%20eq%20false&$top=${LIMIT}&$select=id,subject,from,receivedDateTime`;
|
|
const curlCmd = `curl -s "${url}" -H "Authorization: Bearer ${token}"`;
|
|
|
|
const res = execCmd(curlCmd);
|
|
if (!res) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const data = JSON.parse(res);
|
|
if (!data.value || data.value.length === 0) {
|
|
log(`Outlook (${profile.name}): No unread messages.`);
|
|
return;
|
|
}
|
|
|
|
log(`Outlook (${profile.name}): Found ${data.value.length} unread messages.`);
|
|
|
|
for (const msg of data.value) {
|
|
const subject = msg.subject || "(No Subject)";
|
|
const from = msg.from?.emailAddress?.address || "(Unknown)";
|
|
log(`[Outlook-${profile.name}] ${from}: ${subject}`);
|
|
|
|
// Mark as read
|
|
const patchCmd = `curl -s -X PATCH "https://graph.microsoft.com/v1.0/me/messages/${msg.id}" -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" -d '{"isRead":true}'`;
|
|
execCmd(patchCmd);
|
|
}
|
|
} catch (e) {
|
|
log(`Outlook (${profile.name}) Error: ${e.message}`);
|
|
}
|
|
}
|
|
|
|
// --- Main ---
|
|
function main() {
|
|
log("Starting Email Sweep...");
|
|
processGmail();
|
|
for (const profile of OUTLOOK_PROFILES) {
|
|
processOutlook(profile);
|
|
}
|
|
log("Email Sweep Completed.");
|
|
}
|
|
|
|
main();
|