{
  "name": "Send weekly Skool community events to WhatsApp (Evolution API)",
  "nodes": [
    {
      "parameters": {
        "content": "## 1\ufe0f\u20e3 Trigger & config\nWeekly schedule (Mon 9am). Edit everything in the **Config** node \u2014 the only one you touch.",
        "height": 320,
        "width": 500,
        "color": 5
      },
      "id": "38ec61f8b81e48868d7de96a892d5b4c",
      "name": "Group 1 \u2014 Trigger & config",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -60,
        120
      ]
    },
    {
      "parameters": {
        "content": "## 2\ufe0f\u20e3 Read Skool events\nFresh `auth:login` each run (no stored cookies, never expires, ~$0.02), then `events:list` via the Skool All-in-One API actor.",
        "height": 320,
        "width": 920,
        "color": 4
      },
      "id": "39de6731433a4db69fc522b0388a95fb",
      "name": "Group 2 \u2014 Read Skool events",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        400,
        120
      ]
    },
    {
      "parameters": {
        "content": "## 3\ufe0f\u20e3 Filter & format\nKeep events in the next 7 days, format as WhatsApp markdown. **Silent skip** if none.",
        "height": 320,
        "width": 480,
        "color": 6
      },
      "id": "353a56355be244369e676b641adda44a",
      "name": "Group 3 \u2014 Filter & format",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1300,
        120
      ]
    },
    {
      "parameters": {
        "content": "## 4\ufe0f\u20e3 Send to WhatsApp\nPOST to your group via Evolution `sendText`. Swap for Telegram/Slack/email if needed.",
        "height": 320,
        "width": 320,
        "color": 2
      },
      "id": "4f323edfa8a84e74849f815c1cb7c39a",
      "name": "Group 4 \u2014 Send to WhatsApp",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1740,
        120
      ]
    },
    {
      "parameters": {
        "content": "## \ud83d\udcc5 Weekly Skool events \u2192 WhatsApp\nEvery Monday, post your community's upcoming events to a WhatsApp group. Powered by the Skool All-in-One API actor.\n\n**Actor:** https://apify.com/cristiantala/skool-all-in-one-api\n**Guide:** https://ctala.github.io/skool-api-docs/recipes/automate-skool-events/",
        "height": 210,
        "width": 560,
        "color": 3
      },
      "id": "30f308f4ae3f46e9966f859ec74642d3",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -680,
        -130
      ]
    },
    {
      "parameters": {
        "content": "## \u2699\ufe0f Setup & configuration (5 min)\n\n**1. Apify token** \u2014 free tier at apify.com \u2192 console.apify.com/account/integrations. Set it as the `apifyApi` credential on the 4 Apify nodes.\n\n**2. Edit the `Config` node:**\n- `email` / `password` \u2014 your Skool admin login\n- `groupSlug` \u2014 the part after skool.com/\n- `evoUrl` \u2014 your Evolution API base URL\n- `evoKey` \u2014 your Evolution API key\n- `evoInstance` \u2014 your Evolution instance name\n- `targetGroupJid` \u2014 your WhatsApp group JID (Evolution: GET /group/fetchAllGroups \u2192 id ending in `@g.us`)\n\n**3. Schedule** \u2014 Cron runs Mon 09:00. Edit time + the TZ/locale in the Code node.\n\n**4. Test** \u2014 click \"Test workflow\". Posts only if there are upcoming events.\n\n_No Skool community yet? https://www.skool.com/signup?ref=114150f098fc40ba9b365fa78be01a63_",
        "height": 470,
        "width": 560,
        "color": 7
      },
      "id": "a18ed7622c8c4da185ec88586d71d658",
      "name": "Setup",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -680,
        100
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "id": "bba59cab-7681-47f0-b615-4bd88487baaa",
      "name": "Cron Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        240
      ],
      "notes": "Runs weekly (Mon 9am) \u2014 edit for your timezone",
      "notesInFlow": true
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "33315e07-e640-4dd5-9038-6c674d720776",
              "name": "email",
              "value": "__REPLACE_WITH_SKOOL_EMAIL__",
              "type": "string"
            },
            {
              "id": "14117d29-cc3d-4779-a3af-ce6f6e342fcd",
              "name": "password",
              "value": "__REPLACE_WITH_SKOOL_PASSWORD__",
              "type": "string"
            },
            {
              "id": "0361d596-58e2-4b22-a9b3-094f4adec088",
              "name": "groupSlug",
              "value": "your-community-slug",
              "type": "string"
            },
            {
              "id": "de5bf661-cd16-4446-ae30-5d7220b6b18a",
              "name": "evoUrl",
              "value": "https://YOUR-EVOLUTION-API.com",
              "type": "string"
            },
            {
              "id": "e466a392-53d8-4a86-beb7-cab1361abf62",
              "name": "evoKey",
              "value": "__REPLACE_WITH_EVOLUTION_API_KEY__",
              "type": "string"
            },
            {
              "id": "a6ec3e68-271c-4984-958c-17888540aed0",
              "name": "evoInstance",
              "value": "YOUR_EVOLUTION_INSTANCE",
              "type": "string"
            },
            {
              "id": "9167f746-524c-4c97-bbae-c1dfc64866a7",
              "name": "targetGroupJid",
              "value": "YOUR_GROUP_JID@g.us",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        224,
        240
      ],
      "id": "e11435bf-de29-4250-b8ae-d6ad14406e05",
      "notes": "\u2699\ufe0f Edit ALL your settings here \u2014 the only node you configure",
      "notesInFlow": true
    },
    {
      "parameters": {
        "actorId": {
          "__rl": true,
          "value": "g2VGrINIS7pb8t2bs",
          "mode": "list",
          "cachedResultName": "Skool All-in-One API",
          "cachedResultUrl": "https://console.apify.com/actors/g2VGrINIS7pb8t2bs/input"
        },
        "customBody": "={{ JSON.stringify({ action: \"auth:login\", email: $(\"Config\").first().json.email, password: $(\"Config\").first().json.password, groupSlug: $(\"Config\").first().json.groupSlug }) }}"
      },
      "name": "Skool Login",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        448,
        240
      ],
      "id": "27a49b53-0e79-47d0-958f-16c470e73f1b",
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Fresh auth:login each run \u2014 no stored cookies to expire",
      "notesInFlow": true
    },
    {
      "parameters": {
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}",
        "options": {}
      },
      "name": "Get Login Cookies",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        672,
        240
      ],
      "id": "42454997-f8b9-4e41-a4e4-f91ddaf15f40",
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Reads the cookies returned by the login run",
      "notesInFlow": true
    },
    {
      "parameters": {
        "actorId": {
          "__rl": true,
          "value": "g2VGrINIS7pb8t2bs",
          "mode": "list",
          "cachedResultName": "Skool All-in-One API",
          "cachedResultUrl": "https://console.apify.com/actors/g2VGrINIS7pb8t2bs/input"
        },
        "customBody": "={{ JSON.stringify({ action: \"events:list\", cookies: $json.cookies, groupSlug: $(\"Config\").first().json.groupSlug }) }}"
      },
      "name": "Get Events from Skool",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        896,
        240
      ],
      "id": "0ead0295-fd2d-4d54-ac9a-bfebd6931e36",
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "notes": "events:list \u2014 fetches your community calendar via the actor",
      "notesInFlow": true
    },
    {
      "parameters": {
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}",
        "options": {}
      },
      "name": "Get Events Results",
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        1120,
        240
      ],
      "id": "b750d8fa-f513-41c8-8525-668fa7dd2111",
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "notes": "Reads the events dataset from the previous run",
      "notesInFlow": true
    },
    {
      "parameters": {
        "jsCode": "// Filter events to the next 7 days and format them for WhatsApp (markdown), one link per event.\nconst cfg = $('Config').first().json;\nconst raw = $input.all().map(i => i.json);\nconst events = Array.isArray(raw) ? raw : [];\n\nconst now = new Date();\nconst in7d = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);\n\nconst upcoming = events\n  .filter(e => e && e.startAt)\n  .map(e => ({ ...e, _start: new Date(e.startAt) }))\n  .filter(e => !isNaN(e._start) && e._start > now && e._start <= in7d)\n  .sort((a, b) => a._start - b._start);\n\nif (upcoming.length === 0) {\n  return [{ json: { skip: true, count: 0 } }];\n}\n\n// Edit TZ and locale to match your community.\nconst TZ = 'UTC';\nconst dayFmt = new Intl.DateTimeFormat('en-US', { timeZone: TZ, weekday: 'short', day: '2-digit', month: 'short' });\nconst timeFmt = new Intl.DateTimeFormat('en-US', { timeZone: TZ, hour: '2-digit', minute: '2-digit', hour12: false });\n\nconst eventUrl = (ev) => `https://www.skool.com/${cfg.groupSlug}/calendar?event=${ev.id}`;\n\nconst lines = [\"*This week's events*\", ''];\nfor (const ev of upcoming) {\n  lines.push(`*${dayFmt.format(ev._start)} \u00b7 ${timeFmt.format(ev._start)}*`);\n  lines.push(ev.title);\n  lines.push(eventUrl(ev));\n  lines.push('');\n}\n\nconst text = lines.join('\\n');\nreturn [{ json: { skip: false, count: upcoming.length, text, targetGroupJid: cfg.targetGroupJid, evoUrl: cfg.evoUrl, evoKey: cfg.evoKey, evoInstance: cfg.evoInstance } }];\n"
      },
      "id": "b8aba0d3-f0a8-4bae-8526-0d4384980c76",
      "name": "Filter + Format Events",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1344,
        240
      ],
      "notes": "Next 7 days \u2192 WhatsApp markdown. Silent skip if no events",
      "notesInFlow": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "46ff33a0-8c11-415a-bcda-02c4e19657c9",
              "leftValue": "={{ $json.skip }}",
              "rightValue": false,
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "631a03b9-a0c8-4f29-a2b8-db7024955f7d",
      "name": "Has Events?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1568,
        240
      ],
      "notes": "Stops here if there are no upcoming events",
      "notesInFlow": true
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $json.evoUrl }}/message/sendText/{{ encodeURIComponent($json.evoInstance) }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "={{ $json.evoKey }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={\n  \"number\": {{ JSON.stringify($json.targetGroupJid) }},\n  \"text\": {{ JSON.stringify($json.text) }}\n}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "137aec8c-3d48-41aa-9cb6-a8d1bb542b1e",
      "name": "Send to VIP via Evolution",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1792,
        240
      ],
      "retryOnFail": true,
      "notes": "POST the message to your WhatsApp group via Evolution API",
      "notesInFlow": true
    }
  ],
  "connections": {
    "Cron Trigger": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "Skool Login",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skool Login": {
      "main": [
        [
          {
            "node": "Get Login Cookies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Login Cookies": {
      "main": [
        [
          {
            "node": "Get Events from Skool",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Events from Skool": {
      "main": [
        [
          {
            "node": "Get Events Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Events Results": {
      "main": [
        [
          {
            "node": "Filter + Format Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter + Format Events": {
      "main": [
        [
          {
            "node": "Has Events?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Events?": {
      "main": [
        [
          {
            "node": "Send to VIP via Evolution",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "UTC",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": ""
  },
  "staticData": {
    "node:Cron Trigger": {
      "recurrenceRules": []
    }
  },
  "tags": []
}