// Shared template placeholder substitution for bulk emails/WhatsApp messages and broadcasts. // Async because {{payment.link}} needs to create a live Yoco checkout session per recipient — // every other placeholder is a plain synchronous string replace. async function replacePlaceholders(str, ctx = {}) { if (!str) return str; let out = String(str) .replace(/\{\{\s*name\s*\}\}/g, ctx.name || '') .replace(/\{\{\s*event\.title\s*\}\}/g, ctx.eventTitle || '') .replace(/\{\{\s*event\.start\s*\}\}/g, ctx.eventStart || '') .replace(/\{\{\s*event\.(link|url)\s*\}\}/g, (ctx.eventLinkHtml || ctx.eventLink || '')) .replace(/\{\{\s*promo\.title\s*\}\}/g, ctx.promoTitle || '') .replace(/\{\{\s*promo\.(link|url)\s*\}\}/g, (ctx.promoLinkHtml || ctx.promoLink || '')) .replace(/\{\{\s*balance\s*\}\}/g, ctx.balanceFmt || ''); if (/\{\{\s*payment\.link\s*\}\}/.test(out) && typeof ctx.paymentLinkResolver === 'function') { let link = ''; try { link = (await ctx.paymentLinkResolver()) || ''; } catch (e) { try { console.warn('[placeholders] payment.link resolution failed:', e?.message || e); } catch {} } out = out.replace(/\{\{\s*payment\.link\s*\}\}/g, link); } else { out = out.replace(/\{\{\s*payment\.link\s*\}\}/g, ''); } return out; } module.exports = { replacePlaceholders };