AutomationFlowsSlack & Telegram › Appointment Reminders Noshow

Appointment Reminders Noshow

Appointment-Reminders-Noshow. Uses httpRequest, highLevel, slack. Webhook trigger; 22 nodes.

Webhook trigger★★★★☆ complexity22 nodesHTTP RequestHigh LevelSlack
Slack & Telegram Trigger: Webhook Nodes: 22 Complexity: ★★★★☆ Added:

This workflow follows the HTTP Request → Slack recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "sa-note",
      "name": "Section 1 note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -460,
        -160
      ],
      "parameters": {
        "content": "## 1. Booking confirmed on the spot\n- A new booking lands, the customer is saved in GoHighLevel with their appointment time, and the confirmation text goes out right away.",
        "height": 140,
        "width": 620,
        "color": 4
      }
    },
    {
      "id": "sa-hook",
      "name": "A new appointment gets booked",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -420,
        80
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "demo/appointment-booked",
        "responseMode": "responseNode",
        "options": {}
      }
    },
    {
      "id": "sa-tidy",
      "name": "Tidy up the booking details",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -200,
        80
      ],
      "parameters": {
        "jsCode": "// Booking events arrive in a few different shapes, so check each one in turn.\nconst TZ = 'America/Denver';\n\nconst results = [];\n\nfor (const item of $input.all()) {\n  const raw = item.json || {};\n  const body = raw.body || {};\n  const custom = raw.customData || body.customData || {};\n  const contact = raw.contact || body.contact || {};\n  const sources = [raw, body, custom, contact];\n\n  const pick = (...keys) => {\n    for (const key of keys) {\n      for (const source of sources) {\n        if (!source || typeof source !== 'object') continue;\n        const value = source[key];\n        if (value === undefined || value === null) continue;\n        const text = String(value).trim();\n        if (text !== '') return text;\n      }\n    }\n    return '';\n  };\n\n  const fullName = pick('name', 'full_name', 'fullName', 'customerName', 'customer_name');\n  const firstName = pick('firstName', 'first_name') || fullName.split(' ')[0] || 'there';\n\n  let phone = pick('phone', 'phoneNumber', 'phone_number', 'mobile', 'customerPhone');\n  phone = phone.replace(/[^0-9+]/g, '');\n  if (phone && !phone.startsWith('+')) {\n    phone = phone.length === 10 ? '+1' + phone : '+' + phone;\n  }\n\n  const appointmentTime = pick('appointmentTime', 'appointment_time', 'startTime', 'start_time', 'start', 'apptTime');\n  const apptDate = new Date(appointmentTime);\n  const validDate = appointmentTime && !isNaN(apptDate.getTime());\n\n  const dayPretty = validDate\n    ? apptDate.toLocaleDateString('en-US', { timeZone: TZ, weekday: 'long', month: 'long', day: 'numeric' })\n    : 'your scheduled day';\n  const timePretty = validDate\n    ? apptDate.toLocaleTimeString('en-US', { timeZone: TZ, hour: 'numeric', minute: '2-digit' })\n    : 'the scheduled time';\n\n  results.push({\n    json: {\n      fullName: fullName || firstName,\n      firstName,\n      phone,\n      contactId: pick('contactId', 'contact_id', 'id'),\n      appointmentTime,\n      jobType: pick('jobType', 'job_type', 'service', 'serviceType') || 'service visit',\n      dayPretty,\n      timePretty\n    }\n  });\n}\n\nreturn results;\n"
      }
    },
    {
      "id": "sa-save",
      "name": "Save the customer in GoHighLevel",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        20,
        80
      ],
      "parameters": {
        "method": "POST",
        "url": "https://services.leadconnectorhq.com/contacts/upsert",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ locationId: 'bsHomeSvcDemo01', firstName: $json.firstName, name: $json.fullName, phone: $json.phone, tags: ['appt-confirmed'], customFields: [{ key: 'appointment_time', field_value: $json.appointmentTime }] }) }}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sa-sms",
      "name": "Text the booking confirmation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        240,
        80
      ],
      "parameters": {
        "method": "POST",
        "url": "https://services.leadconnectorhq.com/conversations/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'SMS', contactId: $json.contact?.id || $('Tidy up the booking details').item.json.contactId, message: 'Hey ' + $('Tidy up the booking details').item.json.firstName + ', this is Blue Summit. You are on the books for ' + $('Tidy up the booking details').item.json.dayPretty + ' at ' + $('Tidy up the booking details').item.json.timePretty + '. We will text you a heads up before we head over.' }) }}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sa-respond",
      "name": "Tell the calendar it is booked",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        460,
        80
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ ok: true, message: 'Booked and the confirmation text has gone out.', phone: $('Tidy up the booking details').item.json.phone }) }}",
        "options": {}
      }
    },
    {
      "id": "sb-note",
      "name": "Section 2 note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -460,
        480
      ],
      "parameters": {
        "content": "## 2. The reminder sweep\n- Every fifteen minutes the sweep finds who is about a day out or about two hours out and sends the right text.\n- Both timing windows sit at the top of one code node, so moving a reminder is a one line change.",
        "height": 160,
        "width": 620,
        "color": 4
      }
    },
    {
      "id": "sb-schedule",
      "name": "Check every fifteen minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -420,
        760
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      }
    },
    {
      "id": "sb-list",
      "name": "Get everyone with an appointment on the books",
      "type": "n8n-nodes-base.highLevel",
      "typeVersion": 2,
      "position": [
        -200,
        760
      ],
      "parameters": {
        "resource": "contact",
        "operation": "getAll",
        "returnAll": true,
        "filters": {}
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sb-code",
      "name": "Work out who is due a text now",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        20,
        760
      ],
      "parameters": {
        "jsCode": "// Change the reminder timing here. Minutes count down to the appointment.\nconst RULES = [\n  { due: 'day_before', stampTag: 'reminder-24h-sent', fromMinutes: 22 * 60, toMinutes: 26 * 60 },\n  { due: 'morning_of', stampTag: 'reminder-2h-sent', fromMinutes: 90, toMinutes: 150 }\n];\n\nconst TZ = 'America/Denver';\n\nfunction tagsOf(contact) {\n  const raw = contact.tags ?? contact.tag ?? [];\n  const list = Array.isArray(raw) ? raw : String(raw).split(',');\n  return list.map(t => String(t).trim().toLowerCase()).filter(t => t.length > 0);\n}\n\nfunction toUsNumber(raw) {\n  let digits = String(raw ?? '').replace(/[^0-9+]/g, '');\n  if (!digits) return '';\n  if (digits.startsWith('+')) return digits;\n  if (digits.length === 10) return '+1' + digits;\n  return '+' + digits;\n}\n\nfunction apptTimeOf(contact) {\n  const direct = contact.appointment_time || contact.appointmentTime || contact.apptTime;\n  if (direct) return String(direct);\n  const lists = [contact.customFields, contact.customField, contact.custom_fields];\n  for (const list of lists) {\n    if (!Array.isArray(list)) continue;\n    for (const field of list) {\n      if (!field || typeof field !== 'object') continue;\n      const key = String(field.key || field.fieldKey || field.name || '').toLowerCase();\n      if (!key.includes('appointment')) continue;\n      const value = field.value ?? field.field_value ?? field.fieldValue;\n      if (value) return String(value);\n    }\n  }\n  return '';\n}\n\nconst now = Date.now();\nconst due = [];\n\nfor (const item of $input.all()) {\n  const contact = item.json ?? {};\n  const tags = tagsOf(contact);\n\n  // The tags are the memory. Whoever already has the stamp tag is skipped,\n  // so a restart never sends anyone the same reminder twice.\n  if (!tags.includes('appt-confirmed')) continue;\n  if (tags.includes('no-show')) continue;\n\n  const apptRaw = apptTimeOf(contact);\n  if (!apptRaw) continue;\n  const apptMs = new Date(apptRaw).getTime();\n  if (isNaN(apptMs)) continue;\n\n  const minutesToGo = (apptMs - now) / 60000;\n  const rule = RULES.find(r => minutesToGo >= r.fromMinutes && minutesToGo <= r.toMinutes);\n  if (!rule) continue;\n  if (tags.includes(rule.stampTag)) continue;\n\n  const phone = toUsNumber(contact.phone ?? contact.phoneNumber ?? contact.mobile);\n  if (!phone) continue;\n\n  const contactId = contact.id ?? contact.contactId ?? contact._id;\n  if (!contactId) continue;\n\n  const apptDate = new Date(apptMs);\n  due.push({\n    json: {\n      contactId,\n      firstName: contact.firstName ?? contact.first_name ?? contact.contactName ?? 'there',\n      phone,\n      due: rule.due,\n      stampTag: rule.stampTag,\n      dayPretty: apptDate.toLocaleDateString('en-US', { timeZone: TZ, weekday: 'long', month: 'long', day: 'numeric' }),\n      timePretty: apptDate.toLocaleTimeString('en-US', { timeZone: TZ, hour: 'numeric', minute: '2-digit' })\n    }\n  });\n}\n\n// Nobody in a window right now means the sweep just ends quietly.\nreturn due;\n"
      }
    },
    {
      "id": "sb-switch",
      "name": "Which reminder is due?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        240,
        760
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.due }}",
                    "rightValue": "day_before",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "day_before"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.due }}",
                    "rightValue": "morning_of",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "morning_of"
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      }
    },
    {
      "id": "sb-sms-daybefore",
      "name": "Text the day before reminder",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        460,
        660
      ],
      "parameters": {
        "method": "POST",
        "url": "https://services.leadconnectorhq.com/conversations/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'SMS', contactId: $json.contactId, message: 'Hey ' + $json.firstName + ', Blue Summit here. We have you down for tomorrow at ' + $json.timePretty + '. Reply here if anything changes.' }) }}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sb-sms-morning",
      "name": "Text the morning of heads up",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        460,
        860
      ],
      "parameters": {
        "method": "POST",
        "url": "https://services.leadconnectorhq.com/conversations/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'SMS', contactId: $json.contactId, message: 'Morning ' + $json.firstName + ', Blue Summit here. Our tech is headed your way around ' + $json.timePretty + ' today. See you soon.' }) }}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sb-stamp",
      "name": "Mark the reminder as sent",
      "type": "n8n-nodes-base.highLevel",
      "typeVersion": 2,
      "position": [
        700,
        760
      ],
      "parameters": {
        "resource": "contact",
        "operation": "update",
        "contactId": "={{ $('Work out who is due a text now').item.json.contactId }}",
        "updateFields": {
          "tags": "={{ $('Work out who is due a text now').item.json.stampTag }}"
        }
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sc-note",
      "name": "Section 3 note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -460,
        1160
      ],
      "parameters": {
        "content": "## 3. No-show rescue\n- A no-show gets a low pressure rebook text with the booking link the same day.\n- The office gets a call task for tomorrow and a note in #sales-team, so nobody falls through the cracks.",
        "height": 160,
        "width": 620,
        "color": 4
      }
    },
    {
      "id": "sc-hook",
      "name": "The calendar marks a no-show",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -420,
        1440
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "demo/no-show",
        "responseMode": "responseNode",
        "options": {}
      }
    },
    {
      "id": "sc-tidy",
      "name": "Tidy up the no-show details",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -200,
        1440
      ],
      "parameters": {
        "jsCode": "// No-show events arrive in a few different shapes, so check each one in turn.\nconst results = [];\n\nfor (const item of $input.all()) {\n  const raw = item.json || {};\n  const body = raw.body || {};\n  const custom = raw.customData || body.customData || {};\n  const contact = raw.contact || body.contact || {};\n  const sources = [raw, body, custom, contact];\n\n  const pick = (...keys) => {\n    for (const key of keys) {\n      for (const source of sources) {\n        if (!source || typeof source !== 'object') continue;\n        const value = source[key];\n        if (value === undefined || value === null) continue;\n        const text = String(value).trim();\n        if (text !== '') return text;\n      }\n    }\n    return '';\n  };\n\n  const fullName = pick('name', 'full_name', 'fullName', 'customerName', 'customer_name');\n  const firstName = pick('firstName', 'first_name') || fullName.split(' ')[0] || 'there';\n\n  let phone = pick('phone', 'phoneNumber', 'phone_number', 'mobile', 'customerPhone');\n  phone = phone.replace(/[^0-9+]/g, '');\n  if (phone && !phone.startsWith('+')) {\n    phone = phone.length === 10 ? '+1' + phone : '+' + phone;\n  }\n\n  results.push({\n    json: {\n      contactId: pick('contactId', 'contact_id', 'id'),\n      fullName: fullName || firstName,\n      firstName,\n      phone\n    }\n  });\n}\n\nreturn results;\n"
      }
    },
    {
      "id": "sc-tag",
      "name": "Tag them as a no-show",
      "type": "n8n-nodes-base.highLevel",
      "typeVersion": 2,
      "position": [
        20,
        1440
      ],
      "parameters": {
        "resource": "contact",
        "operation": "update",
        "contactId": "={{ $json.contactId }}",
        "updateFields": {
          "tags": "no-show"
        }
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sc-sms",
      "name": "Text them a way to grab a new time",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        240,
        1440
      ],
      "parameters": {
        "method": "POST",
        "url": "https://services.leadconnectorhq.com/conversations/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'SMS', contactId: $('Tidy up the no-show details').item.json.contactId, message: 'Hey ' + $('Tidy up the no-show details').item.json.firstName + ', this is Blue Summit. Sorry we missed each other today. Want to grab a new time? Book here: https://blue-summit.example.com/book' }) }}",
        "options": {}
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sc-task",
      "name": "Give the office a call task for tomorrow",
      "type": "n8n-nodes-base.highLevel",
      "typeVersion": 2,
      "position": [
        460,
        1440
      ],
      "parameters": {
        "resource": "task",
        "operation": "create",
        "contactId": "={{ $('Tidy up the no-show details').item.json.contactId }}",
        "title": "=Call {{ $('Tidy up the no-show details').item.json.fullName }} if they have not rebooked",
        "dueDate": "={{ $now.plus({ days: 1 }).toISO() }}",
        "additionalFields": {
          "description": "=They missed today's visit and got the rebook text. If there is no new appointment on the calendar, give them a call at {{ $('Tidy up the no-show details').item.json.phone }}."
        }
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sc-slack",
      "name": "Let the sales team know",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        680,
        1440
      ],
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#sales-team"
        },
        "text": "=No-show today: {{ $('Tidy up the no-show details').item.json.fullName }} ({{ $('Tidy up the no-show details').item.json.phone }}). The rebook text went out and the office has a call task for tomorrow in case they do not grab a new time.",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "sc-respond",
      "name": "Tell the calendar it is handled",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        900,
        1440
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ ok: true, message: 'No-show handled. The rebook text went out and the office has a follow up task.', phone: $('Tidy up the no-show details').item.json.phone }) }}",
        "options": {}
      }
    }
  ],
  "connections": {
    "A new appointment gets booked": {
      "main": [
        [
          {
            "node": "Tidy up the booking details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tidy up the booking details": {
      "main": [
        [
          {
            "node": "Save the customer in GoHighLevel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save the customer in GoHighLevel": {
      "main": [
        [
          {
            "node": "Text the booking confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text the booking confirmation": {
      "main": [
        [
          {
            "node": "Tell the calendar it is booked",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check every fifteen minutes": {
      "main": [
        [
          {
            "node": "Get everyone with an appointment on the books",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get everyone with an appointment on the books": {
      "main": [
        [
          {
            "node": "Work out who is due a text now",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Work out who is due a text now": {
      "main": [
        [
          {
            "node": "Which reminder is due?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Which reminder is due?": {
      "main": [
        [
          {
            "node": "Text the day before reminder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Text the morning of heads up",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text the day before reminder": {
      "main": [
        [
          {
            "node": "Mark the reminder as sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text the morning of heads up": {
      "main": [
        [
          {
            "node": "Mark the reminder as sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "The calendar marks a no-show": {
      "main": [
        [
          {
            "node": "Tidy up the no-show details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tidy up the no-show details": {
      "main": [
        [
          {
            "node": "Tag them as a no-show",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tag them as a no-show": {
      "main": [
        [
          {
            "node": "Text them a way to grab a new time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text them a way to grab a new time": {
      "main": [
        [
          {
            "node": "Give the office a call task for tomorrow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give the office a call task for tomorrow": {
      "main": [
        [
          {
            "node": "Let the sales team know",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Let the sales team know": {
      "main": [
        [
          {
            "node": "Tell the calendar it is handled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Appointment-Reminders-Noshow. Uses httpRequest, highLevel, slack. Webhook trigger; 22 nodes.

Source: https://github.com/mcruz1799/automation-examples/blob/main/claude-code/02-automation-file-factory/skills/n8n/section-templates/appointment-reminders-noshow.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

HR teams, IT Operations, and System Administrators managing employee onboarding at scale. It’s perfect if you use Odoo 18 to trigger account requests and need Redmine + GitLab accounts created instant

HTTP Request, Slack
Slack & Telegram

This workflow is a complete, production-ready solution for recovering abandoned carts in Shopify stores using a multi-channel, multi-touch approach. It automates personalized follow-ups via Email, SMS

HTTP Request, Shopify, SendGrid +5
Slack & Telegram

Backbrief: transcripts (Zoom webhook -> Slack + vault). Uses httpRequest, slack. Webhook trigger; 52 nodes.

HTTP Request, Slack
Slack & Telegram

This workflow automates end-to-end research analysis by coordinating multiple AI models—including NVIDIA NIM (Llama), OpenAI GPT-4, and Claude to analyze uploaded documents, extract insights, and gene

HTTP Request, Postgres, Slack +1
Slack & Telegram

Are you tired of the repetitive dance between git push, creating a pull request in GitHub, updating the corresponding task in JIRA, and then manually notifying your team in Slack, or Notion?

HTTP Request, Stop And Error, Jira +2