{
  "metadata": {
    "version": 1,
    "scenario": {
      "name": "FundUp - Prospection - Google PSE -> Extract -> Google Sheets",
      "description": "Loop departments, search with Google Programmable Search, fetch pages, extract emails & partner page, write to Google Sheets."
    }
  },
  "flow": [
    {
      "id": 1,
      "module": "tools:Scheduler",
      "version": 1,
      "parameters": {
        "type": "daily",
        "time": "02:00"
      }
    },
    {
      "id": 2,
      "module": "google-sheets:SearchRows",
      "version": 1,
      "parameters": {
        "spreadsheetId": "YOUR_SPREADSHEET_ID",
        "sheetName": "PARAMS",
        "query": "enabled = TRUE",
        "limit": 1
      }
    },
    {
      "id": 3,
      "module": "tools:SetVariable",
      "version": 1,
      "parameters": {
        "name": "departements_array",
        "value": "{{split(2.departements; \",\")}}"
      }
    },
    {
      "id": 4,
      "module": "tools:Iterator",
      "version": 1,
      "parameters": {
        "array": "{{3.departements_array}}"
      }
    },
    {
      "id": 5,
      "module": "tools:SetVariable",
      "version": 1,
      "parameters": {
        "name": "departement",
        "value": "{{trim(4.value)}}"
      }
    },
    {
      "id": 6,
      "module": "tools:SetVariable",
      "version": 1,
      "parameters": {
        "name": "query",
        "value": "{{2.type_organisation}} département {{5.departement}} partenaires sponsoring contact site:.fr"
      }
    },
    {
      "id": 7,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "GET",
        "url": "https://www.googleapis.com/customsearch/v1",
        "query": [
          { "name": "key", "value": "YOUR_GOOGLE_API_KEY" },
          { "name": "cx", "value": "YOUR_GOOGLE_CX" },
          { "name": "q", "value": "{{6.query}}" },
          { "name": "num", "value": "{{2.max_search_results}}" },
          { "name": "gl", "value": "fr" },
          { "name": "hl", "value": "fr" }
        ],
        "headers": []
      }
    },
    {
      "id": 8,
      "module": "tools:Iterator",
      "version": 1,
      "parameters": {
        "array": "{{7.items}}"
      }
    },
    {
      "id": 9,
      "module": "tools:Filter",
      "version": 1,
      "parameters": {
        "conditions": [
          "{{not(contains(8.link; \"facebook.com\"))}}",
          "{{not(contains(8.link; \"instagram.com\"))}}",
          "{{not(contains(8.link; \"linkedin.com\"))}}",
          "{{not(contains(8.link; \"wikipedia.org\"))}}",
          "{{not(contains(8.link; \"ticketmaster\"))}}"
        ]
      }
    },
    {
      "id": 10,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "GET",
        "url": "{{8.link}}",
        "headers": [
          { "name": "User-Agent", "value": "Mozilla/5.0" }
        ]
      }
    },
    {
      "id": 11,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/responses",
        "headers": [
          { "name": "Authorization", "value": "Bearer YOUR_OPENAI_API_KEY" },
          { "name": "Content-Type", "value": "application/json" }
        ],
        "bodyType": "raw",
        "body": "{\"model\":\"gpt-4.1-mini\",\"input\":[{\"role\":\"user\",\"content\":\"Tu analyses une page web (HTML). Objectif: identifier les meilleurs liens vers: 1) la page de contact 2) la page partenaires / sponsoring / mécénat / devenir partenaire. Retourne uniquement un JSON valide: {\\\"contact_page_url\\\":\\\"string|null\\\",\\\"partner_page_url\\\":\\\"string|null\\\",\\\"is_official_site\\\":true|false}. Règles: Les URLs doivent appartenir au même site. Si aucun lien clair, null. is_official_site=false si article, billetterie ou annuaire non officiel. Ne devine rien. URL actuelle: {{8.link}} HTML: {{10.body}}\"}]}",
        "timeout": 60
      }
    },
    {
      "id": 12,
      "module": "json:ParseJSON",
      "version": 1,
      "parameters": {
        "json": "{{11.output_text}}",
        "schema": {
          "type": "object",
          "properties": {
            "contact_page_url": { "type": ["string", "null"] },
            "partner_page_url": { "type": ["string", "null"] },
            "is_official_site": { "type": "boolean" }
          },
          "required": ["contact_page_url", "partner_page_url", "is_official_site"]
        }
      }
    },
    {
      "id": 13,
      "module": "tools:Filter",
      "version": 1,
      "parameters": {
        "conditions": [
          "{{12.is_official_site}}"
        ]
      }
    },
    {
      "id": 14,
      "module": "tools:Sleep",
      "version": 1,
      "parameters": {
        "milliseconds": 800
      }
    },
    {
      "id": 15,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "GET",
        "url": "{{12.contact_page_url}}",
        "headers": [
          { "name": "User-Agent", "value": "Mozilla/5.0" }
        ]
      }
    },
    {
      "id": 16,
      "module": "tools:Sleep",
      "version": 1,
      "parameters": {
        "milliseconds": 800
      }
    },
    {
      "id": 17,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "GET",
        "url": "{{12.partner_page_url}}",
        "headers": [
          { "name": "User-Agent", "value": "Mozilla/5.0" }
        ]
      }
    },
    {
      "id": 18,
      "module": "tools:TextAggregator",
      "version": 1,
      "parameters": {
        "texts": [
          "### SOURCE: {{8.link}}\n{{10.body}}",
          "### SOURCE: {{12.contact_page_url}}\n{{15.body}}",
          "### SOURCE: {{12.partner_page_url}}\n{{17.body}}"
        ],
        "outputName": "combined_page_text"
      }
    },
    {
      "id": 19,
      "module": "http:MakeARequest",
      "version": 1,
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/responses",
        "headers": [
          { "name": "Authorization", "value": "Bearer YOUR_OPENAI_API_KEY" },
          { "name": "Content-Type", "value": "application/json" }
        ],
        "bodyType": "raw",
        "body": "{\"model\":\"gpt-4.1-mini\",\"input\":[{\"role\":\"user\",\"content\":\"Tu es un assistant d’extraction B2B. À partir des sources ci-dessous (pages web publiques), extrais UNIQUEMENT ce qui est explicitement présent. Retourne uniquement du JSON valide: {\\\"name\\\":\\\"string|null\\\",\\\"city\\\":\\\"string|null\\\",\\\"website\\\":\\\"string|null\\\",\\\"contact_email\\\":\\\"string|null\\\",\\\"partnership_email\\\":\\\"string|null\\\",\\\"partner_page_url\\\":\\\"string|null\\\",\\\"sources\\\":[\\\"...\\\"],\\\"confidence\\\":0,\\\"notes\\\":\\\"string\\\"}. Règles: Ne jamais inventer d’email. Priorité emails génériques et partenariats. Évite emails personnels nominatif. Si seulement formulaire: emails=null et note. Département: {{5.departement}} Type: {{2.type_organisation}} Sources: {{18.combined_page_text}}\"}]}",
        "timeout": 60
      }
    },
    {
      "id": 20,
      "module": "json:ParseJSON",
      "version": 1,
      "parameters": {
        "json": "{{19.output_text}}",
        "schema": {
          "type": "object",
          "properties": {
            "name": { "type": ["string", "null"] },
            "city": { "type": ["string", "null"] },
            "website": { "type": ["string", "null"] },
            "contact_email": { "type": ["string", "null"] },
            "partnership_email": { "type": ["string", "null"] },
            "partner_page_url": { "type": ["string", "null"] },
            "sources": { "type": "array", "items": { "type": "string" } },
            "confidence": { "type": "number" },
            "notes": { "type": "string" }
          },
          "required": ["name", "city", "website", "contact_email", "partnership_email", "partner_page_url", "sources", "confidence", "notes"]
        }
      }
    },
    {
      "id": 21,
      "module": "google-sheets:SearchRows",
      "version": 1,
      "parameters": {
        "spreadsheetId": "YOUR_SPREADSHEET_ID",
        "sheetName": "OUTPUT",
        "query": "website = \"{{20.website}}\"",
        "limit": 1
      }
    },
    {
      "id": 22,
      "module": "tools:Router",
      "version": 1,
      "routes": [
        {
          "name": "New",
          "filter": "{{21.total == 0}}",
          "steps": [
            {
              "id": 23,
              "module": "tools:SetVariable",
              "version": 1,
              "parameters": {
                "name": "status",
                "value": "{{if(20.confidence < 70; \"REVIEW\"; \"NEW\")}}"
              }
            },
            {
              "id": 24,
              "module": "google-sheets:AddRow",
              "version": 1,
              "parameters": {
                "spreadsheetId": "YOUR_SPREADSHEET_ID",
                "sheetName": "OUTPUT",
                "values": {
                  "created_at": "{{now}}",
                  "departement": "{{5.departement}}",
                  "type": "{{2.type_organisation}}",
                  "name": "{{20.name}}",
                  "city": "{{20.city}}",
                  "website": "{{20.website}}",
                  "contact_email": "{{20.contact_email}}",
                  "partnership_email": "{{20.partnership_email}}",
                  "partner_page_url": "{{20.partner_page_url}}",
                  "sources": "{{join(20.sources; \" | \")}}",
                  "confidence": "{{20.confidence}}",
                  "notes": "{{20.notes}}",
                  "status": "{{23.status}}"
                }
              }
            }
          ]
        },
        {
          "name": "Duplicate",
          "filter": "{{21.total > 0}}",
          "steps": [
            {
              "id": 25,
              "module": "tools:Sleep",
              "version": 1,
              "parameters": { "milliseconds": 200 }
            }
          ]
        }
      ]
    },
    {
      "id": 26,
      "module": "tools:Sleep",
      "version": 1,
      "parameters": {
        "milliseconds": 1200
      }
    }
  ]
}