{
 "name": "Ep17 - Connection Check (Google, OpenAI, Slack)",
 "nodes": [
  {
   "parameters": {
    "formTitle": "Connection Check",
    "formDescription": "One tap tests every login this business runs on and shows which ones work, with the exact error and the fix.",
    "formFields": {
     "values": [
      {
       "fieldLabel": "Business name",
       "placeholder": "e.g. Brightside Cleaning",
       "requiredField": true
      }
     ]
    },
    "options": {
     "buttonLabel": "Check my connections"
    }
   },
   "id": "c17-form",
   "name": "Check Form",
   "type": "n8n-nodes-base.formTrigger",
   "typeVersion": 2.2,
   "position": [0, 300],
   "webhookId": "ep17-connection-check"
  },
  {
   "parameters": {
    "documentId": {"__rl": true, "mode": "id", "value": "1PnZPMQ0HL8fnU0Kd5x6GahTqRzaKjW6WL-gmVAWtx2s"},
    "sheetName": {"__rl": true, "mode": "name", "value": "Leads"},
    "options": {}
   },
   "id": "c17-sheets",
   "name": "Google Sheets",
   "type": "n8n-nodes-base.googleSheets",
   "typeVersion": 4.5,
   "position": [260, 300],
   "executeOnce": true,
   "alwaysOutputData": true,
   "onError": "continueRegularOutput",
   "credentials": {"googleSheetsOAuth2Api": {"id": "sHiSaOHdDzOZoxnx", "name": "Google Sheets (OwnerAutomate)"}},
   "notes": "Reads the Leads tab. Swap in your own sheet.",
   "notesInFlow": true
  },
  {
   "parameters": {
    "operation": "getAll",
    "limit": 1,
    "filters": {}
   },
   "id": "c17-gmail",
   "name": "Gmail",
   "type": "n8n-nodes-base.gmail",
   "typeVersion": 2.1,
   "position": [520, 300],
   "executeOnce": true,
   "alwaysOutputData": true,
   "onError": "continueRegularOutput",
   "credentials": {"gmailOAuth2": {"id": "avT0HSTU0k73ksRU", "name": "Gmail (OwnerAutomate)"}},
   "notes": "Reads the newest email. Nothing is sent.",
   "notesInFlow": true
  },
  {
   "parameters": {
    "url": "https://api.openai.com/v1/models",
    "options": {
     "response": {"response": {"fullResponse": true, "neverError": true}}
    }
   },
   "id": "c17-openai",
   "name": "OpenAI",
   "type": "n8n-nodes-base.httpRequest",
   "typeVersion": 4.2,
   "position": [780, 300],
   "executeOnce": true,
   "onError": "continueRegularOutput",
   "notes": "Lists models, costs nothing. Set Authentication to your OpenAI credential.",
   "notesInFlow": true
  },
  {
   "parameters": {
    "method": "POST",
    "url": "https://slack.com/api/auth.test",
    "options": {
     "response": {"response": {"fullResponse": true, "neverError": true}}
    }
   },
   "id": "c17-slack",
   "name": "Slack",
   "type": "n8n-nodes-base.httpRequest",
   "typeVersion": 4.2,
   "position": [1040, 300],
   "executeOnce": true,
   "onError": "continueRegularOutput",
   "notes": "Asks Slack who this token is. Set Authentication to your Slack credential.",
   "notesInFlow": true
  },
  {
   "parameters": {
    "jsCode": "// Connection Check: one line per login, with the error and the fix when it fails.\nconst business = String($('Check Form').first().json['Business name'] || 'your business').trim();\nconst errText = (e) => String((e && (e.message || e.description)) || e || '').split('\\n')[0].slice(0, 140);\nconst lines = [];\nlet ok = 0;\n\n// Google Sheets: an error item means the credential failed; otherwise count the rows it could read.\nconst sheet = $('Google Sheets').all();\nconst sheetErr = sheet[0] && sheet[0].json && sheet[0].json.error;\nif (sheetErr) lines.push(`✗ Google Sheets: ${errText(sheetErr)}. Fix: reconnect the Google credential.`);\nelse { ok++; lines.push(`✓ Google Sheets: connected, ${sheet.filter(i => Object.keys(i.json).length).length} rows in Leads.`); }\n\n// Gmail: same idea, read-only.\nconst mail = $('Gmail').first().json;\nif (mail.error) lines.push(`✗ Gmail: ${errText(mail.error)}. Fix: reconnect the Gmail credential.`);\nelse { ok++; lines.push('✓ Gmail: connected, inbox readable.'); }\n\n// OpenAI: 200 means the key works. 401 = no key or wrong key. 429 = key works but no credit.\nconst ai = $('OpenAI').first().json;\nif (ai.statusCode === 200) { ok++; lines.push('✓ OpenAI: connected.'); }\nelse {\n  const msg = (ai.body && ai.body.error && ai.body.error.message) || errText(ai.error) || 'no answer';\n  const fix = ai.statusCode === 429 ? 'add credit under Billing' : 'paste your API key into an OpenAI credential';\n  lines.push(`✗ OpenAI: ${ai.statusCode || 'error'}, ${msg.split('. ')[0]}. Fix: ${fix}.`);\n}\n\n// Slack: auth.test answers ok true with a working bot token.\nconst sl = $('Slack').first().json;\nif (sl.body && sl.body.ok) { ok++; lines.push(`✓ Slack: connected as ${sl.body.user}.`); }\nelse lines.push(`✗ Slack: ${(sl.body && sl.body.error) || errText(sl.error) || 'no answer'}. Fix: paste your bot token (xoxb-) into a Slack credential.`);\n\nreturn [{ json: { business, ok, total: 4, title: `${ok} of 4 connected for ${business}`, report: lines.join('\\n') } }];"
   },
   "id": "c17-verdict",
   "name": "Verdict",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [1300, 300]
  },
  {
   "parameters": {
    "operation": "completion",
    "completionTitle": "={{ $json.title }}",
    "completionMessage": "={{ $json.report }}",
    "options": {}
   },
   "id": "c17-result",
   "name": "Show Result",
   "type": "n8n-nodes-base.form",
   "typeVersion": 1,
   "position": [1560, 300],
   "webhookId": "5d0f8a52-17c1-4c9e-9a31-e17c0a0c0018"
  }
 ],
 "connections": {
  "Check Form": {"main": [[{"node": "Google Sheets", "type": "main", "index": 0}]]},
  "Google Sheets": {"main": [[{"node": "Gmail", "type": "main", "index": 0}]]},
  "Gmail": {"main": [[{"node": "OpenAI", "type": "main", "index": 0}]]},
  "OpenAI": {"main": [[{"node": "Slack", "type": "main", "index": 0}]]},
  "Slack": {"main": [[{"node": "Verdict", "type": "main", "index": 0}]]},
  "Verdict": {"main": [[{"node": "Show Result", "type": "main", "index": 0}]]}
 },
 "settings": {"executionOrder": "v1"}
}
