retry with same contact name

This commit is contained in:
Jun-te Kim 2026-02-14 13:19:33 +00:00
parent 638cb88732
commit 0d18e25b98

View file

@ -162,10 +162,10 @@ export async function POST(req: NextRequest) {
console.log("👤 [WEBHOOK] Customer name:", name); console.log("👤 [WEBHOOK] Customer name:", name);
// --- Contact (email-only is fine for v1) // --- Contact resolution: email → name → create with ZWS retry (up to 5 times)
console.log("🔍 [WEBHOOK] Looking for existing contact with email:", email); console.log("🔍 [WEBHOOK] Looking for existing contact with email:", email);
const contactsResponse = await xero.accountingApi.getContacts( let contactsResponse = await xero.accountingApi.getContacts(
xeroConn.tenantId, xeroConn.tenantId,
undefined, undefined,
`EmailAddress=="${email}"` `EmailAddress=="${email}"`
@ -173,15 +173,75 @@ export async function POST(req: NextRequest) {
let contact = contactsResponse.body.contacts?.[0]; let contact = contactsResponse.body.contacts?.[0];
// If not found by email, search by name
if (!contact) {
console.log("🔍 [WEBHOOK] Email not found, searching by name:", name);
contactsResponse = await xero.accountingApi.getContacts(
xeroConn.tenantId,
undefined,
`Name=="${name}"`
);
contact = contactsResponse.body.contacts?.[0];
if (contact) {
console.log("✅ [WEBHOOK] Found existing contact by name:", contact.contactID);
}
} else {
console.log("✅ [WEBHOOK] Found existing contact by email:", contact.contactID);
}
// If still not found, create new contact (with retry logic for duplicate names)
if (!contact) { if (!contact) {
console.log(" [WEBHOOK] Creating new contact"); console.log(" [WEBHOOK] Creating new contact");
const created = await xero.accountingApi.createContacts( let attempt = 0;
xeroConn.tenantId, const maxAttempts = 5;
{ contacts: [{ name, emailAddress: email }] }
); while (attempt < maxAttempts && !contact) {
contact = created.body.contacts?.[0]; let contactName = name;
} else {
console.log("✅ [WEBHOOK] Found existing contact:", contact.contactID); // Add zero-width spaces for uniqueness on retries
if (attempt > 0) {
contactName = name + "\u200B".repeat(attempt);
console.log(`🔄 [WEBHOOK] Retry attempt ${attempt}/${maxAttempts - 1} with ${attempt} zero-width space(s)`);
}
try {
const created = await xero.accountingApi.createContacts(
xeroConn.tenantId,
{ contacts: [{ name: contactName, emailAddress: email }] }
);
contact = created.body.contacts?.[0];
if (contact) {
console.log(`✅ [WEBHOOK] Contact created successfully on attempt ${attempt + 1}:`, contact.contactID);
break;
}
} catch (err: any) {
console.log(`⚠️ [WEBHOOK] Attempt ${attempt + 1} failed:`, err.message);
// Try to fetch existing contact by name
if (attempt < maxAttempts - 1) {
const existingByName = await xero.accountingApi.getContacts(
xeroConn.tenantId,
undefined,
`Name=="${name}"`
);
if (existingByName.body.contacts?.length) {
contact = existingByName.body.contacts[0];
console.log("✅ [WEBHOOK] Reusing existing contact with duplicate name:", contact.contactID);
break;
}
}
}
attempt++;
}
if (!contact) {
console.error("❌ [WEBHOOK] Failed to create or reuse contact after 5 attempts");
throw new Error("Failed to create Xero contact after multiple attempts");
}
} }
if (!contact?.contactID) { if (!contact?.contactID) {