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);
// --- 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);
const contactsResponse = await xero.accountingApi.getContacts(
let contactsResponse = await xero.accountingApi.getContacts(
xeroConn.tenantId,
undefined,
`EmailAddress=="${email}"`
@ -173,15 +173,75 @@ export async function POST(req: NextRequest) {
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) {
console.log(" [WEBHOOK] Creating new contact");
const created = await xero.accountingApi.createContacts(
xeroConn.tenantId,
{ contacts: [{ name, emailAddress: email }] }
);
contact = created.body.contacts?.[0];
} else {
console.log("✅ [WEBHOOK] Found existing contact:", contact.contactID);
let attempt = 0;
const maxAttempts = 5;
while (attempt < maxAttempts && !contact) {
let contactName = name;
// 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) {