{
  "name": "HoL — Analytics L4: Monday morning summary",
  "nodes": [
    {
      "name": "Monday 8am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [-460, 0],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      }
    },
    {
      "name": "Date range",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-240, 0],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "d1",
              "name": "plausible_start",
              "value": "={{ $now.minus({ weeks: 1 }).startOf('week').toFormat('yyyy-MM-dd') }}",
              "type": "string"
            },
            {
              "id": "d2",
              "name": "plausible_end",
              "value": "={{ $now.minus({ weeks: 1 }).endOf('week').toFormat('yyyy-MM-dd') }}",
              "type": "string"
            },
            {
              "id": "d3",
              "name": "umami_start",
              "value": "={{ $now.minus({ weeks: 1 }).startOf('week').toMillis() }}",
              "type": "number"
            },
            {
              "id": "d4",
              "name": "umami_end",
              "value": "={{ $now.minus({ weeks: 1 }).endOf('week').toMillis() }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "name": "Plausible stats",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [-20, 0],
      "parameters": {
        "method": "POST",
        "url": "https://plausible.yourdomain.example/api/v2/query",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"site_id\": \"your-domain.com\",\n  \"metrics\": [\"visitors\", \"pageviews\"],\n  \"date_range\": [\"{{ $json.plausible_start }}\", \"{{ $json.plausible_end }}\"]\n}",
        "options": {}
      }
    },
    {
      "name": "Umami login",
      "notesInFlow": false,
      "notes": "Uses a Custom Auth credential whose JSON definition supplies the Umami username and password as a body object — see Lesson 4, step 3. Select your own credential before running this node; do not paste a password into this node's parameters.",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [200, 0],
      "parameters": {
        "method": "POST",
        "url": "https://umami.yourdomain.example/api/auth/login",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpCustomAuth",
        "options": {}
      }
    },
    {
      "name": "Umami stats",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [420, 0],
      "parameters": {
        "url": "=https://umami.yourdomain.example/api/websites/your-website-id/stats",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "startAt",
              "value": "={{ $('Date range').first().json.umami_start }}"
            },
            {
              "name": "endAt",
              "value": "={{ $('Date range').first().json.umami_end }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Umami login').first().json.token }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "name": "Umami top pages",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [640, 0],
      "parameters": {
        "url": "=https://umami.yourdomain.example/api/websites/your-website-id/metrics",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "type",
              "value": "path"
            },
            {
              "name": "startAt",
              "value": "={{ $('Date range').first().json.umami_start }}"
            },
            {
              "name": "endAt",
              "value": "={{ $('Date range').first().json.umami_end }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Umami login').first().json.token }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "name": "Merge and format",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [860, 0],
      "parameters": {
        "jsCode": "const p = $('Plausible stats').first().json;\nconst u = $('Umami stats').first().json;\nconst topPages = $('Umami top pages').all();\n\nconst pages = topPages.slice(0, 3).map(r => `  ${r.json.x} — ${r.json.y}`).join('\\n');\n\nreturn [{ json: { text: [\n  'Last week (Mon–Sun)',\n  `Plausible — visitors ${p.results?.[0]?.metrics?.[0] ?? '?'}, pageviews ${p.results?.[0]?.metrics?.[1] ?? '?'}`,\n  `Umami — visitors ${u.visitors ?? '?'}, pageviews ${u.pageviews ?? '?'}`,\n  'Umami top pages:',\n  pages,\n  '(two tools, two measurements — do not add them together)',\n].join('\\n') } }];"
      }
    },
    {
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [1080, 0],
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "#analytics",
          "mode": "name"
        },
        "text": "={{ $json.text }}",
        "otherOptions": {}
      }
    }
  ],
  "connections": {
    "Monday 8am": {
      "main": [
        [
          {
            "node": "Date range",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Date range": {
      "main": [
        [
          {
            "node": "Plausible stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Plausible stats": {
      "main": [
        [
          {
            "node": "Umami login",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Umami login": {
      "main": [
        [
          {
            "node": "Umami stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Umami stats": {
      "main": [
        [
          {
            "node": "Umami top pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Umami top pages": {
      "main": [
        [
          {
            "node": "Merge and format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge and format": {
      "main": [
        [
          {
            "node": "Post to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
