{
  "name": "Agent 4: Daily Digest & Sender — approve/send/resend emails",
  "description": null,
  "active": false,
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "30 10 * * 1-5"
            }
          ]
        }
      },
      "id": "d_sched",
      "name": "Daily 10:30 AM IST",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        -1408,
        -752
      ]
    },
    {
      "parameters": {},
      "id": "d_manual",
      "name": "Manual",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1408,
        -512
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "approval_status",
              "condition": "eq",
              "keyValue": "pending"
            },
            {
              "keyName": "bounced",
              "condition": "eq",
              "keyValue": "false"
            },
            {
              "keyName": "reply_received",
              "condition": "eq",
              "keyValue": "false"
            }
          ]
        }
      },
      "id": "d_fetch",
      "name": "Fetch Pending Drafts",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -288,
        -560
      ]
    },
    {
      "parameters": {
        "jsCode": "let statsHtml='';try{statsHtml=$('Build Ops Stats').first().json.stats_html||'';}catch(e){}\n\nlet items=$('Remove Duplicates').all().filter(i=>i.json.company||i.json.to_email);\nconst best={};\nfor(const i of items){const k=(i.json.company||i.json.to_email||'').toLowerCase().trim();\n  if(!best[k]||(i.json.quality_score||0)>(best[k].json.quality_score||0)) best[k]=i;}\nitems=Object.values(best);\nitems.sort((a,b)=>((b.json.quality_score||0)-(a.json.quality_score||0))||String(b.json.inserted_at||'').localeCompare(String(a.json.inserted_at||'')));\nconst totalDrafts=items.length;\nconst vDeliv=items.filter(i=>String(i.json.verify_result||'')==='deliverable').length;\nconst vUnknown=items.filter(i=>String(i.json.verify_result||'')==='unknown').length;\nconst moreCount=Math.max(0,totalDrafts-35);\nitems=items.slice(0,35);\n// De-dupe by id: \"Fetch Replies 24h\" runs once per upstream bounced item (17x fan-in),\n// which multiplied 6 real replies into 102. Also filter to genuinely recent replies in JS,\n// because the Supabase node's reply_date>yesterday filter is silently ignored.\nlet bounces=[]; try{\n  const rawB=$('Fetch Bounced Review').all().filter(i=>i.json.to_email||i.json.company);\n  const seenB=new Set();\n  bounces=rawB.filter(i=>{const k=(i.json.id||i.json.to_email||''); if(!k||seenB.has(k))return false; seenB.add(k); return true;});\n}catch(e){}\nlet replies=[]; try{\n  const rawR=$('Fetch Replies 24h').all().filter(i=>i.json.company||i.json.to_email||i.json.email);\n  const cutoff=new Date(Date.now()-2*86400000).toISOString().slice(0,10); // last ~2 days\n  const seenR=new Set();\n  replies=rawR.filter(i=>{\n    const d=i.json; const k=(d.id||d.email||d.company||'');\n    if(!k||seenR.has(k))return false; seenR.add(k);\n    return d.reply_date && String(d.reply_date).slice(0,10) >= cutoff;\n  });\n}catch(e){}\nif(!items.length && !bounces.length && !replies.length) return [{json:{skip:true,count:0,summary_html:'<p>Nothing to review today.</p>'}}];\nconst WH='https://your-n8n-instance.com/webhook';\nconst cards=items.map(i=>{\n const d=i.json; const id=d.id;\n const sendUrl=WH+'/yourbrand-send-one?log_id='+id;\n const rwUrl=WH+'/yourbrand-rewrite-one?log_id='+id;\n const edUrl=WH+'/yourbrand-edit-one?log_id='+id;\n const web=d.website?('<a href=\"'+d.website+'\">'+d.website+'</a>'):'';\n const li=d.linkedin?(' · <a href=\"'+d.linkedin+'\">LinkedIn</a>'):'';\n const score=d.quality_score?(' · <span style=\"color:#718096\">score '+d.quality_score+'/10</span>'):'';\n const pain=d.pain_points?('<p style=\"margin-top:8px;color:#718096;white-space:pre-line\"><strong>Pain points:</strong>\\n'+d.pain_points+'</p>'):'';\n const btn='display:inline-block;color:#fff;padding:8px 16px;border-radius:6px;text-decoration:none;font-weight:bold;margin-left:4px';\n return '<div style=\"border:1px solid #e2e8f0;border-radius:8px;padding:16px;margin:14px 0\">'+\n  '<table style=\"width:100%;font-size:13px\"><tr>'+\n  '<td><strong style=\"font-size:15px\">'+(d.company||'-')+'</strong> · '+(d.city||'')+score+'<br>'+web+li+'<br>'+\n  '<span style=\"color:#718096\">'+(d.founder_name||'')+' '+(d.to_email?('· <span style=\"'+(String(d.verify_result||'')==='deliverable'?'color:#1f7a1f;font-weight:bold':'color:#718096')+'\">'+d.to_email+(String(d.verify_result||'')==='deliverable'?' &#10003;':'')+'</span>'):'')+'</span></td>'+\n  '<td style=\"text-align:right;white-space:nowrap\">'+\n    '<a href=\"'+sendUrl+'\" style=\"'+btn+';background:#48bb78\">SEND</a>'+\n    '<a href=\"'+rwUrl+'\" style=\"'+btn+';background:#ed8936\">REWRITE</a>'+\n    '<a href=\"'+edUrl+'\" style=\"'+btn+';background:#805ad5\">EDIT</a>'+\n  '</td></tr></table>'+\n  '<p style=\"margin:8px 0 4px\"><strong>Subject:</strong> '+(d.email_subject||'')+'</p>'+\n  '<div style=\"background:#f7fafc;border:1px solid #edf2f7;border-radius:6px;padding:12px\">'+(d.email_body||'')+'</div>'+\n  pain+'</div>';\n}).join('');\nlet replyHtml='';\nif(replies.length){\n  const rows=replies.map(r=>{const d=r.json;return '<li style=\"margin:6px 0\"><strong>'+(d.company||'')+'</strong> — '+(d.to_email||d.email||'')+' <span style=\"color:#718096\">(replied '+(d.reply_date||'')+')</span></li>';}).join('');\n  replyHtml='<div style=\"border:1px solid #c6f6d5;background:#f0fff4;border-radius:8px;padding:16px;margin:18px 0\"><h3 style=\"margin:0 0 8px;color:#22543d\">'+replies.length+' repl'+(replies.length>1?'ies':'y')+' received recently — follow-ups paused</h3><ul style=\"margin:0;padding-left:18px\">'+rows+'</ul></div>';\n}\nlet bounceHtml='';\nif(bounces.length){\n  const rows=bounces.map(b=>{const d=b.json;const alt=d.alt_email_found?(' → new: <strong>'+d.alt_email_found+'</strong>'):'';const rs=d.alt_email_found?(' <a href=\"'+WH+'/yourbrand-resend-alt?log_id='+d.id+'\" style=\"color:#fff;background:#3182ce;padding:4px 12px;border-radius:5px;text-decoration:none;font-size:12px;font-weight:bold\">RESEND</a>'):'';return '<li style=\"margin:8px 0\"><strong>'+(d.company||'')+'</strong> — bounced '+(d.to_email||'')+alt+rs+'</li>';}).join('');\n  const resendAllUrl=WH+'/yourbrand-resend-all-bounced';const resendAllBtn=bounces.some(b=>b.json.alt_email_found)?(' <a href=\"'+resendAllUrl+'\" style=\"color:#fff;background:#742a2a;padding:5px 14px;border-radius:5px;text-decoration:none;font-size:12px;font-weight:bold\">RESEND ALL</a>'):'';bounceHtml='<div style=\"border:1px solid #fed7d7;background:#fff5f5;border-radius:8px;padding:16px;margin:18px 0\"><h3 style=\"margin:0 0 8px;color:#742a2a\">'+bounces.length+' bounce(s) need a new address — review'+resendAllBtn+'</h3><ul style=\"margin:0;padding-left:18px\">'+rows+'</ul></div>';\n}\nconst allUrl=WH+'/yourbrand-send-all';\nconst head=items.length?('<h2 style=\"color:#2d3748\">Daily Outreach Digest — top '+items.length+' of '+totalDrafts+' pending</h2><p>For each lead: <b>SEND</b>, <b>REWRITE</b>, <b>EDIT</b>. Or <b>APPROVE ALL</b> below.</p>'+(moreCount?('<p style=\"color:#b7791f\"><b>'+moreCount+' more drafts queued</b> — they surface as the queue drains; drafts older than 21 days auto-expire and get re-written fresh later.</p>'):'')):'<h2 style=\"color:#2d3748\">Daily Outreach Digest</h2>';\nconst draftSection=items.length?(cards+'<div style=\"text-align:center;margin:30px 0\"><a href=\"'+allUrl+'\" style=\"background:#3182ce;color:#fff;padding:14px 36px;border-radius:8px;text-decoration:none;font-weight:bold;font-size:16px\">APPROVE ALL &amp; SEND ('+Math.min(items.length+(moreCount||0),35)+' drafts, oldest first)</a></div>'):'';\nconst verifyBanner=(vDeliv+vUnknown)?('<div style=\"border:1px solid #c6f6d5;background:#f0fff4;border-radius:8px;padding:12px 16px;margin:14px 0\"><span style=\"color:#1f7a1f;font-size:17px;font-weight:bold\">'+vDeliv+' verified valid email'+(vDeliv===1?'':'s')+' ready to send &#10003;</span>'+(vUnknown?('<span style=\"color:#b7791f\"> &middot; '+vUnknown+' catch-all (unconfirmed but sendable)</span>'):'')+'</div>'):'';\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:880px;margin:auto;padding:20px\">'+head+verifyBanner+statsHtml+replyHtml+bounceHtml+draftSection+'<p style=\"color:#a0aec0;font-size:12px\">Meraku Outreach · drafts written twice daily · digest 10:30 AM IST</p></body></html>';\nreturn [{json:{count:items.length,summary_html:html}}];\n"
      },
      "id": "d_digest",
      "name": "Build Master Digest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1504,
        -752
      ]
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "=[ACTION] Daily Outreach Digest — {{ $json.count }} drafts ready",
        "message": "={{ $json.summary_html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "d_gmail",
      "name": "Gmail — Daily Digest",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1728,
        -752
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "path": "yourbrand-send-one",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "w_one",
      "name": "Send-One Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        432
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{log_id:q.log_id||'', confirmed:q.confirm==='1'}}];"
      },
      "id": "w_one_parse",
      "name": "Parse log_id",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        432
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        }
      },
      "id": "w_one_get",
      "name": "Get Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -736,
        336
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst SENDER_B_WEIGHT=25;\nconst __sh=(s)=>{s=String(s||'');let h=0;for(let i=0;i<s.length;i++){h=(h*31+s.charCodeAt(i))>>>0;}return h;};const ABSTRACT_KEYS=[\"YOUR_ABSTRACTAPI_KEY_1\",\"YOUR_ABSTRACTAPI_KEY_2\",\"YOUR_ABSTRACTAPI_KEY\",\"YOUR_ABSTRACTAPI_KEY\"];\nconst __sd=$getWorkflowStaticData('global');\nif(typeof __sd.abstractExhausted!=='object'||!__sd.abstractExhausted) __sd.abstractExhausted={};\nif(typeof __sd.abstractCache!=='object'||!__sd.abstractCache) __sd.abstractCache={};\nconst __sleep=(ms)=>new Promise(r=>setTimeout(r,ms));\nconst verifyEmail=async(email)=>{\n  email=String(email||'').toLowerCase().trim();\n  if(!email||!email.includes('@')) return 'undeliverable';\n  const cached=__sd.abstractCache[email];\n  if(cached && Date.now()-cached.ts < 30*24*3600*1000) return cached.status;\n  const KEY_COOLDOWN=24*3600*1000;\n  for(const key of ABSTRACT_KEYS){\n    const ex=__sd.abstractExhausted[key];\n    if(ex && Date.now()-ex<KEY_COOLDOWN) continue;\n    let attempts=0;\n    while(attempts<5){\n      attempts++;\n      try{\n        await __sleep(1400+Math.floor(Math.random()*800));\n        const res=await this.helpers.httpRequest({method:'GET',\n          url:'https://emailreputation.abstractapi.com/v1/?api_key='+key+'&email='+encodeURIComponent(email),\n          json:true, returnFullResponse:true, ignoreHttpStatusErrors:true, timeout:20000});\n        const code=Number(res.statusCode||0);\n        if(code===422){\n          const msg422=JSON.stringify(res.body||'').toLowerCase();\n          if(msg422.includes('quota')){ __sd.abstractExhausted[key]=Date.now(); break; }\n          return 'error';\n        }\n        if(code===429){\n          const msg=JSON.stringify(res.body||'').toLowerCase();\n          const isQuota = msg.includes('quota') && !msg.includes('per second');\n          if(isQuota){ __sd.abstractExhausted[key]=Date.now(); break; }\n          if(attempts<5){ await __sleep(1200*attempts+500); continue; }\n          return 'error';\n        }\n        if(code===401||code===402||code===403){ __sd.abstractExhausted[key]=Date.now(); break; }\n        if(code<200||code>=300) return 'error';\n        const status=String((res.body&&res.body.email_deliverability&&res.body.email_deliverability.status)||'unknown').toLowerCase();\n        const final=(status==='deliverable')?'deliverable':(status==='undeliverable'?'undeliverable':'unknown');\n        __sd.abstractCache[email]={status:final,ts:Date.now()};\n        return final;\n      }catch(e){ return 'error'; }\n    }\n  }\n  return 'quota_exhausted';\n};\nconst NAME_PH=/\\{\\{[^}]*\\}\\}|\\[[A-Za-z _]{2,30}\\]/g;\nconst fixPH=(d,s)=>{const fn=(d.founder_name||'').trim().replace(/^(dr|mr|mrs|ms|prof|shri|smt)\\.?\\s+/i,'');const f=(fn&&/^[A-Za-z][A-Za-z.'-]+$/.test(fn.split(/\\s+/)[0]))?fn.split(/\\s+/)[0]:'there';return String(s||'').replace(NAME_PH,f);};\n\nconst items=$input.all();\nconst out=[];\nfor(const it of items){const r=it.json;const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\n d.email_subject=fixPH(d,d.email_subject);d.email_body=fixPH(d,d.email_body);\n d.verify_result=await verifyEmail(d.to_email);\n d.sender_b=(__sh(String(d.prospect_id||d.id))%100)<SENDER_B_WEIGHT;\n out.push({json:{...d, today:new Date().toISOString().slice(0,10)}});}\nreturn out;\n"
      },
      "id": "w_one_today",
      "name": "Stamp Today",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -512,
        336
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.to_email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "w_one_send",
      "name": "Send Prospect Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -64,
        48
      ],
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $('Stamp Today').item.json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "approval_status",
              "fieldValue": "approved"
            },
            {
              "fieldId": "sent_date",
              "fieldValue": "={{ $('Stamp Today').item.json.today }}"
            },
            {
              "fieldId": "gmail_message_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "gmail_thread_id",
              "fieldValue": "={{ $json.threadId }}"
            }
          ]
        }
      },
      "id": "w_one_mark",
      "name": "Mark Sent",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        160,
        -144
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "Email sent.",
        "options": {}
      },
      "id": "w_one_resp",
      "name": "Resp One",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        384,
        -144
      ]
    },
    {
      "parameters": {
        "path": "yourbrand-send-all",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "w_all",
      "name": "Send-All Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        1808
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "Sending all drafts now with 1-3 min gaps. You can close this tab.",
        "options": {}
      },
      "id": "w_all_resp",
      "name": "Resp All",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -736,
        1904
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "limit": 35,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "approval_status",
              "condition": "eq",
              "keyValue": "pending"
            },
            {
              "keyName": "bounced",
              "condition": "eq",
              "keyValue": "false"
            },
            {
              "keyName": "reply_received",
              "condition": "eq",
              "keyValue": "false"
            }
          ]
        }
      },
      "id": "w_all_fetch",
      "name": "Fetch All Pending",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -512,
        1904
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "w_all_loop",
      "name": "Loop Drafts",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -288,
        1904
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst SENDER_B_WEIGHT=25;\nconst __sh=(s)=>{s=String(s||'');let h=0;for(let i=0;i<s.length;i++){h=(h*31+s.charCodeAt(i))>>>0;}return h;};const ABSTRACT_KEYS=[\"YOUR_ABSTRACTAPI_KEY_1\",\"YOUR_ABSTRACTAPI_KEY_2\",\"YOUR_ABSTRACTAPI_KEY\",\"YOUR_ABSTRACTAPI_KEY\"];\nconst __sd=$getWorkflowStaticData('global');\nif(typeof __sd.abstractExhausted!=='object'||!__sd.abstractExhausted) __sd.abstractExhausted={};\nif(typeof __sd.abstractCache!=='object'||!__sd.abstractCache) __sd.abstractCache={};\nconst __sleep=(ms)=>new Promise(r=>setTimeout(r,ms));\nconst verifyEmail=async(email)=>{\n  email=String(email||'').toLowerCase().trim();\n  if(!email||!email.includes('@')) return 'undeliverable';\n  const cached=__sd.abstractCache[email];\n  if(cached && Date.now()-cached.ts < 30*24*3600*1000) return cached.status;\n  const KEY_COOLDOWN=24*3600*1000;\n  for(const key of ABSTRACT_KEYS){\n    const ex=__sd.abstractExhausted[key];\n    if(ex && Date.now()-ex<KEY_COOLDOWN) continue;\n    let attempts=0;\n    while(attempts<5){\n      attempts++;\n      try{\n        await __sleep(1400+Math.floor(Math.random()*800));\n        const res=await this.helpers.httpRequest({method:'GET',\n          url:'https://emailreputation.abstractapi.com/v1/?api_key='+key+'&email='+encodeURIComponent(email),\n          json:true, returnFullResponse:true, ignoreHttpStatusErrors:true, timeout:20000});\n        const code=Number(res.statusCode||0);\n        if(code===422){\n          const msg422=JSON.stringify(res.body||'').toLowerCase();\n          if(msg422.includes('quota')){ __sd.abstractExhausted[key]=Date.now(); break; }\n          return 'error';\n        }\n        if(code===429){\n          const msg=JSON.stringify(res.body||'').toLowerCase();\n          const isQuota = msg.includes('quota') && !msg.includes('per second');\n          if(isQuota){ __sd.abstractExhausted[key]=Date.now(); break; }\n          if(attempts<5){ await __sleep(1200*attempts+500); continue; }\n          return 'error';\n        }\n        if(code===401||code===402||code===403){ __sd.abstractExhausted[key]=Date.now(); break; }\n        if(code<200||code>=300) return 'error';\n        const status=String((res.body&&res.body.email_deliverability&&res.body.email_deliverability.status)||'unknown').toLowerCase();\n        const final=(status==='deliverable')?'deliverable':(status==='undeliverable'?'undeliverable':'unknown');\n        __sd.abstractCache[email]={status:final,ts:Date.now()};\n        return final;\n      }catch(e){ return 'error'; }\n    }\n  }\n  return 'quota_exhausted';\n};\nconst NAME_PH=/\\{\\{[^}]*\\}\\}|\\[[A-Za-z _]{2,30}\\]/g;\nconst fixPH=(d,s)=>{const fn=(d.founder_name||'').trim().replace(/^(dr|mr|mrs|ms|prof|shri|smt)\\.?\\s+/i,'');const f=(fn&&/^[A-Za-z][A-Za-z.'-]+$/.test(fn.split(/\\s+/)[0]))?fn.split(/\\s+/)[0]:'there';return String(s||'').replace(NAME_PH,f);};\n\nconst PH=/\\{\\{[^}]*\\}\\}|\\[[A-Za-z _]{2,30}\\]/;\nconst pre=$input.all()\n .filter(i=>{const j=i.json||{};return j.id && j.approval_status==='pending' && !j.sent_date && !j.bounced && !j.reply_received;})\n .map(i=>{const j={...i.json};j.email_subject=fixPH(j,j.email_subject);j.email_body=fixPH(j,j.email_body);\n   return {json:{...j,today:new Date().toISOString().slice(0,10)}};})\n .filter(i=>!PH.test((i.json.email_subject||'')+(i.json.email_body||'')));\nfor(const i of pre){ i.json.verify_result=await verifyEmail(i.json.to_email); i.json.sender_b=(__sh(String(i.json.prospect_id||i.json.id))%100)<SENDER_B_WEIGHT; }\nreturn pre;\n"
      },
      "id": "w_all_today",
      "name": "Stamp Today All",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -64,
        1160
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.to_email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "w_all_send",
      "name": "Send Each",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        384,
        1088
      ],
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $('Stamp Today All').item.json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "approval_status",
              "fieldValue": "approved"
            },
            {
              "fieldId": "sent_date",
              "fieldValue": "={{ $('Stamp Today All').item.json.today }}"
            },
            {
              "fieldId": "gmail_message_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "gmail_thread_id",
              "fieldValue": "={{ $json.threadId }}"
            }
          ]
        }
      },
      "id": "w_all_mark",
      "name": "Mark Each Sent",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        896
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "amount": "={{ Math.floor(Math.random()*3)+1 }}",
        "unit": "minutes"
      },
      "id": "w_all_wait",
      "name": "Random 1-3 min",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        832,
        992
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst items=$input.all();\nconst norm=s=>(s||'').toLowerCase().trim();\nconst groups={};\nfor(const it of items){const k=norm(it.json.company||it.json.to_email);(groups[k]=groups[k]||[]).push(it);}\nconst keep=[]; const delIds=[];\nfor(const k in groups){\n  const g=groups[k].sort((a,b)=>(b.json.quality_score||0)-(a.json.quality_score||0));\n  keep.push(g[0]);\n  for(let i=1;i<g.length;i++) delIds.push(g[i].json.id);\n}\nreturn keep.map(it => ({ json: { ...it.json, _delete_ids: delIds } }));\n"
      },
      "id": "d_dedup",
      "name": "Remove Duplicates",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        384,
        -752
      ]
    },
    {
      "parameters": {
        "path": "yourbrand-edit-one",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "ed_wh",
      "name": "Edit Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        2352
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{log_id:q.log_id||''}}];"
      },
      "id": "ed_parse",
      "name": "Parse Edit log_id",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        2352
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        }
      },
      "id": "ed_get",
      "name": "Get Edit Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -960,
        2352
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst r=$input.all()[0].json; const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\nconst esc=s=>(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');\nconst html='<html><body style=\"font-family:Arial;max-width:720px;margin:auto;padding:24px\">'+\n '<h2>Edit email — '+(d.company||'')+'</h2>'+\n '<form method=\"POST\" action=\"https://your-n8n-instance.com/webhook/yourbrand-edit-save\">'+\n '<input type=\"hidden\" name=\"log_id\" value=\"'+(d.id||'')+'\">'+\n '<p><b>Subject</b><br><input name=\"subject\" style=\"width:100%;padding:8px\" value=\"'+esc(d.email_subject).replace(/\"/g,'&quot;')+'\"></p>'+\n '<p><b>Body (HTML)</b><br><textarea name=\"body\" rows=\"22\" style=\"width:100%;padding:8px;font-family:monospace\">'+esc(d.email_body)+'</textarea></p>'+\n '<button type=\"submit\" style=\"background:#3182ce;color:#fff;padding:12px 30px;border:none;border-radius:6px;font-size:15px;font-weight:bold\">Save changes</button>'+\n '</form></body></html>';\nreturn [{json:{html}}];\n"
      },
      "id": "ed_form",
      "name": "Build Edit Form",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        2352
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "ed_resp",
      "name": "Serve Form",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        2352
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "yourbrand-edit-save",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "es_wh",
      "name": "Edit Save Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        3920
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst b=$input.all()[0].json.body||{};\nreturn [{json:{log_id:b.log_id||'', subject:b.subject||'', body:b.body||''}}];\n"
      },
      "id": "es_parse",
      "name": "Parse Saved Edit",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        3920
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_subject",
              "fieldValue": "={{ $json.subject }}"
            },
            {
              "fieldId": "email_body",
              "fieldValue": "={{ $json.body }}"
            }
          ]
        }
      },
      "id": "es_update",
      "name": "Save Edited Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -960,
        3920
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "Saved. Your edited email is updated. You can close this tab.",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "es_resp",
      "name": "Saved Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -736,
        3824
      ]
    },
    {
      "parameters": {
        "path": "yourbrand-rewrite-one",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "rw_wh",
      "name": "Rewrite Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        2128
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{log_id:q.log_id||''}}];"
      },
      "id": "rw_parse",
      "name": "Parse RW log_id",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        2128
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        }
      },
      "id": "rw_get",
      "name": "Get RW Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -960,
        2128
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst r=$input.all()[0].json; const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\nconst esc=s=>(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');\nconst html='<html><body style=\"font-family:Arial;max-width:720px;margin:auto;padding:24px\">'+\n '<h2 style=\"color:#2d3748\">Rewrite email — '+(d.company||'')+'</h2>'+\n '<form method=\"POST\" action=\"https://your-n8n-instance.com/webhook/yourbrand-rewrite-apply\">'+\n '<input type=\"hidden\" name=\"log_id\" value=\"'+(d.id||'')+'\">'+\n '<p style=\"font-weight:bold\">What changes do you want?</p>'+\n '<textarea name=\"instructions\" rows=\"5\" style=\"width:100%;padding:10px;font-size:14px\" placeholder=\"e.g. Make it shorter and more casual; mention their new Dubai branch; lead with the AI Overview angle; remove the bullet list...\"></textarea>'+\n '<button type=\"submit\" style=\"background:#ed8936;color:#fff;padding:12px 30px;border:none;border-radius:6px;font-size:15px;font-weight:bold;margin-top:10px\">Rewrite with these changes</button>'+\n '</form>'+\n '<h3 style=\"color:#718096;margin-top:24px\">Current email</h3>'+\n '<p><b>Subject:</b> '+esc(d.email_subject)+'</p>'+\n '<div style=\"background:#f7fafc;border:1px solid #e2e8f0;border-radius:6px;padding:14px\">'+(d.email_body||'')+'</div>'+\n '</body></html>';\nreturn [{json:{html}}];\n"
      },
      "id": "rw_form",
      "name": "Build RW Form",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        2128
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "rw_serve",
      "name": "Serve RW Form",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        2128
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "yourbrand-rewrite-apply",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "rwa_wh",
      "name": "Rewrite Apply Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        2672
      ]
    },
    {
      "parameters": {
        "jsCode": "const b=$input.all()[0].json.body||{};return [{json:{log_id:b.log_id||'', instructions:b.instructions||''}}];"
      },
      "id": "rwa_parse",
      "name": "Parse RW Apply",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        2672
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        }
      },
      "id": "rwa_get",
      "name": "Get RW Apply Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -960,
        2672
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst r=$input.all()[0].json; const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\nconst instr=$('Parse RW Apply').first().json.instructions||'';\nconst name=d.founder_name||''; const greet=name?('Dear '+name+','):'Hello,';\nconst prompt=`You are Manvendra Singh, founder of Meraku Media. Rewrite the outreach email below, APPLYING the user's requested changes.\nUSER'S REQUESTED CHANGES (top priority): ${instr}\nUnless the changes say otherwise, keep this proven structure & warm professional tone:\n\"${greet}\" (full name with title if present; never a placeholder; never \"[Company] Team\")\n[warm 1-2 line opener specific to ${d.company}]\n\"I'm Manvendra, and I recently led the digital marketing & SEO for a premium senior living brand that we scaled from the ground up. Within a few months, we achieved:\"\n5 bullets: #1 ranking on Google for key senior & assisted living keywords; 380% increase in organic traffic; 3x growth in high-intent inquiries; Better cost efficiency through optimized Google Ads; Branded video content that helped build strong trust with families\n\"Now that I've transitioned out of that project, I'm exploring opportunities to partner with another premium brand in this space — and ${d.company} immediately stood out to me.\" + ONE concise line on the biggest gap.\n\"Would you be open to a quick 15-20 minute call this week or early next to explore how I could help ${d.company} achieve similar or better results?\"\n\"Looking forward to hearing from you.\" + signoff.\nCurrent email: Subject: ${d.email_subject} | Body: ${d.email_body}\nRULES: apply the user's changes faithfully; never name a past client (say \"a premium senior living brand\"); no emojis.\nReturn ONLY JSON: {\"subject\":\"...\",\"body_html\":\"...\"}`;\nreturn [{json:{prompt, log_id:d.id}}];\n"
      },
      "id": "rw_build",
      "name": "Build RW Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        2672
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://moviesbar1-resource.openai.azure.com/openai/v1/chat/completions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ {\"model\":\"gpt-5.4-2\",\"messages\":[{\"role\":\"user\",\"content\":$json.prompt}],\"max_completion_tokens\":4096} }}",
        "options": {
          "timeout": 180000
        }
      },
      "id": "rw_kimi",
      "name": "GPT — RW",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -512,
        2672
      ],
      "retryOnFail": true,
      "maxTries": 2
    },
    {
      "parameters": {
        "jsCode": "\nconst logId=$('Build RW Prompt').all()[0].json.log_id;\nlet c=$input.all()[0].json.choices?.[0]?.message?.content||'{}';\nconst f=c.match(/```(?:json)?\\s*([\\s\\S]*?)```/);if(f)c=f[1].trim();\nconst jm=c.match(/\\{[\\s\\S]*\\}/);if(jm)c=jm[0];\nlet p={};try{p=JSON.parse(c);}catch(e){}\nreturn [{json:{log_id:logId, subject:(p.subject||'').replace(/[\\u{1F000}-\\u{1FFFF}\\u{2600}-\\u{27BF}]/gu,'').trim(), body_html:p.body_html||p.body||c}}];\n"
      },
      "id": "rw_pparse",
      "name": "Parse RW",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -288,
        2672
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_subject",
              "fieldValue": "={{ $json.subject }}"
            },
            {
              "fieldId": "email_body",
              "fieldValue": "={{ $json.body_html }}"
            }
          ]
        }
      },
      "id": "rw_update",
      "name": "Update RW Log",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -64,
        2672
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "=Rewritten and saved:<br><br><b>{{ $json.subject }}</b><br><br>{{ $json.body_html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "rw_done",
      "name": "Respond RW",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        160,
        2576
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "bounced",
              "condition": "eq",
              "keyValue": "true"
            },
            {
              "keyName": "alt_email_found",
              "condition": "neq"
            }
          ]
        }
      },
      "id": "fetch_bounced",
      "name": "Fetch Bounced Review",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        1056,
        -752
      ],
      "alwaysOutputData": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "reply_received",
              "condition": "eq",
              "keyValue": "true"
            },
            {
              "keyName": "reply_date",
              "condition": "gt",
              "keyValue": "={{ new Date(Date.now() - 86400000).toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "id": "fetch_replies",
      "name": "Fetch Replies 24h",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        1280,
        -752
      ],
      "alwaysOutputData": true,
      "executeOnce": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "path": "yourbrand-resend-alt",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "rs_wh",
      "name": "Resend-Alt Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        3504
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{log_id:q.log_id||'', confirmed:q.confirm==='1'}}];"
      },
      "id": "rs_parse",
      "name": "Parse Resend log_id",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        3504
      ]
    },
    {
      "parameters": {
        "operation": "get",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.log_id }}"
            }
          ]
        }
      },
      "id": "rs_get",
      "name": "Get Resend Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -736,
        3600
      ]
    },
    {
      "parameters": {
        "jsCode": "const ABSTRACT_KEYS=['YOUR_ABSTRACTAPI_KEY_1'];\nconst __sd=$getWorkflowStaticData('global');\nif(typeof __sd.abstractExhausted!=='object'||!__sd.abstractExhausted) __sd.abstractExhausted={};\nif(typeof __sd.abstractCache!=='object'||!__sd.abstractCache) __sd.abstractCache={};\nconst __sleep=(ms)=>new Promise(r=>setTimeout(r,ms));\nconst verifyEmail=async(email)=>{\n  email=String(email||'').toLowerCase().trim();\n  if(!email||!email.includes('@')) return 'undeliverable';\n  const cached=__sd.abstractCache[email];\n  if(cached && Date.now()-cached.ts < 30*24*3600*1000) return cached.status;\n  const KEY_COOLDOWN=24*3600*1000;\n  for(const key of ABSTRACT_KEYS){\n    const ex=__sd.abstractExhausted[key];\n    if(ex && Date.now()-ex<KEY_COOLDOWN) continue;\n    let attempts=0;\n    while(attempts<5){\n      attempts++;\n      try{\n        await __sleep(1400+Math.floor(Math.random()*800));\n        const res=await this.helpers.httpRequest({method:'GET',\n          url:'https://emailreputation.abstractapi.com/v1/?api_key='+key+'&email='+encodeURIComponent(email),\n          json:true, returnFullResponse:true, ignoreHttpStatusErrors:true, timeout:20000});\n        const code=Number(res.statusCode||0);\n        if(code===422){\n          const msg422=JSON.stringify(res.body||'').toLowerCase();\n          if(msg422.includes('quota')){ __sd.abstractExhausted[key]=Date.now(); break; }\n          return 'error';\n        }\n        if(code===429){\n          const msg=JSON.stringify(res.body||'').toLowerCase();\n          const isQuota = msg.includes('quota') && !msg.includes('per second');\n          if(isQuota){ __sd.abstractExhausted[key]=Date.now(); break; }\n          if(attempts<5){ await __sleep(1200*attempts+500); continue; }\n          return 'error';\n        }\n        if(code===401||code===402||code===403){ __sd.abstractExhausted[key]=Date.now(); break; }\n        if(code<200||code>=300) return 'error';\n        const status=String((res.body&&res.body.email_deliverability&&res.body.email_deliverability.status)||'unknown').toLowerCase();\n        const final=(status==='deliverable')?'deliverable':(status==='undeliverable'?'undeliverable':'unknown');\n        __sd.abstractCache[email]={status:final,ts:Date.now()};\n        return final;\n      }catch(e){ return 'error'; }\n    }\n  }\n  return 'quota_exhausted';\n};\nconst NAME_PH=/\\{\\{[^}]*\\}\\}|\\[[A-Za-z _]{2,30}\\]/g;\nconst fixPH=(d,s)=>{const fn=(d.founder_name||'').trim().replace(/^(dr|mr|mrs|ms|prof|shri|smt)\\.?\\s+/i,'');const f=(fn&&/^[A-Za-z][A-Za-z.'-]+$/.test(fn.split(/\\s+/)[0]))?fn.split(/\\s+/)[0]:'there';return String(s||'').replace(NAME_PH,f);};\n\nconst items=$input.all();const out=[];\nfor(const it of items){const r=it.json;const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\n d.email_subject=fixPH(d,d.email_subject);d.email_body=fixPH(d,d.email_body);\n const target=(d.alt_email_found||d.to_email);\n d.verify_result=await verifyEmail(target);\n out.push({json:{...d,To_Email:target,today:new Date().toISOString().slice(0,10)}});}\nreturn out;\n"
      },
      "id": "rs_prep",
      "name": "Prep Resend",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -512,
        3600
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.To_Email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "rs_send",
      "name": "Send Resend",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -288,
        3600
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $('Prep Resend').item.json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "to_email",
              "fieldValue": "={{ $('Prep Resend').item.json.To_Email }}"
            },
            {
              "fieldId": "bounced",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "approval_status",
              "fieldValue": "approved"
            },
            {
              "fieldId": "sent_date",
              "fieldValue": "={{ $('Prep Resend').item.json.today }}"
            },
            {
              "fieldId": "gmail_message_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "gmail_thread_id",
              "fieldValue": "={{ $json.threadId }}"
            }
          ]
        }
      },
      "id": "rs_mark",
      "name": "Mark Resent",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -64,
        3600
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "Resent to alternative address.",
        "options": {}
      },
      "id": "rs_resp",
      "name": "Resp Resend",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        160,
        3600
      ]
    },
    {
      "parameters": {
        "path": "yourbrand-resend-all-bounced",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "rab_wh",
      "name": "Resend-All Bounced Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1408,
        3088
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "Resending all bounced leads to their alternative address now with 1-3 min gaps.",
        "options": {}
      },
      "id": "rab_resp",
      "name": "Resp Resend All",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -736,
        3184
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "bounced",
              "condition": "eq",
              "keyValue": "true"
            },
            {
              "keyName": "alt_email_found",
              "condition": "neq"
            }
          ]
        }
      },
      "id": "rab_fetch",
      "name": "Fetch All Bounced w/ Alt",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -512,
        3184
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "rab_loop",
      "name": "Loop Bounced",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -288,
        3184
      ]
    },
    {
      "parameters": {
        "jsCode": "const ABSTRACT_KEYS=['YOUR_ABSTRACTAPI_KEY_1'];\nconst __sd=$getWorkflowStaticData('global');\nif(typeof __sd.abstractExhausted!=='object'||!__sd.abstractExhausted) __sd.abstractExhausted={};\nif(typeof __sd.abstractCache!=='object'||!__sd.abstractCache) __sd.abstractCache={};\nconst __sleep=(ms)=>new Promise(r=>setTimeout(r,ms));\nconst verifyEmail=async(email)=>{\n  email=String(email||'').toLowerCase().trim();\n  if(!email||!email.includes('@')) return 'undeliverable';\n  const cached=__sd.abstractCache[email];\n  if(cached && Date.now()-cached.ts < 30*24*3600*1000) return cached.status;\n  const KEY_COOLDOWN=24*3600*1000;\n  for(const key of ABSTRACT_KEYS){\n    const ex=__sd.abstractExhausted[key];\n    if(ex && Date.now()-ex<KEY_COOLDOWN) continue;\n    let attempts=0;\n    while(attempts<5){\n      attempts++;\n      try{\n        await __sleep(1400+Math.floor(Math.random()*800));\n        const res=await this.helpers.httpRequest({method:'GET',\n          url:'https://emailreputation.abstractapi.com/v1/?api_key='+key+'&email='+encodeURIComponent(email),\n          json:true, returnFullResponse:true, ignoreHttpStatusErrors:true, timeout:20000});\n        const code=Number(res.statusCode||0);\n        if(code===422){\n          const msg422=JSON.stringify(res.body||'').toLowerCase();\n          if(msg422.includes('quota')){ __sd.abstractExhausted[key]=Date.now(); break; }\n          return 'error';\n        }\n        if(code===429){\n          const msg=JSON.stringify(res.body||'').toLowerCase();\n          const isQuota = msg.includes('quota') && !msg.includes('per second');\n          if(isQuota){ __sd.abstractExhausted[key]=Date.now(); break; }\n          if(attempts<5){ await __sleep(1200*attempts+500); continue; }\n          return 'error';\n        }\n        if(code===401||code===402||code===403){ __sd.abstractExhausted[key]=Date.now(); break; }\n        if(code<200||code>=300) return 'error';\n        const status=String((res.body&&res.body.email_deliverability&&res.body.email_deliverability.status)||'unknown').toLowerCase();\n        const final=(status==='deliverable')?'deliverable':(status==='undeliverable'?'undeliverable':'unknown');\n        __sd.abstractCache[email]={status:final,ts:Date.now()};\n        return final;\n      }catch(e){ return 'error'; }\n    }\n  }\n  return 'quota_exhausted';\n};\nconst NAME_PH=/\\{\\{[^}]*\\}\\}|\\[[A-Za-z _]{2,30}\\]/g;\nconst fixPH=(d,s)=>{const fn=(d.founder_name||'').trim().replace(/^(dr|mr|mrs|ms|prof|shri|smt)\\.?\\s+/i,'');const f=(fn&&/^[A-Za-z][A-Za-z.'-]+$/.test(fn.split(/\\s+/)[0]))?fn.split(/\\s+/)[0]:'there';return String(s||'').replace(NAME_PH,f);};\n\nconst items=$input.all();const out=[];\nfor(const it of items){const r=it.json;const d=(r.fields&&r.id)?{...r.fields,id:r.id}:r;\n d.email_subject=fixPH(d,d.email_subject);d.email_body=fixPH(d,d.email_body);\n const target=(d.alt_email_found||d.to_email);\n d.verify_result=await verifyEmail(target);\n out.push({json:{...d,To_Email:target,today:new Date().toISOString().slice(0,10)}});}\nreturn out;\n"
      },
      "id": "rab_prep",
      "name": "Prep Resend Each",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -64,
        3112
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.To_Email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "rab_send",
      "name": "Send Resend Each",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        160,
        3112
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $('Prep Resend Each').item.json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "to_email",
              "fieldValue": "={{ $('Prep Resend Each').item.json.To_Email }}"
            },
            {
              "fieldId": "bounced",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "approval_status",
              "fieldValue": "approved"
            },
            {
              "fieldId": "sent_date",
              "fieldValue": "={{ $('Prep Resend Each').item.json.today }}"
            },
            {
              "fieldId": "gmail_message_id",
              "fieldValue": "={{ $json.id }}"
            },
            {
              "fieldId": "gmail_thread_id",
              "fieldValue": "={{ $json.threadId }}"
            }
          ]
        }
      },
      "id": "rab_mark",
      "name": "Mark Resent Each",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        384,
        3112
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "amount": "={{ Math.floor(Math.random()*3)+1 }}",
        "unit": "minutes"
      },
      "id": "rab_wait",
      "name": "Random 1-3 min RAB",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        608,
        3184
      ]
    },
    {
      "parameters": {
        "operation": "delete",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "in",
              "keyValue": "={{ $json._delete_ids && $json._delete_ids.length ? '(' + $json._delete_ids.join(',') + ')' : '(00000000-0000-0000-0000-000000000000)' }}"
            }
          ]
        }
      },
      "id": "dd_del",
      "name": "Delete Duplicate Drafts",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        -752
      ],
      "alwaysOutputData": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { ok: true } }];"
      },
      "id": "dd_cont",
      "name": "Continue After Delete",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        832,
        -752
      ]
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true,
        "matchType": "allFilters",
        "filters": {
          "conditions": [
            {
              "keyName": "approval_status",
              "condition": "eq",
              "keyValue": "pending"
            },
            {
              "keyName": "inserted_at",
              "condition": "lt",
              "keyValue": "={{ new Date(Date.now()-21*86400000).toISOString() }}"
            }
          ]
        }
      },
      "id": "exp_fetch",
      "name": "Fetch Stale Pending",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -1184,
        -800
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "return $input.all().filter(i=>i.json&&i.json.id).map(i=>({json:{id:i.json.id,prospect_id:i.json.prospect_id||''}}));"
      },
      "id": "exp_prep",
      "name": "Prep Expiry",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -960,
        -800
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "approval_status",
              "fieldValue": "expired"
            }
          ]
        }
      },
      "id": "exp_mark",
      "name": "Expire Stale Draft",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -736,
        -800
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $('Prep Expiry').item.json.prospect_id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "status",
              "fieldValue": "enriched"
            }
          ]
        }
      },
      "id": "exp_reset",
      "name": "Reset Prospect (expired)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -512,
        -800
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.confirmed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cf1_if",
      "name": "Confirmed One?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -960,
        432
      ]
    },
    {
      "parameters": {
        "jsCode": "const url='https://your-n8n-instance.com/webhook/yourbrand-send-one?log_id='+$json.log_id+'&confirm=1';\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:480px;margin:40px auto;text-align:center\">'+\n'<h2 style=\"color:#2d3748\">Send this outreach email?</h2><p style=\"color:#4a5568\">This will email the prospect immediately.</p>'+\n'<a href=\"'+url+'\" style=\"display:inline-block;background:#48bb78;color:#fff;padding:14px 32px;border-radius:8px;text-decoration:none;font-weight:bold;font-size:16px\">YES — PROCEED</a>'+\n'<p style=\"color:#a0aec0;margin-top:18px\">Close this tab to cancel. Nothing has been sent yet.</p></body></html>';\nreturn [{json:{confirm_html:html}}];"
      },
      "id": "cf1_pg",
      "name": "Build Confirm One",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        528
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.confirm_html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "cf1_rs",
      "name": "Serve Confirm One",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        528
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{confirmed:q.confirm==='1'}}];"
      },
      "id": "cf2_ps",
      "name": "Parse SendAll Confirm",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        1808
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.confirmed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cf2_if",
      "name": "Confirmed All?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -960,
        1808
      ]
    },
    {
      "parameters": {
        "jsCode": "const url='https://your-n8n-instance.com/webhook/yourbrand-send-all?confirm=1';\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:480px;margin:40px auto;text-align:center\">'+\n'<h2 style=\"color:#2d3748\">Approve ALL pending drafts?</h2><p style=\"color:#4a5568\">Sends up to 25 oldest pending drafts to prospects, spaced 1-3 min apart.</p>'+\n'<a href=\"'+url+'\" style=\"display:inline-block;background:#48bb78;color:#fff;padding:14px 32px;border-radius:8px;text-decoration:none;font-weight:bold;font-size:16px\">YES — PROCEED</a>'+\n'<p style=\"color:#a0aec0;margin-top:18px\">Close this tab to cancel. Nothing has been sent yet.</p></body></html>';\nreturn [{json:{confirm_html:html}}];"
      },
      "id": "cf2_pg",
      "name": "Build Confirm All",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        1712
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.confirm_html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "cf2_rs",
      "name": "Serve Confirm All",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        1712
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.confirmed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cf3_if",
      "name": "Confirmed Resend?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -960,
        3504
      ]
    },
    {
      "parameters": {
        "jsCode": "const url='https://your-n8n-instance.com/webhook/yourbrand-resend-alt?log_id='+$json.log_id+'&confirm=1';\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:480px;margin:40px auto;text-align:center\">'+\n'<h2 style=\"color:#2d3748\">Resend to the alternate address?</h2><p style=\"color:#4a5568\">This will email the newly found contact immediately.</p>'+\n'<a href=\"'+url+'\" style=\"display:inline-block;background:#48bb78;color:#fff;padding:14px 32px;border-radius:8px;text-decoration:none;font-weight:bold;font-size:16px\">YES — PROCEED</a>'+\n'<p style=\"color:#a0aec0;margin-top:18px\">Close this tab to cancel. Nothing has been sent yet.</p></body></html>';\nreturn [{json:{confirm_html:html}}];"
      },
      "id": "cf3_pg",
      "name": "Build Confirm Resend",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        3408
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.confirm_html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "cf3_rs",
      "name": "Serve Confirm Resend",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        3408
      ]
    },
    {
      "parameters": {
        "jsCode": "const q=$input.all()[0].json.query||{};return [{json:{confirmed:q.confirm==='1'}}];"
      },
      "id": "cf4_ps",
      "name": "Parse ResendAll Confirm",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        3088
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.confirmed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cf4_if",
      "name": "Confirmed ResendAll?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -960,
        3088
      ]
    },
    {
      "parameters": {
        "jsCode": "const url='https://your-n8n-instance.com/webhook/yourbrand-resend-all-bounced?confirm=1';\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:480px;margin:40px auto;text-align:center\">'+\n'<h2 style=\"color:#2d3748\">Resend ALL bounced emails?</h2><p style=\"color:#4a5568\">Sends to every alternate address found, spaced 1-3 min apart.</p>'+\n'<a href=\"'+url+'\" style=\"display:inline-block;background:#48bb78;color:#fff;padding:14px 32px;border-radius:8px;text-decoration:none;font-weight:bold;font-size:16px\">YES — PROCEED</a>'+\n'<p style=\"color:#a0aec0;margin-top:18px\">Close this tab to cancel. Nothing has been sent yet.</p></body></html>';\nreturn [{json:{confirm_html:html}}];"
      },
      "id": "cf4_pg",
      "name": "Build Confirm ResendAll",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        2992
      ]
    },
    {
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.confirm_html }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/html; charset=utf-8"
              }
            ]
          }
        }
      },
      "id": "cf4_rs",
      "name": "Serve Confirm ResendAll",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -512,
        2992
      ]
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "condition": "ilike",
              "keyValue": "={{ $json.to_email }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_valid",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "email_status",
              "fieldValue": "send_failed"
            }
          ]
        }
      },
      "id": "sf_p1",
      "name": "Flag SF Prospect",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        160,
        48
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "bounced",
              "fieldValue": "={{ true }}"
            },
            {
              "fieldId": "bounce_date",
              "fieldValue": "={{ new Date().toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "id": "sf_l1",
      "name": "Flag SF Log",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        160,
        240
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "condition": "ilike",
              "keyValue": "={{ $json.to_email }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_valid",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "email_status",
              "fieldValue": "send_failed"
            }
          ]
        }
      },
      "id": "sf_p2",
      "name": "Flag SF Prospect (Each)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        1088
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "bounced",
              "fieldValue": "={{ true }}"
            },
            {
              "fieldId": "bounce_date",
              "fieldValue": "={{ new Date().toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "id": "sf_l2",
      "name": "Flag SF Log (Each)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        1280
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "prospects",
        "returnAll": true,
        "filters": {
          "conditions": [
            {
              "keyName": "inserted_at",
              "condition": "gt",
              "keyValue": "={{ new Date(Date.now()-172800000).toISOString() }}"
            }
          ]
        }
      },
      "id": "st_pro",
      "name": "Stats: Fetch Prospects",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -1184,
        -560
      ],
      "alwaysOutputData": true,
      "executeOnce": true
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "outreach_log",
        "returnAll": true
      },
      "id": "st_out",
      "name": "Stats: Fetch Outreach",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -960,
        -560
      ],
      "alwaysOutputData": true,
      "executeOnce": true
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "activity_log",
        "returnAll": true,
        "filters": {
          "conditions": [
            {
              "keyName": "created_at",
              "condition": "gt",
              "keyValue": "={{ new Date(Date.now()-172800000).toISOString() }}"
            }
          ]
        }
      },
      "id": "st_act",
      "name": "Stats: Fetch Activity",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -736,
        -560
      ],
      "alwaysOutputData": true,
      "executeOnce": true
    },
    {
      "parameters": {
        "jsCode": "\nconst now=Date.now();\nconst cut=new Date(now-86400000).toISOString();\nconst cutDate=new Date(now-86400000).toISOString().slice(0,10);\nconst pro=$('Stats: Fetch Prospects').all().map(i=>i.json).filter(x=>x&&(x.id||x.inserted_at));\nconst out=$('Stats: Fetch Outreach').all().map(i=>i.json).filter(x=>x&&x.id);\nconst act=$('Stats: Fetch Activity').all().map(i=>i.json).filter(x=>x&&x.workflow);\nconst newProspects=pro.filter(p=>String(p.inserted_at||'')>=cut).length;\nlet enriched=0; for(const r of act.filter(r=>r.workflow==='Contact Enrichment'&&String(r.created_at||'')>=cut)){const m=String(r.details||'').match(/(\\d+)\\s*enriched/i);enriched+=m?+m[1]:Number(r.count||0);}\nlet followWritten=0; for(const r of act.filter(r=>r.workflow==='Follow-up Sequencer'&&String(r.created_at||'')>=cut)) followWritten+=Number(r.count||0);\nconst bset=new Set(); for(const r of act.filter(r=>r.workflow==='Bounce Handler'&&String(r.created_at||'')>=cut)){const k=(String(r.details||'').match(/Bounced\\s+(\\S+)\\./)||[])[1]||r.company||r.id; bset.add(k);} const bounced=bset.size;\nlet replied=0; for(const r of act.filter(r=>r.workflow==='Reply Tracker'&&String(r.created_at||'')>=cut)) replied+=Number(r.count||1);\nconst coldDrafts=out.filter(o=>String(o.inserted_at||'')>=cut).length;\nconst hasTs=out.some(o=>o.sent_at);\nconst sentCold=hasTs ? out.filter(o=>String(o.sent_at||'')>=cut).length\n                     : out.filter(o=>String(o.sent_date||'')>=cutDate).length;\nconst fuSent=out.filter(o=>String(o.last_followup_at||'')>=cut).length;\nconst sent=sentCold+fuSent;\nconst card=(v,l,w,tint,tc)=>`<td style=\"padding:12px 6px;border:1px solid #e2e8f0;border-radius:10px;text-align:center;background:${tint||'#ffffff'};width:${w}\"><div style=\"font-size:24px;font-weight:700;color:${tc||'#2d3748'};line-height:1\">${v}</div><div style=\"font-size:11px;color:#718096;margin-top:3px\">${l}</div></td>`;\nconst gap='<td style=\"width:6px\"></td>';\nconst stats_html=`<div style=\"border:1px solid #e2e8f0;border-radius:12px;padding:16px;margin:0 0 22px;background:#f7fafc\">\n<h3 style=\"margin:0 0 10px;color:#2d3748;font-size:15px\">Last 24 hours</h3>\n<table style=\"width:100%;border-collapse:separate;border-spacing:0\"><tr>${card(newProspects,'new prospects found','20%')}${gap}${card(enriched,'prospects enriched','20%')}${gap}${card(coldDrafts,'cold emails written','20%')}${gap}${card(followWritten,'follow-ups written','20%')}${gap}${card(sent,(fuSent?('emails sent ('+sentCold+' cold + '+fuSent+' follow-ups)'):'emails sent'),'20%')}</tr></table>\n<table style=\"width:100%;border-collapse:separate;border-spacing:0;margin-top:6px\"><tr>${card(bounced,'emails bounced','50%','#fffaf0','#dd6b20')}${gap}${card(replied,'replies received','50%','#f0fff4','#2f855a')}</tr></table>\n</div>`;\nconst note=hasTs?'':'<p style=\"font-size:11px;color:#a0aec0;margin:6px 0 0\">sent uses date-granularity until the sent_at migration is run</p>';\nconst stats_html2=stats_html.replace('</div>', note+'</div>');\nreturn [{json:{stats_html:stats_html2,newProspects,enriched,coldDrafts,followWritten,sent,bounced,replied}}];\n"
      },
      "id": "st_build",
      "name": "Build Ops Stats",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -512,
        -560
      ]
    },
    {
      "parameters": {
        "resource": "label",
        "operation": "create",
        "name": "ACTION",
        "options": {}
      },
      "id": "al_ensure_AD",
      "name": "Ensure 'ACTION' Label AD",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1952,
        -752
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "label",
        "returnAll": true
      },
      "id": "al_get_AD",
      "name": "Get Gmail Labels (AD)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        2176,
        -752
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "addLabels",
        "messageId": "={{ $('Gmail — Daily Digest').item.json.id }}",
        "labelIds": [
          "={{ $('Get Gmail Labels (AD)').all().find(l => (l.json.name||'').toLowerCase()==='action')?.json.id }}"
        ]
      },
      "id": "al_apply_AD",
      "name": "Apply 'ACTION' Label AD",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        2400,
        -752
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const d=$json.fields&&$json.id?{...$json.fields,id:$json.id}:$json;\nconst url='https://your-n8n-instance.com/webhook/yourbrand-send-one?log_id='+d.id;\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:720px;margin:auto;padding:16px\">'\n+'<h2 style=\"color:#2d3748\">Updated draft — review before sending</h2>'\n+'<p><b>'+(d.company||'')+'</b> · '+(d.to_email||'')+'</p>'\n+'<p><b>Subject:</b> '+(d.email_subject||'')+'</p>'\n+'<div style=\"border:1px solid #e2e8f0;border-radius:8px;padding:14px;background:#f7fafc\">'+(d.email_body||'')+'</div>'\n+'<div style=\"text-align:center;margin:22px 0\"><a href=\"'+url+'\" style=\"background:#48bb78;color:#fff;padding:12px 30px;border-radius:8px;text-decoration:none;font-weight:bold\">SEND THIS VERSION</a></div>'\n+'<p style=\"color:#a0aec0;font-size:12px\">Further edits/rewrites available from the daily digest.</p></body></html>';\nreturn [{json:{id:d.id,company:d.company||d.to_email||'',review_html:html}}];"
      },
      "id": "rv_b_Edited",
      "name": "Build Review (Edited)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        4016
      ]
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "=[ACTION] Edited draft — {{ $json.company }} — review & send",
        "message": "={{ $json.review_html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "rv_g_Edited",
      "name": "Gmail — Review (Edited)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -512,
        4016
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const d=$json.fields&&$json.id?{...$json.fields,id:$json.id}:$json;\nconst url='https://your-n8n-instance.com/webhook/yourbrand-send-one?log_id='+d.id;\nconst html='<html><body style=\"font-family:Arial,sans-serif;max-width:720px;margin:auto;padding:16px\">'\n+'<h2 style=\"color:#2d3748\">Updated draft — review before sending</h2>'\n+'<p><b>'+(d.company||'')+'</b> · '+(d.to_email||'')+'</p>'\n+'<p><b>Subject:</b> '+(d.email_subject||'')+'</p>'\n+'<div style=\"border:1px solid #e2e8f0;border-radius:8px;padding:14px;background:#f7fafc\">'+(d.email_body||'')+'</div>'\n+'<div style=\"text-align:center;margin:22px 0\"><a href=\"'+url+'\" style=\"background:#48bb78;color:#fff;padding:12px 30px;border-radius:8px;text-decoration:none;font-weight:bold\">SEND THIS VERSION</a></div>'\n+'<p style=\"color:#a0aec0;font-size:12px\">Further edits/rewrites available from the daily digest.</p></body></html>';\nreturn [{json:{id:d.id,company:d.company||d.to_email||'',review_html:html}}];"
      },
      "id": "rv_b_Rewritten",
      "name": "Build Review (Rewritten)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        160,
        2768
      ]
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "=[ACTION] Rewritten draft — {{ $json.company }} — review & send",
        "message": "={{ $json.review_html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "rv_g_Rewritten",
      "name": "Gmail — Review (Rewritten)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        384,
        2768
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Email Verified?",
              "leftValue": "={{ $json.verify_result !== 'undeliverable' && $json.verify_result !== 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Email Verified?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -288,
        336
      ],
      "id": "9797076c-8b73-4c2d-943f-ba211f49f1e2"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Quota Exhausted?",
              "leftValue": "={{ $json.verify_result === 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Quota Exhausted?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -64,
        528
      ],
      "id": "a4eed6fe-feef-40d6-ab5a-635a1641c751"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "bounced",
              "fieldValue": "={{ true }}"
            },
            {
              "fieldId": "bounce_date",
              "fieldValue": "={{ new Date().toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "name": "Mark Verify-Failed Log",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        160,
        672
      ],
      "id": "9b3e4177-bced-42df-8d9d-d4fcc411ecc8",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "condition": "ilike",
              "keyValue": "={{ $json.to_email }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_valid",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "email_status",
              "fieldValue": "verify_failed"
            }
          ]
        }
      },
      "name": "Mark Verify-Failed Prospect",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        384,
        672
      ],
      "id": "e7309281-177d-4a97-be6d-b3d73d51791c",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const sd=$getWorkflowStaticData('global');\nconst last=Number(sd.lastQuotaAlert||0);\nconst need=(Date.now()-last)>24*3600*1000;\nif(need) sd.lastQuotaAlert=Date.now();\nreturn $input.all().map((i,idx)=>({json:{...i.json,_send_alert:need && idx===0}}));"
      },
      "name": "Quota Alert Guard",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        160,
        432
      ],
      "id": "4235c0f7-7f1b-4346-88f1-e3a2e8de5a70"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Send Quota Alert?",
              "leftValue": "={{ $json._send_alert === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Send Quota Alert?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        384,
        432
      ],
      "id": "cb3c34eb-0fb1-4ecb-a54a-54078ab87a45"
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "[ACTION] Add AbstractAPI key — outreach verification paused",
        "message": "<p><b>AbstractAPI email verification credits are exhausted.</b></p><p>Outreach is safely on hold: unverified drafts stay pending, nothing is sent to unchecked addresses.</p><p style=\"margin:20px 0\"><a href=\"https://your-n8n-instance.com/webhook/yourbrand-abstract-keys\" style=\"background:#2e7d5b;color:#ffffff;padding:13px 26px;border-radius:6px;text-decoration:none;font-weight:bold;font-size:15px\">ADD NEW API KEY</a></p><p style=\"color:#555\">1. Create a free account at abstractapi.com (Email Reputation API)<br>2. Copy the API key<br>3. Click the button above, paste, save.</p><p style=\"color:#555\">The key is tested live, added to every agent, and verification of pending emails resumes automatically.</p>",
        "options": {
          "appendAttribution": false
        }
      },
      "name": "Gmail — Credits Alert",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        608,
        360
      ],
      "id": "5322b382-d9e9-42ce-8343-288efd41b75c",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"ok\": false, \"message\": \"Email address failed verification. NOT sent. The prospect was flagged and the bounce-handler will hunt an alternate address.\"}",
        "options": {}
      },
      "name": "Resp Verify-Blocked",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        608,
        672
      ],
      "id": "643d5932-65cb-4941-9173-cd3bd815ca4d"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"ok\": false, \"message\": \"Verification credits exhausted. Email NOT sent and stays pending. Add new AbstractAPI keys.\"}",
        "options": {}
      },
      "name": "Resp Quota Hold",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        832,
        432
      ],
      "id": "ec1519f9-432c-4d3e-b279-37355a817f2c"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Email Verified? (All)",
              "leftValue": "={{ $json.verify_result !== 'undeliverable' && $json.verify_result !== 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Email Verified? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        160,
        1160
      ],
      "id": "ec6df554-c616-4b0a-a3aa-3cff8da45789"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Quota Exhausted? (All)",
              "leftValue": "={{ $json.verify_result === 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Quota Exhausted? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        384,
        1568
      ],
      "id": "75471a1e-bde6-471b-a08a-6f2010b17dc3"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "bounced",
              "fieldValue": "={{ true }}"
            },
            {
              "fieldId": "bounce_date",
              "fieldValue": "={{ new Date().toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "name": "Mark VF Log (All)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        1664
      ],
      "id": "3a563a95-697a-4cbf-8ef9-c1cc779117e7",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "condition": "ilike",
              "keyValue": "={{ $json.to_email }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_valid",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "email_status",
              "fieldValue": "verify_failed"
            }
          ]
        }
      },
      "name": "Mark VF Prospect (All)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        832,
        1712
      ],
      "id": "a5473634-547a-4d71-b79c-a3a104a67d6a",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const sd=$getWorkflowStaticData('global');\nconst last=Number(sd.lastQuotaAlert||0);\nconst need=(Date.now()-last)>24*3600*1000;\nif(need) sd.lastQuotaAlert=Date.now();\nreturn $input.all().map((i,idx)=>({json:{...i.json,_send_alert:need && idx===0}}));"
      },
      "name": "Quota Alert Guard (All)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        608,
        1472
      ],
      "id": "978be88d-0a7f-4bc3-b012-caac4a6c2c5d"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Send Quota Alert? (All)",
              "leftValue": "={{ $json._send_alert === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Send Quota Alert? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        832,
        1520
      ],
      "id": "45d299f6-549d-48c4-a542-f6894b85d8d1"
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "[ACTION] Add AbstractAPI key — outreach verification paused",
        "message": "<p><b>AbstractAPI email verification credits are exhausted.</b></p><p>Outreach is safely on hold: unverified drafts stay pending, nothing is sent to unchecked addresses.</p><p style=\"margin:20px 0\"><a href=\"https://your-n8n-instance.com/webhook/yourbrand-abstract-keys\" style=\"background:#2e7d5b;color:#ffffff;padding:13px 26px;border-radius:6px;text-decoration:none;font-weight:bold;font-size:15px\">ADD NEW API KEY</a></p><p style=\"color:#555\">1. Create a free account at abstractapi.com (Email Reputation API)<br>2. Copy the API key<br>3. Click the button above, paste, save.</p><p style=\"color:#555\">The key is tested live, added to every agent, and verification of pending emails resumes automatically.</p>",
        "options": {
          "appendAttribution": false
        }
      },
      "name": "Gmail — Credits Alert (All)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1056,
        1784
      ],
      "id": "898a70b8-d6eb-4347-8faa-9367511a9744",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const ABSTRACT_KEYS=[\"YOUR_ABSTRACTAPI_KEY_1\",\"YOUR_ABSTRACTAPI_KEY_2\",\"YOUR_ABSTRACTAPI_KEY\",\"YOUR_ABSTRACTAPI_KEY\"];\nconst __sd=$getWorkflowStaticData('global');\nif(typeof __sd.abstractExhausted!=='object'||!__sd.abstractExhausted) __sd.abstractExhausted={};\nif(typeof __sd.abstractCache!=='object'||!__sd.abstractCache) __sd.abstractCache={};\nconst __sleep=(ms)=>new Promise(r=>setTimeout(r,ms));\nconst verifyEmail=async(email)=>{\n  email=String(email||'').toLowerCase().trim();\n  if(!email||!email.includes('@')) return 'undeliverable';\n  const cached=__sd.abstractCache[email];\n  if(cached && Date.now()-cached.ts < 30*24*3600*1000) return cached.status;\n  const KEY_COOLDOWN=24*3600*1000;\n  for(const key of ABSTRACT_KEYS){\n    const ex=__sd.abstractExhausted[key];\n    if(ex && Date.now()-ex<KEY_COOLDOWN) continue;\n    let attempts=0;\n    while(attempts<5){\n      attempts++;\n      try{\n        await __sleep(1400+Math.floor(Math.random()*800));\n        const res=await this.helpers.httpRequest({method:'GET',\n          url:'https://emailreputation.abstractapi.com/v1/?api_key='+key+'&email='+encodeURIComponent(email),\n          json:true, returnFullResponse:true, ignoreHttpStatusErrors:true, timeout:20000});\n        const code=Number(res.statusCode||0);\n        if(code===422){\n          const msg422=JSON.stringify(res.body||'').toLowerCase();\n          if(msg422.includes('quota')){ __sd.abstractExhausted[key]=Date.now(); break; }\n          return 'error';\n        }\n        if(code===429){\n          const msg=JSON.stringify(res.body||'').toLowerCase();\n          const isQuota = msg.includes('quota') && !msg.includes('per second');\n          if(isQuota){ __sd.abstractExhausted[key]=Date.now(); break; }\n          if(attempts<5){ await __sleep(1200*attempts+500); continue; }\n          return 'error';\n        }\n        if(code===401||code===402||code===403){ __sd.abstractExhausted[key]=Date.now(); break; }\n        if(code<200||code>=300) return 'error';\n        const status=String((res.body&&res.body.email_deliverability&&res.body.email_deliverability.status)||'unknown').toLowerCase();\n        const final=(status==='deliverable')?'deliverable':(status==='undeliverable'?'undeliverable':'unknown');\n        __sd.abstractCache[email]={status:final,ts:Date.now()};\n        return final;\n      }catch(e){ return 'error'; }\n    }\n  }\n  return 'quota_exhausted';\n};\n\nconst out=[];\nfor(const it of $input.all()){\n  const d={...it.json};\n  d.verify_result=await verifyEmail(d.to_email);\n  out.push({json:d});\n}\nreturn out;"
      },
      "name": "Verify Digest Drafts",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -64,
        -560
      ],
      "id": "f46168d8-35a3-4f7a-aa4e-4cb6f320a3e2"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Digest: Verified?",
              "leftValue": "={{ $json.verify_result !== 'undeliverable' && $json.verify_result !== 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Digest: Verified?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        160,
        -560
      ],
      "id": "dff34c4e-55d4-49c4-8210-00c5beff05e4"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Digest: Quota?",
              "leftValue": "={{ $json.verify_result === 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Digest: Quota?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        384,
        -464
      ],
      "id": "127a5926-3819-48fa-88d2-2c941cd2758b"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "bounced",
              "fieldValue": "={{ true }}"
            },
            {
              "fieldId": "bounce_date",
              "fieldValue": "={{ new Date().toISOString().slice(0,10) }}"
            }
          ]
        }
      },
      "name": "Digest: Mark VF Log",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        608,
        -368
      ],
      "id": "8f6c70f7-8e33-4f5f-a947-68649e9819c4",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "update",
        "tableId": "prospects",
        "filters": {
          "conditions": [
            {
              "keyName": "email",
              "condition": "ilike",
              "keyValue": "={{ $json.to_email }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "email_valid",
              "fieldValue": "={{ false }}"
            },
            {
              "fieldId": "email_status",
              "fieldValue": "verify_failed"
            }
          ]
        }
      },
      "name": "Digest: Mark VF Prospect",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        832,
        -368
      ],
      "id": "ad6d88ee-3718-4457-8823-bad1c8b508d2",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const sd=$getWorkflowStaticData('global');\nconst last=Number(sd.lastQuotaAlert||0);\nconst need=(Date.now()-last)>24*3600*1000;\nif(need) sd.lastQuotaAlert=Date.now();\nreturn $input.all().map((i,idx)=>({json:{...i.json,_send_alert:need && idx===0}}));"
      },
      "name": "Digest: Quota Guard",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        608,
        -560
      ],
      "id": "2631973f-e8e0-462d-9696-ae55a5f91e72"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Digest: Send Alert?",
              "leftValue": "={{ $json._send_alert === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Digest: Send Alert?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        832,
        -560
      ],
      "id": "b2d34b6f-9df0-4d15-ae21-3396cf5f6bff"
    },
    {
      "parameters": {
        "sendTo": "you@yourdomain.com",
        "subject": "[ACTION] Add AbstractAPI key — outreach verification paused",
        "message": "<p><b>AbstractAPI email verification credits are exhausted.</b></p><p>Outreach is safely on hold: unverified drafts stay pending, nothing is sent to unchecked addresses.</p><p style=\"margin:20px 0\"><a href=\"https://your-n8n-instance.com/webhook/yourbrand-abstract-keys\" style=\"background:#2e7d5b;color:#ffffff;padding:13px 26px;border-radius:6px;text-decoration:none;font-weight:bold;font-size:15px\">ADD NEW API KEY</a></p><p style=\"color:#555\">1. Create a free account at abstractapi.com (Email Reputation API)<br>2. Copy the API key<br>3. Click the button above, paste, save.</p><p style=\"color:#555\">The key is tested live, added to every agent, and verification of pending emails resumes automatically.</p>",
        "options": {
          "appendAttribution": false
        }
      },
      "name": "Gmail — Credits Alert (Digest)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1056,
        -560
      ],
      "id": "f7f7ae53-62ed-4b84-a255-72d2d2ec1e81",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "sendTo": "={{ $json.to_email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "w_one_send",
      "name": "Send Prospect Email (B)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -64,
        268
      ],
      "onError": "continueErrorOutput"
    },
    {
      "name": "Sender B?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -224,
        158
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Sender B?",
              "leftValue": "={{ $json.sender_b === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "a3d2a06a-fe88-4cab-9f4a-ba0ecee07022"
    },
    {
      "parameters": {
        "sendTo": "={{ $json.to_email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "w_all_send",
      "name": "Send Each (B)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        384,
        1308
      ],
      "onError": "continueErrorOutput"
    },
    {
      "name": "Sender B? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        224,
        1198
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Sender B? (All)",
              "leftValue": "={{ $json.sender_b === true }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "2bb0aefa-55a9-431c-a8e4-78063c50b2ce"
    },
    {
      "name": "Resend OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        0,
        900
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Resend OK?",
              "leftValue": "={{ $json.verify_result !== 'undeliverable' && $json.verify_result !== 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "89a39664-42fe-4c1e-b13c-dd7639e5b368"
    },
    {
      "name": "Resend Quota?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        160,
        980
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Resend Quota?",
              "leftValue": "={{ $json.verify_result === 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "7caa525c-90a0-4de9-a8bf-7d7f758d4c73"
    },
    {
      "name": "Clear Bad Alt",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        320,
        1060
      ],
      "onError": "continueRegularOutput",
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "alt_email_found",
              "fieldValue": ""
            }
          ]
        }
      },
      "id": "b3c70391-bdbf-45c4-9a0d-7195c1c3549b"
    },
    {
      "name": "Resp Resend Blocked",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        480,
        1060
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"ok\": false, \"message\": \"Alternate address failed verification. NOT sent; cleared it so the bounce handler hunts a fresh one.\"}"
      },
      "id": "e969017b-0cf4-464a-9ddb-0da9c6be1d61"
    },
    {
      "name": "Resp Resend Quota",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        320,
        940
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\"ok\": false, \"message\": \"Verification credits exhausted. Resend held. Add a new AbstractAPI key via the Agent 9 form.\"}"
      },
      "id": "b3f22943-99f2-448b-946e-efaa77aee1cb"
    },
    {
      "name": "Resend OK? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        0,
        1200
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Resend OK? (All)",
              "leftValue": "={{ $json.verify_result !== 'undeliverable' && $json.verify_result !== 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "2430d9b7-9a9b-4783-94a8-c93e0a960c2d"
    },
    {
      "name": "Resend Quota? (All)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        160,
        1280
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "Resend Quota? (All)",
              "leftValue": "={{ $json.verify_result === 'quota_exhausted' }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "64a9ba4b-f37b-4a38-89b2-8b276be242fe"
    },
    {
      "name": "Clear Bad Alt (All)",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        320,
        1360
      ],
      "onError": "continueRegularOutput",
      "parameters": {
        "operation": "update",
        "tableId": "outreach_log",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "alt_email_found",
              "fieldValue": ""
            }
          ]
        }
      },
      "id": "077b385e-752e-489c-9820-1323911e2673"
    }
  ],
  "connections": {
    "Manual": {
      "main": [
        [
          {
            "node": "Stats: Fetch Prospects",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Pending Drafts": {
      "main": [
        [
          {
            "node": "Verify Digest Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Master Digest": {
      "main": [
        [
          {
            "node": "Gmail — Daily Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send-One Webhook": {
      "main": [
        [
          {
            "node": "Parse log_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse log_id": {
      "main": [
        [
          {
            "node": "Confirmed One?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Draft": {
      "main": [
        [
          {
            "node": "Stamp Today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stamp Today": {
      "main": [
        [
          {
            "node": "Email Verified?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Prospect Email": {
      "main": [
        [
          {
            "node": "Mark Sent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag SF Prospect",
            "type": "main",
            "index": 0
          },
          {
            "node": "Flag SF Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Sent": {
      "main": [
        [
          {
            "node": "Resp One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send-All Webhook": {
      "main": [
        [
          {
            "node": "Parse SendAll Confirm",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resp All": {
      "main": [
        [
          {
            "node": "Fetch All Pending",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Pending": {
      "main": [
        [
          {
            "node": "Loop Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Drafts": {
      "main": [
        [],
        [
          {
            "node": "Stamp Today All",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stamp Today All": {
      "main": [
        [
          {
            "node": "Email Verified? (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Each": {
      "main": [
        [
          {
            "node": "Mark Each Sent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag SF Prospect (Each)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Flag SF Log (Each)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Each Sent": {
      "main": [
        [
          {
            "node": "Random 1-3 min",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Random 1-3 min": {
      "main": [
        [
          {
            "node": "Loop Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates": {
      "main": [
        [
          {
            "node": "Delete Duplicate Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Webhook": {
      "main": [
        [
          {
            "node": "Parse Edit log_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Edit log_id": {
      "main": [
        [
          {
            "node": "Get Edit Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Edit Draft": {
      "main": [
        [
          {
            "node": "Build Edit Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Edit Form": {
      "main": [
        [
          {
            "node": "Serve Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Save Webhook": {
      "main": [
        [
          {
            "node": "Parse Saved Edit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Saved Edit": {
      "main": [
        [
          {
            "node": "Save Edited Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Edited Draft": {
      "main": [
        [
          {
            "node": "Saved Response",
            "type": "main",
            "index": 0
          },
          {
            "node": "Build Review (Edited)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rewrite Webhook": {
      "main": [
        [
          {
            "node": "Parse RW log_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse RW log_id": {
      "main": [
        [
          {
            "node": "Get RW Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get RW Draft": {
      "main": [
        [
          {
            "node": "Build RW Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build RW Form": {
      "main": [
        [
          {
            "node": "Serve RW Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rewrite Apply Webhook": {
      "main": [
        [
          {
            "node": "Parse RW Apply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse RW Apply": {
      "main": [
        [
          {
            "node": "Get RW Apply Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get RW Apply Draft": {
      "main": [
        [
          {
            "node": "Build RW Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build RW Prompt": {
      "main": [
        [
          {
            "node": "GPT — RW",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GPT — RW": {
      "main": [
        [
          {
            "node": "Parse RW",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse RW": {
      "main": [
        [
          {
            "node": "Update RW Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update RW Log": {
      "main": [
        [
          {
            "node": "Respond RW",
            "type": "main",
            "index": 0
          },
          {
            "node": "Build Review (Rewritten)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Bounced Review": {
      "main": [
        [
          {
            "node": "Fetch Replies 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Replies 24h": {
      "main": [
        [
          {
            "node": "Build Master Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend-Alt Webhook": {
      "main": [
        [
          {
            "node": "Parse Resend log_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Resend log_id": {
      "main": [
        [
          {
            "node": "Confirmed Resend?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Resend Draft": {
      "main": [
        [
          {
            "node": "Prep Resend",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prep Resend": {
      "main": [
        [
          {
            "node": "Resend OK?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Resend": {
      "main": [
        [
          {
            "node": "Mark Resent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Resent": {
      "main": [
        [
          {
            "node": "Resp Resend",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend-All Bounced Webhook": {
      "main": [
        [
          {
            "node": "Parse ResendAll Confirm",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resp Resend All": {
      "main": [
        [
          {
            "node": "Fetch All Bounced w/ Alt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Bounced w/ Alt": {
      "main": [
        [
          {
            "node": "Loop Bounced",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Bounced": {
      "main": [
        [],
        [
          {
            "node": "Prep Resend Each",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prep Resend Each": {
      "main": [
        [
          {
            "node": "Resend OK? (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Resend Each": {
      "main": [
        [
          {
            "node": "Mark Resent Each",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Resent Each": {
      "main": [
        [
          {
            "node": "Random 1-3 min RAB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Random 1-3 min RAB": {
      "main": [
        [
          {
            "node": "Loop Bounced",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily 10:30 AM IST": {
      "main": [
        [
          {
            "node": "Stats: Fetch Prospects",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Stale Pending",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Duplicate Drafts": {
      "main": [
        [
          {
            "node": "Continue After Delete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Continue After Delete": {
      "main": [
        [
          {
            "node": "Fetch Bounced Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Stale Pending": {
      "main": [
        [
          {
            "node": "Prep Expiry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prep Expiry": {
      "main": [
        [
          {
            "node": "Expire Stale Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Expire Stale Draft": {
      "main": [
        [
          {
            "node": "Reset Prospect (expired)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirmed One?": {
      "main": [
        [
          {
            "node": "Get Draft",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Confirm One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Confirm One": {
      "main": [
        [
          {
            "node": "Serve Confirm One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse SendAll Confirm": {
      "main": [
        [
          {
            "node": "Confirmed All?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirmed All?": {
      "main": [
        [
          {
            "node": "Resp All",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Confirm All",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Confirm All": {
      "main": [
        [
          {
            "node": "Serve Confirm All",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirmed Resend?": {
      "main": [
        [
          {
            "node": "Get Resend Draft",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Confirm Resend",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Confirm Resend": {
      "main": [
        [
          {
            "node": "Serve Confirm Resend",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse ResendAll Confirm": {
      "main": [
        [
          {
            "node": "Confirmed ResendAll?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirmed ResendAll?": {
      "main": [
        [
          {
            "node": "Resp Resend All",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Confirm ResendAll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Confirm ResendAll": {
      "main": [
        [
          {
            "node": "Serve Confirm ResendAll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stats: Fetch Prospects": {
      "main": [
        [
          {
            "node": "Stats: Fetch Outreach",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stats: Fetch Outreach": {
      "main": [
        [
          {
            "node": "Stats: Fetch Activity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stats: Fetch Activity": {
      "main": [
        [
          {
            "node": "Build Ops Stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Ops Stats": {
      "main": [
        [
          {
            "node": "Fetch Pending Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail — Daily Digest": {
      "main": [
        [
          {
            "node": "Ensure 'ACTION' Label AD",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ensure 'ACTION' Label AD": {
      "main": [
        [
          {
            "node": "Get Gmail Labels (AD)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Gmail Labels (AD)": {
      "main": [
        [
          {
            "node": "Apply 'ACTION' Label AD",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Review (Edited)": {
      "main": [
        [
          {
            "node": "Gmail — Review (Edited)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Review (Rewritten)": {
      "main": [
        [
          {
            "node": "Gmail — Review (Rewritten)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Verified?": {
      "main": [
        [
          {
            "node": "Sender B?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quota Exhausted?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quota Exhausted?": {
      "main": [
        [
          {
            "node": "Quota Alert Guard",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Verify-Failed Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quota Alert Guard": {
      "main": [
        [
          {
            "node": "Send Quota Alert?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Quota Alert?": {
      "main": [
        [
          {
            "node": "Gmail — Credits Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Resp Quota Hold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail — Credits Alert": {
      "main": [
        [
          {
            "node": "Resp Quota Hold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Verify-Failed Log": {
      "main": [
        [
          {
            "node": "Mark Verify-Failed Prospect",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Verify-Failed Prospect": {
      "main": [
        [
          {
            "node": "Resp Verify-Blocked",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Verified? (All)": {
      "main": [
        [
          {
            "node": "Sender B? (All)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Quota Exhausted? (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quota Exhausted? (All)": {
      "main": [
        [
          {
            "node": "Quota Alert Guard (All)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark VF Log (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quota Alert Guard (All)": {
      "main": [
        [
          {
            "node": "Send Quota Alert? (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Quota Alert? (All)": {
      "main": [
        [
          {
            "node": "Gmail — Credits Alert (All)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail — Credits Alert (All)": {
      "main": [
        [
          {
            "node": "Loop Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark VF Log (All)": {
      "main": [
        [
          {
            "node": "Mark VF Prospect (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark VF Prospect (All)": {
      "main": [
        [
          {
            "node": "Loop Drafts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify Digest Drafts": {
      "main": [
        [
          {
            "node": "Digest: Verified?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Digest: Verified?": {
      "main": [
        [
          {
            "node": "Remove Duplicates",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Digest: Quota?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Digest: Quota?": {
      "main": [
        [
          {
            "node": "Digest: Quota Guard",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Digest: Mark VF Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Digest: Quota Guard": {
      "main": [
        [
          {
            "node": "Digest: Send Alert?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Digest: Send Alert?": {
      "main": [
        [
          {
            "node": "Gmail — Credits Alert (Digest)",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Digest: Mark VF Log": {
      "main": [
        [
          {
            "node": "Digest: Mark VF Prospect",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sender B?": {
      "main": [
        [
          {
            "node": "Send Prospect Email (B)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Prospect Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Prospect Email (B)": {
      "main": [
        [
          {
            "node": "Mark Sent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag SF Prospect",
            "type": "main",
            "index": 0
          },
          {
            "node": "Flag SF Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sender B? (All)": {
      "main": [
        [
          {
            "node": "Send Each (B)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Each",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Each (B)": {
      "main": [
        [
          {
            "node": "Mark Each Sent",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag SF Prospect (Each)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Flag SF Log (Each)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend OK?": {
      "main": [
        [
          {
            "node": "Send Resend",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Resend Quota?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend Quota?": {
      "main": [
        [
          {
            "node": "Resp Resend Quota",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Clear Bad Alt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clear Bad Alt": {
      "main": [
        [
          {
            "node": "Resp Resend Blocked",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend OK? (All)": {
      "main": [
        [
          {
            "node": "Send Resend Each",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Resend Quota? (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resend Quota? (All)": {
      "main": [
        [
          {
            "node": "Loop Bounced",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Clear Bad Alt (All)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clear Bad Alt (All)": {
      "main": [
        [
          {
            "node": "Loop Bounced",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "binaryMode": "separate"
  }
}