入社キャッチアップ評価システム

中級

これは自動化ワークフローで、14個のノードを含みます。主にCode, Gmail, Slack, Webhook, GoogleSheetsなどのノードを使用。 Fireflies.ai、OpenAI、Google Sheetsを使った営業通話スコアリングの自動化

前提条件
  • Googleアカウント + Gmail API認証情報
  • Slack Bot Token または Webhook URL
  • HTTP Webhookエンドポイント(n8nが自動生成)
  • Google Sheets API認証情報
  • OpenAI API Key

カテゴリー

-
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "id": "zKRrIwXzcv7QvepA",
  "meta": {
    "instanceId": "6615d3df9d365bf328b0a329fe952ab6b434c9ecc8f5a2517849ec1f68f0d9b0",
    "templateCredsSetupCompleted": true
  },
  "name": "OnBoarding Call Grading System",
  "tags": [
    {
      "id": "OYNCvrDxVQHw2gvR",
      "name": "Upwork",
      "createdAt": "2025-10-02T10:34:02.340Z",
      "updatedAt": "2025-10-02T10:34:02.340Z"
    }
  ],
  "nodes": [
    {
      "id": "a9579f80-9bec-473c-83c4-66b1134194ee",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -16,
        -176
      ],
      "webhookId": "66273cf2-950f-42e5-a386-60d643868985",
      "parameters": {
        "path": "66273cf2-950f-42e5-a386-60d643868985",
        "options": {},
        "httpMethod": "POST",
        "responseData": "allEntries",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d7377f6f-c1cc-47a9-8d1d-99dadd47fb2f",
      "name": "シートに行を追加",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1280,
        -176
      ],
      "parameters": {
        "columns": {
          "value": {
            "Pain Points": "={{ $json.pain_points }}",
            "Overall Score %": "={{ $json.overall_score_percent }}",
            "What I Did Well": "={{ $json.what_i_did_well }}",
            "What to Improve": "={{ $json.what_to_improve }}",
            "Discovery (1–5)": "={{ $json.scores_discovery }}",
            "Feature requested": "={{ $json.feature_requested }}",
            "Overall Score [25]": "={{ $json.overall_score_25 }}",
            "Recording Share Url": "={{ $('Get a transcript').item.json.data.transcript_url }}",
            "Meeting Invitees Name": "={{ $('Get a transcript').item.json.data.sentences[15].speaker_name }}",
            "Meeting Invitees Email": "nico-wenck@clicklessai.de",
            "Close/Next Steps (1–5)": "={{ $json.scores_close_next_steps }}",
            "Engagement/Rapport (1–5)": "={{ $json.scores_engagement_rapport }}",
            "Objection Handling (1–5)": "={{ $json.scores_objection_handling }}",
            "Onboarding Clarity (1–5)": "={{ $json.scores_onboarding_clarity }}",
            "Recording Duration In Minutes": "={{ $('Get a transcript').item.json.data.duration }}",
            "What CRM have you used in the past?": "={{ $json.crm_used_past }}"
          },
          "schema": [
            {
              "id": "Meeting Invitees Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Meeting Invitees Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Meeting Invitees Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Meeting Invitees Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recording Share Url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recording Share Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recording Duration In Minutes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recording Duration In Minutes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "What CRM have you used in the past?",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "What CRM have you used in the past?",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pain Points",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pain Points",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Feature requested",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Feature requested",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "What I Did Well",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "What I Did Well",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "What to Improve",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "What to Improve",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Discovery (1–5)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Discovery (1–5)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Onboarding Clarity (1–5)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Onboarding Clarity (1–5)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Objection Handling (1–5)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Objection Handling (1–5)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Engagement/Rapport (1–5)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Engagement/Rapport (1–5)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Close/Next Steps (1–5)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Close/Next Steps (1–5)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Overall Score [25]",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Overall Score [25]",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Overall Score %",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Overall Score %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "@dropdown",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "@dropdown",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meeting_invitees_name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "meeting_invitees_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "meeting_invitees_email",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "meeting_invitees_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "crm_used_past",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "crm_used_past",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "pain_points",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "pain_points",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "feature_requested",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "feature_requested",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "what_i_did_well",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "what_i_did_well",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "what_to_improve",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "what_to_improve",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scores_discovery",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "scores_discovery",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scores_onboarding_clarity",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "scores_onboarding_clarity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scores_objection_handling",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "scores_objection_handling",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scores_engagement_rapport",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "scores_engagement_rapport",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scores_close_next_steps",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "scores_close_next_steps",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "overall_score_25",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "overall_score_25",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "overall_score_percent",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "overall_score_percent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "notes",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1TcWkY4KVQfl7n5n9UyjiV590GdzgbCOrLvfb8d6FreA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1TcWkY4KVQfl7n5n9UyjiV590GdzgbCOrLvfb8d6FreA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1TcWkY4KVQfl7n5n9UyjiV590GdzgbCOrLvfb8d6FreA/edit?usp=drivesdk",
          "cachedResultName": "Kopie von REsimpli Onboarding Call - Fathom Call Score"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "0mHUWOW7FKfeUt2J",
          "name": "ClickLessAI Google Sheets"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "072de8f9-05a4-4c32-a3a8-42726eefe3e3",
      "name": "トランスクリプトを取得",
      "type": "@firefliesai/n8n-nodes-fireflies.fireflies",
      "position": [
        208,
        -176
      ],
      "parameters": {
        "transcriptId": "={{ $json.body.meetingId }}"
      },
      "credentials": {
        "firefliesApi": {
          "id": "MaxlgNMFhzk3ltwr",
          "name": "Fireflies account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "57c6c8ee-a89d-4fd1-b7ae-e5fcb54ebb34",
      "name": "モデルにメッセージを送信",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        688,
        -176
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Transcript (raw):\n{{ $json.Transcript }}\n\nTask:\n- Extract facts and evaluate according to System Prompt.\n- Reply exclusively in JSON format according to Assistant Prompt."
            },
            {
              "role": "assistant",
              "content": "={\n  \"meeting_invitees_name\": \"\",\n  \"meeting_invitees_email\": \"\",\n  \"crm_used_past\": \"\",\n  \"pain_points\": \"\",\n  \"feature_requested\": \"\",\n  \"what_i_did_well\": \"\",\n  \"what_to_improve\": \"\",\n  \"scores\": {\n    \"discovery\": 1,\n    \"onboarding_clarity\": 1,\n    \"objection_handling\": 1,\n    \"engagement_rapport\": 1,\n    \"close_next_steps\": 1\n  },\n  \"overall_score_25\": 0,\n  \"overall_score_percent\": 0,\n  \"notes\": \"\"\n}\n\n\nSpecific format requirements:\n- pain_points, feature_requested, what_i_did_well, what_to_improve are SEMICOLON-separated strings (not arrays).\n- Sort points alphabetically; deduplicate identical phrases.\n- Maximum 6 points per field; each phrase ≤ 12 words.\n- \"notes\" is optional, short (≤ 50 words)."
            },
            {
              "role": "system",
              "content": "=You are a sober analyzer for sales transcripts of a CRM provider.\n\nRules:\n- Extract ONLY information from the transcript (no hallucinations).\n- If info is missing/unclear: use empty string \"\".\n- meeting_invitees_name = main contact (prospect), NOT additional participants.\n- Emails/names only if explicitly mentioned.\n- Scores are whole numbers 1–5 (estimate conservatively, never 0).\n- Calculate overall_score_25 = sum of the 5 scores.\n- Calculate overall_score_percent = round((overall_score_25/25)*100).\n- Output must be STRICT JSON according to the Assistant schema. No explanations/Markdown.\n\nFormat rules for text fields:\n- Always use ONE string (no arrays).\n- Multiple points must be SEMICOLON-separated, with a space after each semicolon.\n- No duplicate points, no leading/trailing semicolons, everything trimmed.\n- Order: alphabetically sorted (German sorting) for consistency.\n\n“What to Improve” – generation rules (must NOT be empty):\n- Derive improvements from (a) explicit criticism from the prospect, (b) visible gaps in discovery (goals, stakeholders, timeline, budget),\n  (c) unclear next steps, (d) weak objection handling, (e) missing proof of value.\n- Provide AT LEAST one, preferably 2–3 short, concrete points (semicolon-separated)."
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "id": "WVC4WZ1lsahz1CtE",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "2a5072fd-8895-41d6-b2bd-9c005b7d1b5d",
      "name": "JavaScriptコード",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        -176
      ],
      "parameters": {
        "jsCode": "// Hilfsfunktionen\nfunction getRawContent(item) {\n  const j = item.json || {};\n  return (\n    j?.message?.content ??\n    j?.data?.[0]?.message?.content ??\n    j?.choices?.[0]?.message?.content ??\n    j?.content ??\n    ''\n  );\n}\n\nfunction extractJson(raw) {\n  if (typeof raw !== 'string') return null;\n  // Entferne Markdown-Fences ```json ... ```\n  let cleaned = raw.replace(/```json/gi, '').replace(/```/g, '').trim();\n  const m = cleaned.match(/\\{[\\s\\S]*\\}/);\n  return m ? m[0] : null;\n}\n\nfunction clamp1to5(v) {\n  const n = Math.round(Number(v));\n  if (Number.isNaN(n)) return 1;\n  return Math.max(1, Math.min(5, n));\n}\n\nfunction ensureString(val) {\n  if (val === undefined || val === null) return \"\";\n  return String(val).trim();\n}\n\n// Starte mit dem ersten Item (typisch: 1 LLM-Response)\nconst raw = getRawContent(items[0]);\nconst jsonStr = extractJson(raw);\nif (!jsonStr) {\n  throw new Error('Kein JSON im LLM-Output gefunden.');\n}\n\nlet obj;\ntry {\n  obj = JSON.parse(jsonStr);\n} catch (e) {\n  throw new Error('JSON nicht parsebar: ' + e.message);\n}\n\n// Default-Werte einsetzen\nobj.meeting_invitees_name = ensureString(obj.meeting_invitees_name);\nobj.meeting_invitees_email = ensureString(obj.meeting_invitees_email);\nobj.crm_used_past = ensureString(obj.crm_used_past);\nobj.pain_points = ensureString(obj.pain_points);\nobj.feature_requested = ensureString(obj.feature_requested);\nobj.what_i_did_well = ensureString(obj.what_i_did_well);\nobj.what_to_improve = ensureString(obj.what_to_improve);\nobj.notes = ensureString(obj.notes);\n\n// Scores validieren\nconst s = obj.scores || {};\ns.discovery = clamp1to5(s.discovery);\ns.onboarding_clarity = clamp1to5(s.onboarding_clarity);\ns.objection_handling = clamp1to5(s.objection_handling);\ns.engagement_rapport = clamp1to5(s.engagement_rapport);\ns.close_next_steps = clamp1to5(s.close_next_steps);\nobj.scores = s;\n\n// Gesamtwerte neu berechnen\nconst overall = s.discovery + s.onboarding_clarity + s.objection_handling + s.engagement_rapport + s.close_next_steps;\nobj.overall_score_25 = overall;\nobj.overall_score_percent = Math.round((overall / 25) * 100);\n\n// Output flatten für Sheets/Airtable etc.\nconst out = {\n  meeting_invitees_name: obj.meeting_invitees_name,\n  meeting_invitees_email: obj.meeting_invitees_email,\n  crm_used_past: obj.crm_used_past,\n  pain_points: obj.pain_points,\n  feature_requested: obj.feature_requested,\n  what_i_did_well: obj.what_i_did_well,\n  what_to_improve: obj.what_to_improve,\n  scores_discovery: s.discovery,\n  scores_onboarding_clarity: s.onboarding_clarity,\n  scores_objection_handling: s.objection_handling,\n  scores_engagement_rapport: s.engagement_rapport,\n  scores_close_next_steps: s.close_next_steps,\n  overall_score_25: obj.overall_score_25,\n  overall_score_percent: obj.overall_score_percent,\n  notes: obj.notes\n};\n\nreturn [{ json: out }];"
      },
      "typeVersion": 2
    },
    {
      "id": "d15b7a46-5899-4cdb-b434-41da0b969f20",
      "name": "JavaScriptコード1",
      "type": "n8n-nodes-base.code",
      "position": [
        448,
        -176
      ],
      "parameters": {
        "jsCode": "// === Konfiguration ===\nconst GAP_BREAK_SECONDS = 15;     // Neuer Block, wenn zwischen Sätzen > 15s liegen\nconst INCLUDE_TIMESTAMPS = true;  // Zeitstempel am Block-Anfang zeigen (mm:ss)\nconst TIME_FORMAT = \"mm:ss\";      // mm:ss oder hh:mm:ss\n\n// === Hilfsfunktionen ===\nfunction toTimecode(sec) {\n  if (sec == null || isNaN(sec)) return \"\";\n  const s = Math.max(0, Math.floor(sec));\n  const h = Math.floor(s / 3600);\n  const m = Math.floor((s % 3600) / 60);\n  const ss = s % 60;\n  const pad = (n)=>String(n).padStart(2,\"0\");\n  if (TIME_FORMAT === \"hh:mm:ss\" || h > 0) return `${pad(h)}:${pad(m)}:${pad(ss)}`;\n  return `${pad(m)}:${pad(ss)}`;\n}\n\nfunction cleanText(t) {\n  // Bewahre Original-Satz, aber trimme Leerzeichen\n  return String(t ?? \"\").replace(/\\s+/g, \" \").trim();\n}\n\nfunction ensureEndPunctuation(t) {\n  // Wenn der Block nicht auf . ! ? endet, füge einen Punkt hinzu\n  if (!t) return t;\n  return /[.!?…]$/.test(t) ? t : t + \".\";\n}\n\n// === Input robust finden ===\nconst root = items[0]?.json || {};\nconst data = root.data || root;\nconst sentences = Array.isArray(data.sentences) ? data.sentences.slice() : [];\nconst speakersArr = Array.isArray(data.speakers) ? data.speakers : [];\n\n// Map Speaker-ID -> Name\nconst speakerMap = new Map();\nfor (const s of speakersArr) {\n  if (s && typeof s.id !== \"undefined\") {\n    speakerMap.set(s.id, s.name || `Speaker ${s.id}`);\n  }\n}\n\n// Fallback: wenn speakerMap leer ist, holen wir Namen aus den Sätzen\nif (speakerMap.size === 0) {\n  for (const s of sentences) {\n    if (typeof s.speaker_id !== \"undefined\") {\n      speakerMap.set(s.speaker_id, s.speaker_name || `Speaker ${s.speaker_id}`);\n    }\n  }\n}\n\n// Sortieren nach index (falls vorhanden) sonst start_time\nsentences.sort((a, b) => {\n  if (typeof a.index === \"number\" && typeof b.index === \"number\") return a.index - b.index;\n  return (a.start_time ?? 0) - (b.start_time ?? 0);\n});\n\n// === Gruppierung zu Sprecher-Blöcken ===\nconst blocks = []; // [{ speakerName, startTime, endTime, text }]\nlet current = null;\n\nfor (const s of sentences) {\n  const name = speakerMap.get(s.speaker_id) || s.speaker_name || \"Unbekannt\";\n  const t = cleanText(s.text ?? s.raw_text ?? \"\");\n\n  if (!t) continue;\n\n  const st = Number(s.start_time ?? 0);\n  const et = Number(s.end_time ?? st);\n\n  const shouldBreak =\n    !current ||\n    current.speakerName !== name ||\n    (typeof current.lastEnd === \"number\" && typeof st === \"number\" && st - current.lastEnd > GAP_BREAK_SECONDS);\n\n  if (shouldBreak) {\n    // neuen Block starten\n    current = {\n      speakerName: name,\n      startTime: st,\n      lastEnd: et,\n      texts: [t]\n    };\n    blocks.push(current);\n  } else {\n    // an bestehenden Block anhängen\n    current.texts.push(t);\n    current.lastEnd = et;\n  }\n}\n\n// === Formatierung ===\n\n// a) Formatiert mit Sprecher + Zeit (wie Beispiel)\nconst formattedLines = blocks.map(b => {\n  let linePrefix = b.speakerName + \": \";\n  if (INCLUDE_TIMESTAMPS) {\n    linePrefix = `${b.speakerName}: ${toTimecode(b.startTime)}  `;\n  }\n  const paragraph = ensureEndPunctuation(cleanText(b.texts.join(\" \")));\n  return linePrefix + paragraph;\n});\nconst transcript_formatted = formattedLines.join(\"\\n\\n\");\n\n// b) Plain-Fließtext ohne Zeitstempel, Sprecher dennoch markiert\nconst plainLines = blocks.map(b => {\n  const paragraph = ensureEndPunctuation(cleanText(b.texts.join(\" \")));\n  return `${b.speakerName}: ${paragraph}`;\n});\nconst transcript_plain = plainLines.join(\"\\n\\n\");\n\n// Optional: Metadaten (Titel/Meeting-Link), falls vorhanden\nconst meta = {\n  title: data.title || \"\",\n  meeting_link: data.meeting_link || \"\",\n  organizer_email: data.organizer_email || \"\",\n  date_iso: data.dateString || \"\"\n};\n\nreturn [{\n  json: {\n    transcript_formatted,\n    transcript_plain,\n    meta\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "bd1bf746-bc2f-468e-95ca-8179aab21cec",
      "name": "メッセージを送信",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2016,
        -48
      ],
      "webhookId": "394e352b-227d-446f-a204-0598524b0b09",
      "parameters": {
        "sendTo": "managment@clicklessai.de",
        "message": "Hey, your google sheet is ready! Go check it out!",
        "options": {},
        "subject": "Grading Call System ",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "2Rt5sYy8vHGty2lV",
          "name": "ClickLessAI Gmail"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "bb529931-6899-4905-9a14-a2322f5c8488",
      "name": "メッセージを送信1",
      "type": "n8n-nodes-base.slack",
      "position": [
        1536,
        -48
      ],
      "webhookId": "05be8f86-7174-452b-ad93-bacadaf8e927",
      "parameters": {
        "text": "Hey, your google sheet is ready! Go check it out!",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09HKQVAKB7",
          "cachedResultName": "demo"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "G4NvdInPNhmhP1e9",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d877f4be-78c0-4ea1-af64-6b296c35cd00",
      "name": "付箋",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -480
      ],
      "parameters": {
        "width": 464,
        "height": 608,
        "content": "## Setup fireflies.ai\n\n- Create an Account \n- Setup a Webhook in fireflies.ai \n- API Section: https://app.fireflies.ai/integrations/custom/n8n"
      },
      "typeVersion": 1
    },
    {
      "id": "3253a5b7-fcb5-4652-8bda-2c18639969e9",
      "name": "付箋1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -480
      ],
      "parameters": {
        "color": 5,
        "width": 816,
        "height": 608,
        "content": "## Connect Open AI Credential \nGo to https://platform.openai.com and log in.\n\t2.\tClick on your profile icon in the top-right corner.\n\t3.\tSelect View API keys.\n\t4.\tClick Create new secret key.\n\t5.\tCopy the generated key (it starts with sk-...) and save it securely — you won’t be able to see it again later."
      },
      "typeVersion": 1
    },
    {
      "id": "42cc890a-7510-4dfa-b556-5125357cc34c",
      "name": "付箋2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1232,
        -480
      ],
      "parameters": {
        "color": 4,
        "width": 512,
        "height": 608,
        "content": "## Setup Slack\n\n🔹 Slack API Credentials\n\n\t1.\tGo to https://api.slack.com/apps and log in with your Slack account.\n\t2.\tClick Create New App.\n\t•\tChoose From scratch and select your workspace.\n\t3.\tIn the app dashboard, go to OAuth & Permissions.\n\t4.\tUnder Scopes, add the permissions your app needs.\n\t5.\tScroll up and click Install to Workspace.\n\t6.\tOnce installed, you’ll see your Bot User OAuth Token (xoxb-...). Copy and save it securely."
      },
      "typeVersion": 1
    },
    {
      "id": "8d4db160-d9f7-4b8c-9744-f11f99375455",
      "name": "付箋3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1776,
        -480
      ],
      "parameters": {
        "width": 464,
        "height": 608,
        "content": "## Setup Gmail  \n\n1.\tGo to https://console.cloud.google.com/ and log in.\n2.\tCreate a New Project (or select an existing one).\n3.\tIn the left menu, go to APIs & Services → Library.\n4.\tSearch for Gmail API and click Enable.\n5.\tGo to APIs & Services → Credentials.\n6.\tClick Create Credentials → OAuth client ID.\n7. You’ll need to configure an OAuth consent screen first (name + scope).\n8.\tChoose the app type (e.g., Desktop, Web).\n9.\tOnce created, copy your Client ID and Client Secret.\n10.\tDownload the credentials.json file (you’ll need it for client apps)."
      },
      "typeVersion": 1
    },
    {
      "id": "13ec4b49-ebed-4fa3-bc00-993951948242",
      "name": "付箋4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        -848
      ],
      "parameters": {
        "color": 6,
        "width": 368,
        "height": 336,
        "content": "## How it Works \n\n\t1.\tTrigger via Webhook – The workflow starts whenever a Fireflies.ai transcript is available.\n\t2.\tTranscript Analysis – The call transcript is passed to OpenAI, which evaluates and grades the quality of the call.\n\t3.\tLead Data Logging – The graded results and lead information are automatically appended into a Google Sheet for record-keeping and performance tracking.\n\t4.\tNotifications – You instantly receive a Slack or Gmail notification summarizing the evaluation, ensuring you never miss important insights."
      },
      "typeVersion": 1
    },
    {
      "id": "9c4a4d5d-e559-4302-9c34-b762b95dbe22",
      "name": "付箋5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        -848
      ],
      "parameters": {
        "color": 6,
        "width": 368,
        "height": 336,
        "content": "## Why its Valuable \n\n\t•\t✅ Automated Call Reviews – No need to manually re-listen or grade calls.\n\t•\t✅ Consistent Scoring – Objective AI-powered evaluation improves training and feedback.\n\t•\t✅ Centralized Data – All call insights and lead details are stored neatly in Google Sheets.\n\t•\t✅ Instant Alerts – Sales teams get notified right away via Slack or Gmail, boosting response times.\n\t•\t✅ Scalable – Works out-of-the-box for onboarding, sales, or support teams, and reduces manual overhead.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e3db7392-05a2-4fca-abfd-7f442e5563b9",
  "connections": {
    "a9579f80-9bec-473c-83c4-66b1134194ee": {
      "main": [
        [
          {
            "node": "072de8f9-05a4-4c32-a3a8-42726eefe3e3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "57c6c8ee-a89d-4fd1-b7ae-e5fcb54ebb34": {
      "main": [
        [
          {
            "node": "2a5072fd-8895-41d6-b2bd-9c005b7d1b5d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "072de8f9-05a4-4c32-a3a8-42726eefe3e3": {
      "main": [
        [
          {
            "node": "d15b7a46-5899-4cdb-b434-41da0b969f20",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2a5072fd-8895-41d6-b2bd-9c005b7d1b5d": {
      "main": [
        [
          {
            "node": "d7377f6f-c1cc-47a9-8d1d-99dadd47fb2f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d7377f6f-c1cc-47a9-8d1d-99dadd47fb2f": {
      "main": [
        [
          {
            "node": "bd1bf746-bc2f-468e-95ca-8179aab21cec",
            "type": "main",
            "index": 0
          },
          {
            "node": "bb529931-6899-4905-9a14-a2322f5c8488",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d15b7a46-5899-4cdb-b434-41da0b969f20": {
      "main": [
        [
          {
            "node": "57c6c8ee-a89d-4fd1-b7ae-e5fcb54ebb34",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

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

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

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

中級

有料ですか?

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

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

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

作成者
Emilio Loewenstein

Emilio Loewenstein

@emilio-loewenstein

Emilio is an 18-year-old AI Engineer and Co-Founder of an AI agency, building intelligent systems that help businesses automate, innovate, and scale.

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34