Files
moyosapp_beta.0.0.3.3_beta1/scripts/test-resend-webhook.ts

145 lines
4.2 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";
type EmailLogPreview = {
id: string;
resendMessageId: string | null;
recipientEmail: string;
status: string;
createdAt?: Date;
};
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: EmailLogPreview) => {
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: unknown;
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: unknown) {
console.error("❌ Error calling webhook:", error);
}
}
// Run the test
testWebhook().catch((err: unknown) => console.error(err));