Fix thread ID matching for email replies

This commit is contained in:
gpt-engineer-app[bot]
2025-10-28 20:29:14 +00:00
parent f57323aed4
commit 375db2e7d8
2 changed files with 65 additions and 13 deletions

View File

@@ -44,7 +44,7 @@ const handler = async (req: Request): Promise<Response> => {
}); });
// Extract thread ID from headers or inReplyTo // Extract thread ID from headers or inReplyTo
const threadId = headers['X-Thread-ID'] || let threadId = headers['X-Thread-ID'] ||
(inReplyTo ? inReplyTo.replace(/<|>/g, '').split('@')[0] : null); (inReplyTo ? inReplyTo.replace(/<|>/g, '').split('@')[0] : null);
if (!threadId) { if (!threadId) {
@@ -58,17 +58,68 @@ const handler = async (req: Request): Promise<Response> => {
}); });
} }
// Find submission by thread_id // Extract ticket number from thread_id (handles multiple formats)
const { data: submission, error: submissionError } = await supabase // Formats: "TW-100000.uuid", "ticket-TW-100000", "TW-100000"
const ticketMatch = threadId.match(/(?:ticket-)?(TW-\d+)/i);
const ticketNumber = ticketMatch ? ticketMatch[1] : null;
edgeLogger.info('Thread ID extracted', {
requestId: tracking.requestId,
rawThreadId: threadId,
ticketNumber
});
// Find submission by thread_id or ticket_number
let submission = null;
let submissionError = null;
// Strategy 1: Try exact thread_id match
const { data: submissionByThreadId, error: error1 } = await supabase
.from('contact_submissions') .from('contact_submissions')
.select('id, email, status') .select('id, email, status, ticket_number')
.eq('thread_id', threadId) .eq('thread_id', threadId)
.single(); .maybeSingle();
if (submissionByThreadId) {
submission = submissionByThreadId;
} else if (ticketNumber) {
// Strategy 2: Try ticket_number match
const { data: submissionByTicket, error: error2 } = await supabase
.from('contact_submissions')
.select('id, email, status, ticket_number, thread_id')
.eq('ticket_number', ticketNumber)
.maybeSingle();
if (submissionByTicket) {
submission = submissionByTicket;
// Update thread_id if it's null or in old format
if (!submissionByTicket.thread_id || submissionByTicket.thread_id !== threadId) {
await supabase
.from('contact_submissions')
.update({ thread_id: threadId })
.eq('id', submissionByTicket.id);
edgeLogger.info('Updated submission thread_id', {
requestId: tracking.requestId,
submissionId: submissionByTicket.id,
oldThreadId: submissionByTicket.thread_id,
newThreadId: threadId
});
}
} else {
submissionError = error2;
}
} else {
submissionError = error1;
}
if (submissionError || !submission) { if (submissionError || !submission) {
edgeLogger.warn('Submission not found for thread ID', { edgeLogger.warn('Submission not found for thread ID', {
requestId: tracking.requestId, requestId: tracking.requestId,
threadId threadId,
ticketNumber,
error: submissionError
}); });
return new Response(JSON.stringify({ success: false, reason: 'submission_not_found' }), { return new Response(JSON.stringify({ success: false, reason: 'submission_not_found' }), {
status: 200, status: 200,

View File

@@ -232,6 +232,13 @@ const handler = async (req: Request): Promise<Response> => {
} }
}); });
// Update thread_id with Message-ID format (always, not just when email is sent)
const threadId = `${ticketNumber}.${submission.id}`;
await supabase
.from('contact_submissions')
.update({ thread_id: threadId })
.eq('id', submission.id);
if (forwardEmailKey) { if (forwardEmailKey) {
// Send admin notification // Send admin notification
fetch('https://api.forwardemail.net/v1/emails', { fetch('https://api.forwardemail.net/v1/emails', {
@@ -302,12 +309,6 @@ The ThrillWiki Team`,
}).catch(err => { }).catch(err => {
edgeLogger.error('Failed to send confirmation email', { requestId, error: err.message }); edgeLogger.error('Failed to send confirmation email', { requestId, error: err.message });
}); });
// Update thread_id with ticket number
await supabase
.from('contact_submissions')
.update({ thread_id: `ticket-${ticketNumber}` })
.eq('id', submission.id);
} }
const duration = Date.now() - startTime; const duration = Date.now() - startTime;