{
  "id": "dSEgsAFEb4ekvPgY",
  "name": "Calendly Booking Link Generator",
  "tags": [],
  "nodes": [
    {
      "id": "c3c09ac6-013d-4a7a-aa62-76f868baf7bc",
      "name": "\ud83d\udccb WORKFLOW OVERVIEW",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -128
      ],
      "parameters": {
        "color": 5,
        "width": 820,
        "height": 620,
        "content": "## \ud83d\udd17 Calendly Booking Link Generator\n\n**What this workflow does:**\n1. \ud83d\udd10 Authenticates with Calendly API\n2. \ud83d\udccb Gets your event types\n3. \ud83d\udd17 Creates single-use booking links\n4. \u2709\ufe0f Personalizes links with recipient info\n5. \ud83d\udcca Logs generated links to Google Sheets\n6. \ud83d\udcac Notifies via Slack (optional)\n\n**Why Single-Use Links?**\nCalendly API does NOT allow direct booking.\nInstead, generate personalized links that:\n- Expire after one booking\n- Pre-fill invitee name/email\n- Can be tracked\n- Work seamlessly\n\n**Use Cases:**\n- CRM automation\n- Sales outreach\n- Customer support\n- Automated follow-ups"
      },
      "typeVersion": 1
    },
    {
      "id": "5fa6844e-dd8a-4f9b-8b28-60ee68c443aa",
      "name": "\u2699\ufe0f SETUP GUIDE",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        -128
      ],
      "parameters": {
        "color": 6,
        "width": 860,
        "height": 620,
        "content": "## \u2699\ufe0f Setup Instructions\n\n**Step 1: Calendly OAuth2**\n1. Go to calendly.com/integrations\n2. Click \"API & Webhooks\"\n3. Set up OAuth2 application\n4. In n8n, add Calendly OAuth2 credential\n\n**Step 2: Google Sheets (Optional)**\n1. Create a spreadsheet for tracking\n2. Headers: Name, Email, Link, Event, Created\n3. Add Google Sheets OAuth2 credential\n4. Update document ID in node\n\n**Step 3: Slack (Optional)**\n1. Create Slack app at api.slack.com\n2. Add bot token scopes\n3. Add Slack credential in n8n\n4. Set channel ID\n\n---\n\n**\u26a0\ufe0f Important Notes:**\n- Single-use links expire after:\n  - 1 booking, OR\n  - 90 days unused\n- Links are unique per generation\n- Cannot be modified after creation"
      },
      "typeVersion": 1
    },
    {
      "id": "130cc077-ece1-4168-b37f-c1061ac0af77",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "notes": "POST with recipient details",
      "position": [
        368,
        544
      ],
      "parameters": {
        "path": "generate-calendly-link",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "94e36147-7595-40bb-9fcf-66c636a5d468",
      "name": "\ud83c\udfaf INPUT FORMAT",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        480
      ],
      "parameters": {
        "color": 5,
        "width": 344,
        "height": 240,
        "content": "## \ud83c\udfaf Webhook Input\n\n**POST Body:**\n```json\n{\n  \"name\": \"John Doe\",\n  \"email\": \"john@example.com\",\n  \"event_type_uri\": \"optional\"\n}\n```\n\nIf no event_type_uri,\nuses first active type."
      },
      "typeVersion": 1
    },
    {
      "id": "0798031a-8ff5-498a-ab6e-8e92cf0b621d",
      "name": "Set Configuration",
      "type": "n8n-nodes-base.set",
      "notes": "Extract recipient info from request",
      "position": [
        592,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg1",
              "name": "recipient_email",
              "type": "string",
              "value": "={{ $json.body?.email || 'test@example.com' }}"
            },
            {
              "id": "cfg2",
              "name": "recipient_name",
              "type": "string",
              "value": "={{ $json.body?.name || 'Test User' }}"
            },
            {
              "id": "cfg3",
              "name": "requested_event_type",
              "type": "string",
              "value": "={{ $json.body?.event_type_uri || '' }}"
            },
            {
              "id": "cfg4",
              "name": "utm_source",
              "type": "string",
              "value": "={{ $json.body?.utm_source || 'n8n' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6d65c93a-0934-499e-9af7-7ca332f3ad59",
      "name": "Get Current User",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "GET /users/me",
      "onError": "continueRegularOutput",
      "position": [
        816,
        544
      ],
      "parameters": {
        "url": "https://api.calendly.com/users/me",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "calendlyOAuth2Api"
      },
      "credentials": {
        "calendlyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "584b2145-6d49-4f63-bb3f-39e1fff8e2f6",
      "name": "Extract User",
      "type": "n8n-nodes-base.set",
      "position": [
        1040,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "u1",
              "name": "user_uri",
              "type": "string",
              "value": "={{ $json.resource?.uri }}"
            },
            {
              "id": "u2",
              "name": "user_name",
              "type": "string",
              "value": "={{ $json.resource?.name }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "39688e69-141e-4053-b0ca-d2d4cf2367bc",
      "name": "Get Event Types",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "GET /event_types?user={uri}&active=true",
      "onError": "continueRegularOutput",
      "position": [
        1264,
        544
      ],
      "parameters": {
        "url": "https://api.calendly.com/event_types",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "user",
              "value": "={{ $json.user_uri }}"
            },
            {
              "name": "active",
              "value": "true"
            }
          ]
        },
        "nodeCredentialType": "calendlyOAuth2Api"
      },
      "credentials": {
        "calendlyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "e0ed21e2-3258-415e-b414-b7db2cf76530",
      "name": "Select Event Type",
      "type": "n8n-nodes-base.set",
      "notes": "Pick requested or first event type",
      "position": [
        1488,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "et1",
              "name": "selected_event_type_uri",
              "type": "string",
              "value": "={{ $('Set Configuration').item.json.requested_event_type || ($json.collection && $json.collection.length > 0 ? $json.collection[0].uri : '') }}"
            },
            {
              "id": "et2",
              "name": "selected_event_type_name",
              "type": "string",
              "value": "={{ $json.collection && $json.collection.length > 0 ? $json.collection[0].name : '' }}"
            },
            {
              "id": "et3",
              "name": "selected_event_duration",
              "type": "number",
              "value": "={{ $json.collection && $json.collection.length > 0 ? $json.collection[0].duration : 30 }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "231c02e2-996d-42eb-a1a1-d6c59727a9cc",
      "name": "Create Single-Use Link",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "POST /scheduling_links",
      "onError": "continueRegularOutput",
      "position": [
        1712,
        544
      ],
      "parameters": {
        "url": "https://api.calendly.com/scheduling_links",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"max_event_count\": 1,\n  \"owner\": \"{{ $json.selected_event_type_uri }}\",\n  \"owner_type\": \"EventType\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "calendlyOAuth2Api"
      },
      "credentials": {
        "calendlyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "e75994d1-43a7-4a2f-a446-d0b57ed91638",
      "name": "Build Personalized Link",
      "type": "n8n-nodes-base.set",
      "notes": "Add prefill params to URL",
      "position": [
        1936,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "pl1",
              "name": "base_booking_url",
              "type": "string",
              "value": "={{ $json.resource?.booking_url }}"
            },
            {
              "id": "pl2",
              "name": "personalized_booking_url",
              "type": "string",
              "value": "={{ $json.resource?.booking_url }}?name={{ encodeURIComponent($('Set Configuration').item.json.recipient_name) }}&email={{ encodeURIComponent($('Set Configuration').item.json.recipient_email) }}&utm_source={{ $('Set Configuration').item.json.utm_source }}"
            },
            {
              "id": "pl3",
              "name": "recipient_name",
              "type": "string",
              "value": "={{ $('Set Configuration').item.json.recipient_name }}"
            },
            {
              "id": "pl4",
              "name": "recipient_email",
              "type": "string",
              "value": "={{ $('Set Configuration').item.json.recipient_email }}"
            },
            {
              "id": "pl5",
              "name": "event_type_name",
              "type": "string",
              "value": "={{ $('Select Event Type').item.json.selected_event_type_name }}"
            },
            {
              "id": "pl6",
              "name": "event_duration",
              "type": "number",
              "value": "={{ $('Select Event Type').item.json.selected_event_duration }}"
            },
            {
              "id": "pl7",
              "name": "link_created_at",
              "type": "string",
              "value": "={{ new Date().toISOString() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bed3401a-0f1b-4454-9d0d-c67eb5123ea2",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Track generated links",
      "onError": "continueRegularOutput",
      "position": [
        928,
        832
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Sent",
            "Created At": "={{ $json.link_created_at }}",
            "Event Type": "={{ $json.event_type_name }}",
            "Booking URL": "={{ $json.personalized_booking_url }}",
            "Duration (min)": "={{ $json.event_duration }}",
            "Recipient Name": "={{ $json.recipient_name }}",
            "Recipient Email": "={{ $json.recipient_email }}"
          },
          "schema": [
            {
              "id": "Recipient Name",
              "type": "string",
              "display": true
            },
            {
              "id": "Recipient Email",
              "type": "string",
              "display": true
            },
            {
              "id": "Event Type",
              "type": "string",
              "display": true
            },
            {
              "id": "Duration (min)",
              "type": "number",
              "display": true
            },
            {
              "id": "Booking URL",
              "type": "string",
              "display": true
            },
            {
              "id": "Created At",
              "type": "string",
              "display": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Generated Links"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "18gXcSrZuh-59Uv5N323vwZ3pZivaxeP9tnQ6XJqjRjc",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/18gXcSrZuh-59Uv5N323vwZ3pZivaxeP9tnQ6XJqjRjc/edit?usp=drivesdk",
          "cachedResultName": "n8n Template -Calendly Booking"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "0b033070-77b3-4430-a5b1-c1de917feb85",
      "name": "Notify via Slack",
      "type": "n8n-nodes-base.slack",
      "notes": "Optional notification",
      "onError": "continueRegularOutput",
      "position": [
        1152,
        832
      ],
      "parameters": {
        "text": "=\ud83d\udd17 *New Booking Link Generated*\n\n\ud83d\udc64 *For:* {{ $json.recipient_name }}\n\ud83d\udce7 *Email:* {{ $json.recipient_email }}\n\ud83d\udcc5 *Event:* {{ $json.event_type_name }} ({{ $json.event_duration }} min)\n\n\ud83d\udd17 <{{ $json.personalized_booking_url }}|Click to Book>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "general"
        },
        "otherOptions": {
          "mrkdwn": true,
          "unfurl_links": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "65523d31-14fa-4af0-8053-e1167212f18b",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "notes": "Return the generated link",
      "position": [
        1376,
        832
      ],
      "parameters": {
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={\n  \"success\": true,\n  \"booking_url\": \"{{ $('Build Personalized Link').item.json.personalized_booking_url }}\",\n  \"base_url\": \"{{ $('Build Personalized Link').item.json.base_booking_url }}\",\n  \"recipient\": {\n    \"name\": \"{{ $('Build Personalized Link').item.json.recipient_name }}\",\n    \"email\": \"{{ $('Build Personalized Link').item.json.recipient_email }}\"\n  },\n  \"event\": {\n    \"name\": \"{{ $('Build Personalized Link').item.json.event_type_name }}\",\n    \"duration_minutes\": {{ $('Build Personalized Link').item.json.event_duration }}\n  },\n  \"created_at\": \"{{ $('Build Personalized Link').item.json.link_created_at }}\",\n  \"expires\": \"Single-use or 90 days\"\n}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0015b4fa-0244-40c2-83ad-e866999fe7f9",
      "name": "\ud83d\udce4 RESPONSE",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        496
      ],
      "parameters": {
        "color": 5,
        "width": 396,
        "height": 268,
        "content": "## \ud83d\udce4 Response\n\n```json\n{\n  \"success\": true,\n  \"booking_url\": \"https://...\",\n  \"recipient\": {...},\n  \"event\": {...},\n  \"created_at\": \"...\",\n  \"expires\": \"Single-use or 90 days\"\n}\n```"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "47464fb8-c865-46ca-98b5-a4278ec8a500",
  "connections": {
    "Extract User": {
      "main": [
        [
          {
            "node": "Get Event Types",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Event Types": {
      "main": [
        [
          {
            "node": "Select Event Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Set Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Current User": {
      "main": [
        [
          {
            "node": "Extract User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify via Slack": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Event Type": {
      "main": [
        [
          {
            "node": "Create Single-Use Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration": {
      "main": [
        [
          {
            "node": "Get Current User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Notify via Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Single-Use Link": {
      "main": [
        [
          {
            "node": "Build Personalized Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Personalized Link": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}