Files
moyosapp_beta.0.0.3.3_beta/scripts/test-resend-webhook.ts
2026-01-16 19:04:48 +02:00

124 lines
3.9 KiB
TypeScript

#!/usr/bin/env tsx
/**
* Test Resend Webhook Locally
*
* This script simulates a Resend webhook event to test your webhook handler.
*
* Usage:
* npx tsx scripts/test-resend-webhook.ts [emailId] [eventType]
*
* Examples:
* npx tsx scripts/test-resend-webhook.ts # Uses first email from DB
* npx tsx scripts/test-resend-webhook.ts abc123 delivered # Specific email and event
*/
import { prisma } from '../src/lib/db';
const BASE_URL = process.env.APP_URL || 'http://localhost:3001';
async function testWebhook() {
const args = process.argv.slice(2);
let emailId = args[0];
const eventType = args[1] || 'email.delivered';
console.log('🔍 Testing Resend Webhook Locally\n');
// If no emailId provided, get the most recent one from DB
if (!emailId) {
const recentEmail = await prisma.emailLog.findFirst({
where: { resendMessageId: { not: null } },
orderBy: { createdAt: 'desc' },
select: { id: true, resendMessageId: true, recipientEmail: true, status: true },
});
if (recentEmail?.resendMessageId) {
emailId = recentEmail.resendMessageId;
console.log(`📧 Found recent email:`);
console.log(` ID: ${recentEmail.id}`);
console.log(` Resend ID: ${recentEmail.resendMessageId}`);
console.log(` Recipient: ${recentEmail.recipientEmail}`);
console.log(` Current Status: ${recentEmail.status}\n`);
} else {
console.log('❌ No emails found in database with resendMessageId');
console.log(' Send an email first, then run this script again.\n');
// Show all emails for debugging
const allEmails = await prisma.emailLog.findMany({
take: 5,
orderBy: { createdAt: 'desc' },
select: { id: true, resendMessageId: true, recipientEmail: true, status: true, createdAt: true },
});
if (allEmails.length > 0) {
console.log('📋 Recent emails in database:');
allEmails.forEach(e => {
console.log(` - ${e.recipientEmail} | Status: ${e.status} | ResendID: ${e.resendMessageId || 'null'}`);
});
}
process.exit(1);
}
}
// Create webhook payload (simulating Resend's format)
const payload = {
type: eventType,
created_at: new Date().toISOString(),
data: {
email_id: emailId,
from: 'noreply@themoyos.co.za',
to: ['test@example.com'],
subject: 'Test Email',
created_at: new Date().toISOString(),
},
};
console.log(`📤 Sending ${eventType} webhook for email: ${emailId}`);
console.log(` URL: ${BASE_URL}/api/webhooks/resend\n`);
try {
const response = await fetch(`${BASE_URL}/api/webhooks/resend`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// Note: Not including svix headers since we're testing without signature verification
// In production, Resend sends: svix-id, svix-timestamp, svix-signature
},
body: JSON.stringify(payload),
});
const responseText = await response.text();
let responseData;
try {
responseData = JSON.parse(responseText);
} catch {
responseData = responseText;
}
console.log(`📥 Response: ${response.status} ${response.statusText}`);
console.log(` Body:`, responseData);
if (response.ok) {
// Check if the status was updated in the database
const updatedEmail = await prisma.emailLog.findFirst({
where: { resendMessageId: emailId },
select: { id: true, status: true, lastEventAt: true },
});
if (updatedEmail) {
console.log(`\n✅ Email status updated:`);
console.log(` New Status: ${updatedEmail.status}`);
console.log(` Last Event: ${updatedEmail.lastEventAt}`);
}
} else {
console.log(`\n❌ Webhook failed`);
}
} catch (error) {
console.error('❌ Error calling webhook:', error);
}
}
// Run the test
testWebhook().catch(console.error);