Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
0be9d7a595
commit
7af969617e
@@ -5,6 +5,7 @@ import { createFileRoute } from "@tanstack/react-router";
|
||||
import { supabaseAdmin } from "@/integrations/supabase/client.server";
|
||||
import { ImapFlow } from "imapflow";
|
||||
import { simpleParser } from "mailparser";
|
||||
import { matchAndUpdateEmails } from "@/lib/email-matching.server";
|
||||
|
||||
const MAX_MESSAGES_PER_RUN = 50;
|
||||
|
||||
@@ -82,6 +83,51 @@ export const Route = createFileRoute("/hooks/poll-imap")({
|
||||
: null;
|
||||
const attachments = parsed.attachments ?? [];
|
||||
|
||||
// Upload attachments to storage; collect metadata.
|
||||
const attachmentMeta: Array<{
|
||||
filename: string;
|
||||
mime_type: string;
|
||||
size_bytes: number;
|
||||
storage_path: string;
|
||||
}> = [];
|
||||
for (let i = 0; i < attachments.length; i++) {
|
||||
const att = attachments[i];
|
||||
const filename =
|
||||
att.filename || `attachment-${i + 1}.bin`;
|
||||
const safeName = filename.replace(/[^\w.\-]+/g, "_");
|
||||
const path = `${msg.uid}/${Date.now()}-${i}-${safeName}`;
|
||||
try {
|
||||
const { error: upErr } = await supabaseAdmin.storage
|
||||
.from("email-attachments")
|
||||
.upload(path, att.content as Buffer, {
|
||||
contentType: att.contentType || "application/octet-stream",
|
||||
upsert: true,
|
||||
});
|
||||
if (upErr) {
|
||||
console.error("Attachment upload failed", filename, upErr.message);
|
||||
continue;
|
||||
}
|
||||
attachmentMeta.push({
|
||||
filename,
|
||||
mime_type: att.contentType || "application/octet-stream",
|
||||
size_bytes: att.size ?? (att.content as Buffer)?.length ?? 0,
|
||||
storage_path: path,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("Attachment store error", filename, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Threading headers
|
||||
const inReplyTo =
|
||||
(parsed.inReplyTo as string | undefined) ?? null;
|
||||
const refsRaw = (parsed.references as string | string[] | undefined) ?? [];
|
||||
const references = Array.isArray(refsRaw)
|
||||
? refsRaw
|
||||
: refsRaw
|
||||
? [refsRaw]
|
||||
: [];
|
||||
|
||||
const insertRow = {
|
||||
message_id: parsed.messageId ?? null,
|
||||
imap_uid: msg.uid,
|
||||
@@ -94,20 +140,27 @@ export const Route = createFileRoute("/hooks/poll-imap")({
|
||||
body_text: text,
|
||||
body_html: parsed.html || null,
|
||||
snippet,
|
||||
has_attachments: attachments.length > 0,
|
||||
attachment_count: attachments.length,
|
||||
has_attachments: attachmentMeta.length > 0,
|
||||
attachment_count: attachmentMeta.length,
|
||||
attachments: attachmentMeta,
|
||||
in_reply_to: inReplyTo,
|
||||
email_references: references,
|
||||
raw_size_bytes: msg.size ?? null,
|
||||
};
|
||||
|
||||
// Upsert by message_id to avoid duplicates if mailbox is re-polled
|
||||
const { error: insErr } = await supabaseAdmin
|
||||
const { data: insertedRows, error: insErr } = await supabaseAdmin
|
||||
.from("incoming_emails")
|
||||
.upsert(insertRow, { onConflict: "message_id", ignoreDuplicates: true });
|
||||
.upsert(insertRow, { onConflict: "message_id", ignoreDuplicates: true })
|
||||
.select("id");
|
||||
|
||||
if (insErr && !insErr.message.includes("duplicate")) {
|
||||
console.error("Insert failed for uid", msg.uid, insErr.message);
|
||||
} else {
|
||||
imported++;
|
||||
if (insertedRows && insertedRows.length > 0) {
|
||||
newEmailIds.push(insertedRows[0].id);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.uid > highestUid) highestUid = msg.uid;
|
||||
|
||||
Reference in New Issue
Block a user