NeahFront9/app/api/mail/route.ts
2025-04-15 20:24:09 +02:00

155 lines
4.0 KiB
TypeScript

import { NextResponse } from 'next/server';
import Imap from 'imap';
import { simpleParser } from 'mailparser';
// IMAP configuration
const imapConfig = {
user: 'contact@governance-labs.org',
password: 'K!376c$6H#kMknM',
host: 'mail.infomaniak.com',
port: 993,
tls: true,
tlsOptions: { rejectUnauthorized: false }
};
interface ImapMessage {
header: {
from?: string[];
to?: string[];
subject?: string[];
date?: string[];
[key: string]: string[] | undefined;
};
body: string;
attributes: {
flags: string[];
};
}
// Helper function to create a promise-based IMAP connection
function createImapConnection() {
return new Promise((resolve, reject) => {
const imap = new Imap(imapConfig);
imap.once('ready', () => resolve(imap));
imap.once('error', (err: Error) => reject(err));
imap.connect();
});
}
// Helper function to promisify the message fetching
function fetchMessages(imap: Imap, box: string): Promise<ImapMessage[]> {
return new Promise((resolve, reject) => {
imap.openBox(box, false, (err, mailbox) => {
if (err) {
reject(err);
return;
}
// Search for all messages
imap.search(['ALL'], (err, results) => {
if (err) {
reject(err);
return;
}
// No messages found
if (!results || !results.length) {
resolve([]);
return;
}
const fetch = imap.fetch(results, {
bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE)', 'TEXT'],
struct: true
});
const messages: ImapMessage[] = [];
fetch.on('message', (msg) => {
const message: Partial<ImapMessage> = {};
msg.on('body', (stream, info) => {
let buffer = '';
stream.on('data', (chunk) => {
buffer += chunk.toString('utf8');
});
stream.once('end', () => {
if (info.which === 'TEXT') {
message.body = buffer;
} else {
message.header = Imap.parseHeader(buffer);
}
});
});
msg.once('attributes', (attrs) => {
message.attributes = attrs;
});
msg.once('end', () => {
messages.push(message as ImapMessage);
});
});
fetch.once('error', (err) => {
reject(err);
});
fetch.once('end', () => {
resolve(messages);
});
});
});
});
}
export async function GET(request: Request) {
try {
const imap = await createImapConnection() as Imap;
const messages = await fetchMessages(imap, 'INBOX');
// Process messages into the format expected by the frontend
const processedMessages = messages.map((msg: ImapMessage, index: number) => ({
id: index + 1,
accountId: 1,
from: msg.header.from?.[0] || '',
fromName: (msg.header.from?.[0] || '').split('<')[0].trim(),
to: msg.header.to?.[0] || '',
subject: msg.header.subject?.[0] || '',
body: msg.body || '',
date: msg.header.date?.[0] || new Date().toISOString(),
read: !(msg.attributes.flags.indexOf('\\Seen') < 0),
starred: !(msg.attributes.flags.indexOf('\\Flagged') < 0),
category: 'inbox'
}));
imap.end();
return NextResponse.json({ messages: processedMessages });
} catch (error) {
console.error('Error fetching emails:', error);
return NextResponse.json({ error: 'Failed to fetch emails' }, { status: 500 });
}
}
// Add endpoint to get mailboxes
export async function POST(request: Request) {
try {
const imap = await createImapConnection() as Imap;
const mailboxes = await new Promise((resolve, reject) => {
imap.getBoxes((err, boxes) => {
if (err) reject(err);
resolve(boxes);
});
});
imap.end();
return NextResponse.json({ mailboxes });
} catch (error) {
console.error('Error fetching mailboxes:', error);
return NextResponse.json({ error: 'Failed to fetch mailboxes' }, { status: 500 });
}
}