{
  "id": "OFpPRbCwK58gYKtz",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Facebook Event RSVP Tracking with Airtable Capacity Control & Slack Alerts",
  "tags": [],
  "nodes": [
    {
      "id": "507648e3-66b0-48dc-a401-8a14222d300b",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "42dbca73-4680-421d-b7f7-bfdadb696a1c",
              "name": "eventId",
              "type": "string",
              "value": "={{ $json.entry[0].changes[0].value.event_id }}"
            },
            {
              "id": "8893bbf7-54d5-4f41-b92f-38ac5e1695a3",
              "name": "userId",
              "type": "string",
              "value": "={{ $json.entry[0].changes[0].value.user_id }}"
            },
            {
              "id": "c7182669-f543-420a-8106-08d60d73723b",
              "name": "rsvpStatus",
              "type": "string",
              "value": "={{ $json.entry[0].changes[0].value.rsvp_status }}"
            },
            {
              "id": "e27c6983-3f19-4900-a004-f93b06d40551",
              "name": "receivedAt",
              "type": "string",
              "value": "={{new Date().toISOString()}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2230e4bf-51da-4da6-8962-d5368f5a39fe",
      "name": "Facebook Event RSVP Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        0
      ],
      "parameters": {
        "path": "facebook-event-rsvp",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "82e70b09-f0ac-424b-923f-2870d5d33fd2",
      "name": "Upsert RSVP in Airtable",
      "type": "n8n-nodes-base.airtable",
      "position": [
        544,
        0
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appipUxLpxPEKRXrJ",
          "cachedResultUrl": "",
          "cachedResultName": "Fake Review Detector"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblvi5s5CkzrBlFaw",
          "cachedResultUrl": "",
          "cachedResultName": "LogAtendeeData"
        },
        "columns": {
          "value": {
            "user_Id": "={{ $json.userId }}",
            "event_Id": "={{ $json.eventId }}",
            "receivedAt": "={{ $json.receivedAt }}",
            "rsvpStatus": "={{ $json.rsvpStatus }}"
          },
          "schema": [
            {
              "id": "event_Id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "event_Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "user_Id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "user_Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rsvpStatus",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "rsvpStatus",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "receivedAt",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "receivedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "event_Id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "upsert"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "bb718187-c039-4bce-b550-41829f5466a3",
      "name": "Fetch Attending RSVPs for Event",
      "type": "n8n-nodes-base.airtable",
      "position": [
        944,
        0
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appipUxLpxPEKRXrJ",
          "cachedResultUrl": "",
          "cachedResultName": "Fake Review Detector"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblvi5s5CkzrBlFaw",
          "cachedResultUrl": "",
          "cachedResultName": "LogAtendeeData"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "=AND(\n  {event_Id} = '{{ $json.fields.event_Id }}',\n  {rsvpStatus} = 'attending'\n)"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ef306c7b-c5b3-4f8c-b444-e762984b22c9",
      "name": "Is Event Capacity Exceeded?",
      "type": "n8n-nodes-base.if",
      "position": [
        1152,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d4d753fe-bb3f-4216-b302-6b400ac3add1",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{$items().length}}",
              "rightValue": 50
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "27b9d471-5aa6-4fa5-a6d0-45e0e380e33c",
      "name": "Is Capacity Alert Already Sent?",
      "type": "n8n-nodes-base.if",
      "position": [
        1504,
        -16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "e197a3cd-c197-4279-9dab-5d93e895ad64",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.capacity_alert_sent }}",
              "rightValue": ""
            },
            {
              "id": "b395e2c8-420d-4af7-907e-bb2030f47f2c",
              "operator": {
                "type": "boolean",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.capacity_alert_sent }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5bdf8440-96c3-4058-8ff0-2620cf138ca2",
      "name": "Send Slack Capacity Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1920,
        -16
      ],
      "parameters": {
        "text": "= Event Capacity Alert  Event ID:  {{ $json.event_Id }}Attendees: {{$items().length}} / 50",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8a9f8f67-dbf3-4538-8628-46eedf22e06a",
      "name": "Mark Capacity Alert as Sent",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2096,
        -16
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appipUxLpxPEKRXrJ",
          "cachedResultUrl": "https://airtable.com/appipUxLpxPEKRXrJ",
          "cachedResultName": "Fake Review Detector"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblvi5s5CkzrBlFaw",
          "cachedResultUrl": "",
          "cachedResultName": "LogAtendeeData"
        },
        "columns": {
          "value": {
            "id": "={{ $('Is Event Capacity Exceeded?').item.json.id }}",
            "capacity_alert_sent": true
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true
            },
            {
              "id": "event_Id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "event_Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "user_Id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "user_Id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rsvpStatus",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "rsvpStatus",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "receivedAt",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "receivedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "capacity_alert_sent",
              "type": "boolean",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "capacity_alert_sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "upsert"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "3d63d981-0633-4059-8675-6645efa3a634",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 336,
        "content": "## Receive Event RSVP\nThis section captures new RSVP responses from a Facebook event and prepares the attendee data in a clean, usable format for further processing."
      },
      "typeVersion": 1
    },
    {
      "id": "e40c6b40-d4a0-4f89-b6b9-b183fb34f4ff",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 336,
        "content": "## Save Attendee Details\nStores or updates attendee RSVP information in Airtable, ensuring no duplicate records are created and the latest RSVP status is always saved."
      },
      "typeVersion": 1
    },
    {
      "id": "b8136d2b-39a7-44cc-9fd1-760a3764fd43",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 336,
        "content": "## Event Capacity Calculation\nCounts how many people are attending the event and checks whether the total number has reached or crossed the maximum allowed capacity."
      },
      "typeVersion": 1
    },
    {
      "id": "f4fd2115-78df-46b9-bfe3-f810574ddd1b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 336,
        "content": "## Alert Control & Deduplication\nChecks whether a capacity alert has already been sent for the event to prevent duplicate notifications when additional RSVPs arrive after capacity is reached."
      },
      "typeVersion": 1
    },
    {
      "id": "b03b4aad-c476-4aae-babb-aa9193a561a5",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 336,
        "content": "## Team Notification & State Update\nSends a real-time Slack alert to the team when event capacity is crossed and updates Airtable to mark the alert as sent for future executions."
      },
      "typeVersion": 1
    },
    {
      "id": "dd2e1329-7ffc-4f06-ba4f-2f3012f44ebb",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -832
      ],
      "parameters": {
        "width": 416,
        "height": 848,
        "content": "## How This Workflow Works\n**The workflow starts automatically whenever a new RSVP is received for a Facebook Event.**\n\n**The RSVP data is captured through a webhook and cleaned to keep only important details like event ID, user ID, RSVP status and time.**\n\n**Attendee information is saved in Airtable using upsert logic, which prevents duplicate records and keeps RSVP status up to date.**\n\n**The workflow then counts how many people are marked as attending for the event.**\n\n**This count is compared against the event\u2019s maximum capacity.**\n\n**If the capacity is reached or exceeded, the workflow checks whether the team has already been notified.**\n\n**If no alert was sent earlier, a Slack message is sent to inform the team that the event is full.**\n\n**Finally, Airtable is updated to record that the capacity alert has been sent, preventing duplicate notifications.**\n\n## Setup Steps\n\n**Create a webhook to receive Facebook RSVP events.**\n\n**Normalize the incoming data using a Set node.**\n\n**Store or update attendee records in Airtable.**\n\n**Count confirmed attendees and compare with event capacity.**\n\n**Send a Slack alert when capacity is reached and mark it as sent.**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "8d79b884-9ab8-433f-861e-1384a86e1604",
  "connections": {
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Upsert RSVP in Airtable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert RSVP in Airtable": {
      "main": [
        [
          {
            "node": "Fetch Attending RSVPs for Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Slack Capacity Alert": {
      "main": [
        [
          {
            "node": "Mark Capacity Alert as Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Facebook Event RSVP Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Event Capacity Exceeded?": {
      "main": [
        [
          {
            "node": "Is Capacity Alert Already Sent?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Fetch Attending RSVPs for Event": {
      "main": [
        [
          {
            "node": "Is Event Capacity Exceeded?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Capacity Alert Already Sent?": {
      "main": [
        [],
        [
          {
            "node": "Send Slack Capacity Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}