/** * Read multiple emails functionality */ const config = require('../config'); const { callGraphAPI } = require('../utils/graph-api'); const { ensureAuthenticated } = require('../auth'); const { cleanBody } = require('../utils/bodyParser'); const { formatDateTime } = require('../utils/time-formatter'); const { normalizeMailbox, buildPath, withMailboxHeaders } = require('../utils/mailbox'); /** * Format a single email for display * @param {object} email - Email object from Graph API * @param {string} emailId - Email ID for error context * @returns {string} - Formatted email text */ function formatEmail(email, emailId) { if (!email) { return `Email ID ${emailId}: Not found or inaccessible`; } try { const sender = email.from ? `${email.from.emailAddress.name} (${email.from.emailAddress.address})` : 'Unknown'; const to = email.toRecipients ? email.toRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None'; const cc = email.ccRecipients && email.ccRecipients.length > 0 ? email.ccRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None'; const bcc = email.bccRecipients && email.bccRecipients.length > 0 ? email.bccRecipients.map(r => `${r.emailAddress.name} (${r.emailAddress.address})`).join(", ") : 'None'; const date = formatDateTime(email.receivedDateTime); let body = ''; if (email.body) { body = cleanBody(email.body.content); } else { body = cleanBody(email.bodyPreview) || 'No content'; } return `From: ${sender} To: ${to} ${cc !== 'None' ? `CC: ${cc}\n` : ''}${bcc !== 'None' ? `BCC: ${bcc}\n` : ''}Subject: ${email.subject} Date: ${date} Importance: ${email.importance || 'normal'} Has Attachments: ${email.hasAttachments ? 'Yes' : 'No'} ${body}`; } catch (error) { return `Email ID ${emailId}: Error formatting email - ${error.message}`; } } /** * Read multiple emails handler * @param {object} args - Tool arguments * @returns {object} - MCP response */ async function handleReadMultipleEmails(args) { const emailIds = args.ids; const mb = normalizeMailbox(args.mailbox); const opts = { headers: withMailboxHeaders(mb) }; if (!emailIds || !Array.isArray(emailIds) || emailIds.length === 0) { return { content: [{ type: "text", text: "Email IDs array is required and must contain at least one ID." }] }; } const maxEmails = 10; if (emailIds.length > maxEmails) { return { content: [{ type: "text", text: `Too many email IDs provided. Maximum allowed is ${maxEmails}, but ${emailIds.length} were provided.` }] }; } try { const accessToken = await ensureAuthenticated(); const emailPromises = emailIds.map(async (emailId) => { try { const endpoint = buildPath(mb, `messages/${emailId}`); const queryParams = { $select: config.EMAIL_DETAIL_FIELDS }; const email = await callGraphAPI(accessToken, 'GET', endpoint, null, queryParams, opts); return { emailId, email, error: null }; } catch (error) { console.error(`Error reading email ${emailId}: ${error.message}`); return { emailId, email: null, error: error.message }; } }); const results = await Promise.all(emailPromises); const mailboxNote = mb.kind === 'user' ? ` Mailbox: ${mb.smtpOrUpn}.` : ''; const formattedEmails = results.map((result, index) => { const emailNumber = index + 1; const separator = "=".repeat(80); if (result.error) { return `${separator} EMAIL ${emailNumber} (ID: ${result.emailId}) ${separator} Error: ${result.error}`; } else { const formattedEmail = formatEmail(result.email, result.emailId); return `${separator} EMAIL ${emailNumber} (ID: ${result.emailId}) ${separator} ${formattedEmail}`; } }); const successCount = results.filter(r => !r.error && r.email).length; const errorCount = results.filter(r => r.error || !r.email).length; const summary = `Retrieved ${successCount} email(s) successfully${errorCount > 0 ? `, ${errorCount} failed` : ''}.${mailboxNote} `; return { content: [ { type: "text", text: summary + formattedEmails.join('\n\n') } ] }; } catch (error) { if (error.message === 'Authentication required') { return { content: [{ type: "text", text: "Authentication required. Please use the 'authenticate' tool first." }] }; } return { content: [{ type: "text", text: `Error accessing emails: ${error.message}` }] }; } } module.exports = handleReadMultipleEmails;