{
  "id": "DBOCXuTYe1UulESii7ETA",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Get FAQ Data",
  "tags": [],
  "nodes": [
    {
      "id": "bbe39fd0-b16f-445e-9e28-0f58daf8ad9c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1232,
        -160
      ],
      "parameters": {
        "width": 480,
        "height": 768,
        "content": "## Get FAQ Data\n\n### How it works\n\nThis workflow is designed to be called by another n8n workflow to retrieve FAQ data for a specific branch. It first loads configuration and parses the incoming parameters, then chooses between Rabieh and Bikfaya FAQ Google Sheets. The selected FAQ data is formatted into an enhanced response for the caller.\n\n### Setup steps\n\n- Configure Google Sheets credentials for all Google Sheets nodes.\n- Set the correct spreadsheet IDs, sheet names, and ranges for the Config, Rabieh FAQ, and Bikfaya FAQ sheets.\n- Ensure the calling workflow passes the expected named fields used by the Parse Parameters and branch condition logic.\n- Verify the IF condition matches the exact branch value used to identify Rabieh versus Bikfaya.\n\n### Customization\n\nAdd more branch-specific FAQ sheet nodes and extend the routing logic if additional locations need to be supported. Adjust the final code node to change the response shape or include extra FAQ metadata."
      },
      "typeVersion": 1
    },
    {
      "id": "1331a8da-bb3a-4d1e-abc0-d9924d06f8cc",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 320,
        "content": "## Trigger and parameters\n\nStarts when called by another workflow, reads shared configuration from Google Sheets, and parses the incoming named parameters for downstream routing."
      },
      "typeVersion": 1
    },
    {
      "id": "ba845d0e-7727-4001-9e35-96ca03211aa0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        -160
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 528,
        "content": "## Select FAQ source\n\nChecks whether the request is for the Rabieh branch and routes to the appropriate Google Sheets FAQ source for Rabieh or Bikfaya."
      },
      "typeVersion": 1
    },
    {
      "id": "3f5e3a1b-8aa9-4c42-8105-f08bba05e851",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 240,
        "height": 336,
        "content": "## Format FAQ output\n\nCombines the selected FAQ sheet data into the enhanced output structure returned by the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "d8d01f5e-7540-496e-aaf3-14280f586c69",
      "name": "Workflow Execution Start",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -624,
        112
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "branch"
            },
            {
              "name": "category"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "7c80186d-49e6-493e-bd01-3d2fc8ceaa8c",
      "name": "Process Parameters",
      "type": "n8n-nodes-base.code",
      "position": [
        -272,
        112
      ],
      "parameters": {
        "jsCode": "// v1.1 trigger \u2014 named fields arrive directly\nconst inputData = $('Workflow Execution Start').first().json;\nconst branch = String(inputData.branch || '').toLowerCase().trim();\nconst category = String(inputData.category || '').toLowerCase().trim();\n\nconsole.log('=== ENHANCED FAQ TOOL ===');\nconsole.log('Branch:', branch);\nconsole.log('Category filter:', category);\n\nreturn [{\n  json: {\n    branch: branch,\n    category: category,\n    both_branches: !branch || branch === 'both'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d7699bf0-1e51-4fb3-9624-1d2d01e2415c",
      "name": "Check Branch Location",
      "type": "n8n-nodes-base.if",
      "position": [
        -48,
        112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.branch }}",
              "value2": "rabieh",
              "operation": "equals"
            }
          ],
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "702992ea-c9cb-4210-9e32-669db1a2b642",
      "name": "Fetch Rabieh FAQ from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        176,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "FAQ_Rabieh",
          "cachedResultName": "FAQ_Rabieh"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f8867940-63f6-4240-96da-680ce2e6f6be",
      "name": "Fetch Bikfaya FAQ from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        176,
        208
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "FAQ_Bikfaya",
          "cachedResultName": "FAQ_Bikfaya"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3a20ec8c-6001-4ab6-94de-4e76b543cbb8",
      "name": "Format FAQ Data",
      "type": "n8n-nodes-base.code",
      "position": [
        400,
        112
      ],
      "parameters": {
        "jsCode": "// ============================================\n// ENHANCED FAQ FORMATTING FOR AI ACCURACY\n// Structures FAQs for maximum AI understanding\n// ============================================\n\nconst items = $input.all();\nconst branch = $node[\"Process Parameters\"].json.branch || 'both';\nconst categoryFilter = $node[\"Process Parameters\"].json.category || '';\n\nconsole.log('=== FORMAT ENHANCED FAQ DATA ===');\nconsole.log('Total FAQ items:', items.length);\nconsole.log('Branch:', branch);\nconsole.log('Category filter:', categoryFilter);\n\n// Helper: Extract keywords from text\nfunction extractKeywords(text) {\n  if (!text) return [];\n  \n  const stopWords = ['the', 'is', 'at', 'which', 'on', 'a', 'an', 'and', 'or', 'but', 'in', 'with', 'to', 'for', 'of', 'as', 'by', '\u0645\u0646', '\u0641\u064a', '\u0639\u0644\u0649', '\u0627\u0644\u0649', '\u0648', '\u0623\u0648', '\u0644\u0643\u0646'];\n  \n  return text\n    .toLowerCase()\n    .split(/[\\s,\u060c.\u061f?!]+/)\n    .filter(word => word.length > 2 && !stopWords.includes(word));\n}\n\n// Helper: Generate similar question variations\nfunction generateSimilarQuestions(question) {\n  const similar = [];\n  const q = question.toLowerCase();\n  \n  // Common variations\n  const patterns = [\n    { search: 'what are', replace: 'what is' },\n    { search: 'do you have', replace: 'is there' },\n    { search: 'how much', replace: 'what is the cost' },\n    { search: 'can i', replace: 'is it possible to' },\n    { search: 'where is', replace: 'location of' },\n    // Arabic variations\n    { search: '\u0634\u0648', replace: '\u0645\u0627\u0630\u0627' },\n    { search: '\u0648\u064a\u0646', replace: '\u0623\u064a\u0646' },\n    { search: '\u0643\u064a\u0641', replace: '\u0643\u064a\u0641\u064a\u0629' }\n  ];\n  \n  patterns.forEach(p => {\n    if (q.includes(p.search)) {\n      similar.push(q.replace(p.search, p.replace));\n    }\n  });\n  \n  return similar;\n}\n\n// Process each FAQ\nconst processedFAQs = items.map((item, index) => {\n  const json = item.json;\n  \n  const question = json.Question || json.question || '';\n  const answer = json.Answer || json.answer || '';\n  const tags = json.Tags || json.tags || '';\n  const imageURL = json.ImageURL || json.ImageURL1 || '';\n  \n  // Extract keywords from question and tags\n  const questionKeywords = extractKeywords(question);\n  const tagKeywords = extractKeywords(tags);\n  const allKeywords = [...new Set([...questionKeywords, ...tagKeywords])];\n  \n  // Generate similar question variations\n  const similarQuestions = generateSimilarQuestions(question);\n  \n  // Detect language of question\n  const hasArabic = /[\\u0600-\\u06FF]/.test(question);\n  const hasFrench = /[\u00e0\u00e2\u00e4\u00e7\u00e9\u00e8\u00ea\u00eb\u00ee\u00ef\u00f4\u00f6\u00f9\u00fb\u00fc\u00ff\u0153]/.test(question);\n  const questionLanguage = hasArabic ? 'ar' : hasFrench ? 'fr' : 'en';\n  \n  return {\n    id: index + 1,\n    question: question,\n    answer: answer,\n    tags: tags.split(',').map(t => t.trim().toLowerCase()).filter(t => t),\n    keywords: allKeywords,\n    similar_questions: similarQuestions,\n    language: questionLanguage,\n    branch: branch === 'both' ? (json.Branch || json.branch || 'unknown') : branch,\n    image_url: imageURL,\n    has_image: !!imageURL,\n    answer_length: answer.length,\n    category: tags.split(',')[0]?.trim().toLowerCase() || 'general'\n  };\n});\n\nconsole.log('Processed FAQs:', processedFAQs.length);\n\n// Filter by category if specified\nlet filteredFAQs = processedFAQs;\nif (categoryFilter) {\n  filteredFAQs = processedFAQs.filter(faq => \n    faq.category === categoryFilter || \n    faq.tags.includes(categoryFilter) ||\n    faq.keywords.includes(categoryFilter)\n  );\n  console.log('After category filter:', filteredFAQs.length);\n}\n\n// Group by category for better organization\nconst categories = [...new Set(filteredFAQs.map(f => f.category))];\nconst byCategory = {};\ncategories.forEach(cat => {\n  byCategory[cat] = filteredFAQs.filter(f => f.category === cat).length;\n});\n\n// Extract all unique keywords (helps AI understand what topics are covered)\nconst allUniqueKeywords = [...new Set(filteredFAQs.flatMap(f => f.keywords))];\n\n// Prepare structured output for AI\nconst structuredOutput = {\n  // Metadata\n  branch: branch,\n  total_faqs: filteredFAQs.length,\n  categories: categories,\n  category_counts: byCategory,\n  available_topics: allUniqueKeywords.slice(0, 50), // Top 50 keywords\n  languages_available: [...new Set(filteredFAQs.map(f => f.language))],\n  \n  // FAQ data (structured for AI)\n  faqs: filteredFAQs,\n  \n  // Search hints for AI\n  search_tips: {\n    total_keywords: allUniqueKeywords.length,\n    categories_available: categories.join(', '),\n    branches: branch === 'both' ? 'rabieh, bikfaya' : branch,\n    note: 'Each FAQ has: question, answer, tags, keywords, and similar_questions for matching'\n  }\n};\n\nconsole.log('=== STRUCTURED OUTPUT READY ===');\nconsole.log('Total FAQs:', structuredOutput.total_faqs);\nconsole.log('Categories:', structuredOutput.categories);\nconsole.log('Languages:', structuredOutput.languages_available);\nconsole.log('Sample FAQ:', structuredOutput.faqs[0]);\n\nreturn [{ json: structuredOutput }];"
      },
      "typeVersion": 2
    },
    {
      "id": "2aeed78c-4720-48bc-8b21-60c24b3edf2f",
      "name": "Fetch Config from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -448,
        112
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Gymbot_Config"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "4c9f7e20-8758-469f-8745-a9e6e707a05b",
  "connections": {
    "Process Parameters": {
      "main": [
        [
          {
            "node": "Check Branch Location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Branch Location": {
      "main": [
        [
          {
            "node": "Fetch Rabieh FAQ from Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Bikfaya FAQ from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Config from Sheets": {
      "main": [
        [
          {
            "node": "Process Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Execution Start": {
      "main": [
        [
          {
            "node": "Fetch Config from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Rabieh FAQ from Sheets": {
      "main": [
        [
          {
            "node": "Format FAQ Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Bikfaya FAQ from Sheets": {
      "main": [
        [
          {
            "node": "Format FAQ Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}