Skip to content
// Accept both GoHighLevel outbound shapes and return one clean lead:
//  - "Custom Webhook" action: the body you define (recommended, see lesson Step 1)
//  - "Webhook" action: standard contact fields, your extra fields inside customData
const req = $input.first().json;
const b = req.body ?? {};
const cd = b.customData ?? {};
const pick = (...keys) => {
  for (const k of keys) {
    const v = cd[k] ?? b[k] ?? b.contact?.[k];
    if (v !== undefined && v !== null && String(v).trim() !== '') return String(v).trim();
  }
  return '';
};

const first = pick('first_name', 'firstName');
const last = pick('last_name', 'lastName');
const tags = [].concat(b.tags ?? cd.tags ?? []).flatMap((t) => String(t).split(',')).map((t) => t.trim()).filter(Boolean);

return [{
  json: {
    contact_id: pick('contact_id', 'contactId', 'id'),
    location_id: pick('location_id', 'locationId') || b.location?.id || '',
    name: pick('full_name', 'fullName', 'name') || [first, last].filter(Boolean).join(' '),
    first_name: first,
    email: pick('email').toLowerCase(),
    phone: pick('phone').replace(/[^\d+]/g, ''),
    source: pick('source', 'contact_source', 'lead_source').toLowerCase(),
    message: pick('message', 'notes', 'details', 'how_can_we_help').slice(0, 3000),
    company: pick('company_name', 'companyName', 'company'),
    website: pick('website'),
    tags,
    dry_run: req.query?.dry_run === 'true',
  },
}];