GPT-4 Mini、JotForm、Telegramを基にした自動予約承認システム

中級

これは自動化ワークフローで、12個のノードを含みます。主にIf, Set, Gmail, Telegram, HttpRequestなどのノードを使用。 GPT-4 Mini、JotForm、Telegramを使用した自動予約承認システム

前提条件
  • Googleアカウント + Gmail API認証情報
  • Telegram Bot Token
  • ターゲットAPIの認証情報が必要な場合あり
  • Google Sheets API認証情報
  • OpenAI API Key

カテゴリー

-
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "meta": {
    "instanceId": "02059f0cb4b0ce23b903e8adf7a801dac35cd440dae5af845bde6649af1dcbcf",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "167a413a-b8d5-4111-be62-fd07f7b7413a",
      "name": "構造化出力パーサー",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        4688,
        1904
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"email\": \"patient@example.com\",\n  \"subject\": \"Appointment Update - Rescheduling Required\",\n  \"html_body\": \"<html><body><h1>Appointment Update</h1><p>Dear Roshan Ramani,</p><p>Unfortunately, your requested appointment on <b>16 October 2025</b> could not be approved.</p><p>Please contact us to reschedule at your convenience or choose another available slot.</p><p>Thank you for understanding.<br><b>Doctor's Office</b></p></body></html>\"\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "124507b2-9a28-47cc-921b-a7ee2c6ef8d7",
      "name": "予約リクエストフォームトリガー",
      "type": "n8n-nodes-base.jotFormTrigger",
      "position": [
        3664,
        1680
      ],
      "webhookId": "WEBHOOK_ID_PLACEHOLDER_1",
      "parameters": {
        "form": "YOUR_JOTFORM_FORM_ID",
        "onlyAnswers": false
      },
      "typeVersion": 1
    },
    {
      "id": "16f11b9e-f72a-41e4-a87a-b27837e48a68",
      "name": "解析: 予約詳細を抽出",
      "type": "n8n-nodes-base.set",
      "position": [
        3920,
        1680
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "75edf02c-37a0-406e-96b0-5f86b83272b9",
              "name": "formID",
              "type": "string",
              "value": "={{ $json.formID }}"
            },
            {
              "id": "d9b6b0db-7440-41e5-90da-232c94dd4979",
              "name": "formTitle",
              "type": "string",
              "value": "={{ $json.formTitle }}"
            },
            {
              "id": "85a7a4a5-baf9-4fa3-8bf0-a6b8da4e6e50",
              "name": "submissionID",
              "type": "string",
              "value": "={{ $json.submissionID }}"
            },
            {
              "id": "972d74f3-14d2-4a8f-9cdc-58aeb5d8708c",
              "name": "rawRequest.Name",
              "type": "object",
              "value": "={{ $json.rawRequest.Name }}"
            },
            {
              "id": "8bac118c-3ab2-41e8-8faa-4265ea83cb5f",
              "name": "rawRequest['Phone Number']",
              "type": "object",
              "value": "={{ $json.rawRequest['Phone Number'] }}"
            },
            {
              "id": "05457476-3bde-419c-89fc-1d0380970bfc",
              "name": "rawRequest['E-mail']",
              "type": "string",
              "value": "={{ $json.rawRequest['E-mail'] }}"
            },
            {
              "id": "da5d98ef-4f4d-4f78-acf7-951ebe82fe38",
              "name": "rawRequest['First Time Visit?']",
              "type": "string",
              "value": "={{ $json.rawRequest['First Time Visit?'] }}"
            },
            {
              "id": "c3f4d7be-11e5-49bd-b02d-ad1cb2da3d12",
              "name": "rawRequest['Select an Appointment Date']",
              "type": "object",
              "value": "={{ $json.rawRequest['Select an Appointment Date'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c1823ab1-a0c9-4fc8-adaf-317d119031d7",
      "name": "承認または却下の通知",
      "type": "n8n-nodes-base.telegram",
      "position": [
        4208,
        1680
      ],
      "webhookId": "WEBHOOK_ID_PLACEHOLDER_2",
      "parameters": {
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "message": "=Name : - {{ $json.rawRequest.Name.first }} {{ $json.rawRequest.Name.last }}\nnumber :- {{ $json.rawRequest['Phone Number'].full }}\nfirst time visit :- {{ $json.rawRequest['First Time Visit?'] }}\ndate time :- {{ $json.rawRequest['Select an Appointment Date'].date }}\nduration :- {{ $json.rawRequest['Select an Appointment Date'].duration }}",
        "options": {
          "appendAttribution": false
        },
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c64abc68-4dd0-4d02-9675-cef4fd950db8",
      "name": "生成: 予約応答メール",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        4496,
        1680
      ],
      "parameters": {
        "text": "=doctor decision approved :- {{ $json.data.approved }}\n\ndata :- {{ $('Parse: Extract Appointment Details').item.json.rawRequest.toJsonString() }}\n\nPlease generate an appropriate email (confirmation or reschedule) based on the approval status.\n",
        "options": {
          "systemMessage": "=You are an Appointment Email Assistant for a Doctor's Office.\nYour job is to read appointment form data and the doctor's response, then generate the correct email to send to the patient.\n\nYour tasks:\n\nExtract patient details such as name, email, appointment date, and time from the form data.\n\nCheck if the doctor's approval status (approved) is true or false.\n\nIf approved = true, write a confirmation email confirming the appointment.\n\nIf approved = false, write a polite reschedule or decline email, offering the patient to choose another time or contact the clinic.\n\nAlways reply only in valid JSON format with exactly three fields:\n\nemail → patient's email address\n\nsubject → short and clear subject line\n\nhtml_body → full HTML message with <html>, <body>, <h1>, <p> tags etc.\n\nUse a warm, professional, and caring tone.\n\nAssume the email will be sent via the Gmail tool, so you only need to provide the content — not the sending logic.\n\nExample output when approved:\n\n{\n  \"email\": \"patient@example.com\",\n  \"subject\": \"Appointment Confirmed - 16 Oct 2025, 9:00 AM\",\n  \"html_body\": \"<html><body><h1>Your Appointment is Confirmed</h1><p>Dear Roshan Ramani,</p><p>Your appointment has been confirmed for <b>16 October 2025</b> at <b>9:00 AM</b>. Please arrive 10 minutes early.</p><p>If you have any questions, feel free to reply to this email.</p><p>Warm regards,<br><b>Doctor's Office</b></p></body></html>\"\n}\n\n\nExample output when not approved:\n\n{\n  \"email\": \"patient@example.com\",\n  \"subject\": \"Appointment Update - Rescheduling Required\",\n  \"html_body\": \"<html><body><h1>Appointment Update</h1><p>Dear Roshan Ramani,</p><p>Unfortunately, your requested appointment on <b>16 October 2025</b> could not be approved.</p><p>Please contact us to reschedule at your convenience or choose another available slot.</p><p>Thank you for understanding.<br><b>Doctor's Office</b></p></body></html>\"\n}\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "38424ee8-2585-4ad1-bef6-d70069485596",
      "name": "条件: 承認ステータスを確認",
      "type": "n8n-nodes-base.if",
      "position": [
        4832,
        1680
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cfff1aa3-d240-4527-a526-ebd7ab83c5a1",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Notify for Approval or Decline').item.json.data.approved }}",
              "rightValue": "true"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "f976d556-6d29-4d3a-9633-67bbb06d975e",
      "name": "記録: 予約をスプレッドシートに記録",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5040,
        1584
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest.Name.first }} {{ $('Parse: Extract Appointment Details').item.json.rawRequest.Name.last }}",
            "email": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest['E-mail'] }}",
            "duration": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest['Select an Appointment Date'].duration }}",
            "phone no": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest['Phone Number'].full }}",
            "date and time": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest['Select an Appointment Date'].date }}",
            "is_first time": "={{ $('Parse: Extract Appointment Details').item.json.rawRequest['First Time Visit?'] }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone no",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "phone no",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "is_first time",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "is_first time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date and time",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "date and time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "duration",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "duration",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit?usp=drivesdk",
          "cachedResultName": "new form submissions"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "bbfba0b3-92fe-4da7-9456-aafe0ca911b2",
      "name": "送信: 確認メール",
      "type": "n8n-nodes-base.gmail",
      "position": [
        5248,
        1584
      ],
      "webhookId": "WEBHOOK_ID_PLACEHOLDER_3",
      "parameters": {
        "sendTo": "={{ $('Generate: Appointment Response Email').item.json.output.email }}",
        "message": "={{ $('Generate: Appointment Response Email').item.json.output.html_body }}",
        "options": {},
        "subject": "={{ $('Generate: Appointment Response Email').item.json.output.subject }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e74a6bbe-d2e2-4466-b5b7-3b943d684069",
      "name": "送信: 却下または再調整メール",
      "type": "n8n-nodes-base.gmail",
      "position": [
        5280,
        1856
      ],
      "webhookId": "WEBHOOK_ID_PLACEHOLDER_3",
      "parameters": {
        "sendTo": "={{ $('Generate: Appointment Response Email').item.json.output.email }}",
        "message": "={{ $('Generate: Appointment Response Email').item.json.output.html_body }}",
        "options": {},
        "subject": "={{ $('Generate: Appointment Response Email').item.json.output.subject }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "ff45d2d2-a900-492e-b881-ef6ba2b58a74",
      "name": "却下された予約を削除",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5056,
        1856
      ],
      "parameters": {
        "url": "=https://api.jotform.com/submission/{{ $('Parse: Extract Appointment Details').item.json.submissionID }}",
        "method": "DELETE",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "apiKey",
              "value": "YOUR_JOTFORM_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "134bcabc-106b-4916-9519-fe911ac63b91",
      "name": "付箋メモ2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3072,
        1392
      ],
      "parameters": {
        "width": 2448,
        "height": 880,
        "content": "#  AI Powered All Purpose Appointment System via JotForm\n\nThis workflow automates appointment requests by capturing form submissions, getting approval from a decision-maker, and sending appropriate confirmation or rejection emails.\n\n**What It Does:**\n- Captures new appointment requests from JotForm form\n- Sends appointment details for review and approval\n- Generates personalized confirmation or rejection emails using AI\n- Records approved appointments in Google Sheets\n- Handles both approvals and rejections automatically\n---\n\n👉 [Get the JotForm](https://www.jotform.com/?partner=roshanramanidev)\n\n**How It Works:**\n\n1. **Appointment Request Form Trigger** - New form submission arrives\n2. **Parse: Extract Appointment Details** - Pulls name, email, phone, date, time, visit type\n3. **Notify for Approval or Decline** - Sends details to approval channel for review\n4. **Generate: Appointment Response Email** - AI creates confirmation or reschedule email based on approval\n5. **Condition: Check Approval Status** - Routes to approved or rejected path\n   - **If Approved:**\n     - Log: Record Appointment in sheets - Stores in Google Sheets\n     - Send: Confirmation Email - Sends confirmation to requester\n   - **If Rejected:**\n     - Delete Rejected Appointment - Removes from form system\n     - Send: Rejection or Reschedule Email - Notifies requester\n\n**Key Benefits:**\n- Fully automated with no manual email writing\n- AI-powered personalized responses\n- Clean record keeping in Google Sheets\n- Instant approval/rejection notifications\n- Professional communication maintained\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4b623fe9-5505-47f1-b3ba-be5c0d1a49ec",
      "name": "OpenAI チャットモデル6",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        4496,
        1888
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    }
  ],
  "pinData": {},
  "connections": {
    "4b623fe9-5505-47f1-b3ba-be5c0d1a49ec": {
      "ai_languageModel": [
        [
          {
            "node": "c64abc68-4dd0-4d02-9675-cef4fd950db8",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "167a413a-b8d5-4111-be62-fd07f7b7413a": {
      "ai_outputParser": [
        [
          {
            "node": "c64abc68-4dd0-4d02-9675-cef4fd950db8",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "ff45d2d2-a900-492e-b881-ef6ba2b58a74": {
      "main": [
        [
          {
            "node": "e74a6bbe-d2e2-4466-b5b7-3b943d684069",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c1823ab1-a0c9-4fc8-adaf-317d119031d7": {
      "main": [
        [
          {
            "node": "c64abc68-4dd0-4d02-9675-cef4fd950db8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "124507b2-9a28-47cc-921b-a7ee2c6ef8d7": {
      "main": [
        [
          {
            "node": "16f11b9e-f72a-41e4-a87a-b27837e48a68",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "38424ee8-2585-4ad1-bef6-d70069485596": {
      "main": [
        [
          {
            "node": "f976d556-6d29-4d3a-9633-67bbb06d975e",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ff45d2d2-a900-492e-b881-ef6ba2b58a74",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f976d556-6d29-4d3a-9633-67bbb06d975e": {
      "main": [
        [
          {
            "node": "bbfba0b3-92fe-4da7-9456-aafe0ca911b2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "16f11b9e-f72a-41e4-a87a-b27837e48a68": {
      "main": [
        [
          {
            "node": "c1823ab1-a0c9-4fc8-adaf-317d119031d7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c64abc68-4dd0-4d02-9675-cef4fd950db8": {
      "main": [
        [
          {
            "node": "38424ee8-2585-4ad1-bef6-d70069485596",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

中級

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

ワークフロー情報
難易度
中級
ノード数12
カテゴリー-
ノードタイプ11
難易度説明

経験者向け、6-15ノードの中程度の複雑さのワークフロー

作成者
Roshan Ramani

Roshan Ramani

@rawsun007

I love building smart n8n automations that actually work reliably. My focus is on making everyday tasks like email, social media, and CRM workflows simpler using AI. I've shared templates in the n8n community, including a WhatsApp Expense Tracker that people really enjoy. What keeps me excited is constantly trying new things - testing fresh nodes, playing with AI tools like LangChain, and discovering creative ways to connect systems!

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34