Fathom 会议摘要与行动 AI Agent
高级
这是一个自动化工作流,包含 18 个节点。主要使用 If, Set, Code, Webhook, GoogleDrive 等节点。 使用Gemini AI将Fathom会议转录转换为格式化的Google文档摘要
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •Google Drive API 凭证
- •可能需要目标 API 的认证凭证
- •Google Gemini API Key
使用的节点 (18)
分类
-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "AJch0Bi1L5u67nRO",
"meta": {
"instanceId": "90dd23d886c9cb675f452d0fb004af6ee783e4e974ef4384cbfad1854c68a875",
"templateCredsSetupCompleted": true
},
"name": "Fathom 会议摘要与行动 AI Agent",
"tags": [],
"nodes": [
{
"id": "a362776f-d572-4983-9dc6-a161ddd30392",
"name": "Google Gemini 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
96,
16
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-pro"
},
"credentials": {
"googlePalmApi": {
"id": "etClcv7ej0yswPTF",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "73dc3249-bc5d-4676-95e8-bcd4b2fea8e9",
"name": "结构化输出解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
272,
16
],
"parameters": {
"jsonSchemaExample": "{\n \"Meeting Title\": \"Test call\",\n \"Recording URL\": \"https://fathom.video/share/745cvtcxSXKb7YyfDMiyzMChZ3AsoGad\",\n \"Scheduled Date/Time\": \"30-01-2025, 12:15 to 12:30\",\n \"Recording Date/Time\": \"30-01-2025, 12:16 to 12:16\",\n \"Attendees\": \"John Doe <johndoe@domain.com> (Attendee)\",\n \"Executive Summary\": \"Single-speaker intro explaining that Fathom auto-records meetings, captures key moments and action items, and allows manual highlights. No concrete decisions or actions were stated.\",\n \"Key Points\": \"Fathom auto-records and captures important moments and action items.\\nPost-meeting summaries are delivered quickly.\\nManual highlight button available for special moments.\",\n \"Action Items\": \"Send John 2-3 specific YouTube video links.\\nGet automation engineer to review Sheets integration Mon-Tue.\",\n \"Decisions\": \"Emmily to update feature on the contact page.\\nJohn will speak to Jess about product development roadmap.\",\n \"Risks/Concerns\": \"John mentioned development pace is slow in January meaning a late release date is likely.\",\n \"Open Questions\": \"What's the status of the Hubspot implementation?\\nNone identified in the transcript.\",\n \"Entities — People\": \"Emmily Bowman; John Doe\",\n \"Entities — Orgs/Places\": \"Fathom\",\n \"Entities — Numbers/Dates\": \"30 seconds\"\n}\n"
},
"typeVersion": 1.3
},
{
"id": "a4e520d6-c9bd-4060-94b4-e61f7ef38b19",
"name": "格式化关键部分",
"type": "n8n-nodes-base.code",
"position": [
-368,
-96
],
"parameters": {
"jsCode": "// Minimal formatter: merged transcript turns with per-line timestamps\n\nconst b = $json.body ?? $json ?? {};\nconst toStr = (v) => (typeof v === 'string' ? v.trim() : (v ?? '') + '');\nconst tsToSec = (ts) => {\n const m = typeof ts === 'string' && ts.match(/^(\\d{2}):(\\d{2}):(\\d{2})$/);\n if (!m) return 0;\n const [, hh, mm, ss] = m;\n return (+hh) * 3600 + (+mm) * 60 + (+ss);\n};\nconst uniqBy = (arr, keyFn) => {\n const seen = new Set();\n return arr.filter(x => {\n const key = keyFn(x);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\n// ---- Attendees (optional) ----\nconst invitees = Array.isArray(b.calendar_invitees) ? b.calendar_invitees : [];\nconst attendeesRaw = [\n ...invitees.map(i => ({\n name: toStr(i.name) || toStr(i.matched_speaker_display_name) || 'Unknown',\n email: toStr(i.email) || null,\n role: 'Attendee',\n })),\n ...(b.recorded_by ? [{\n name: toStr(b.recorded_by.name) || 'Unknown',\n email: toStr(b.recorded_by.email) || null,\n role: 'Host',\n }] : []),\n];\nconst attendees = uniqBy(attendeesRaw, a => a.email ? `e:${a.email.toLowerCase()}` : `n:${a.name.toLowerCase()}`);\n\n// ---- Per-line → normalize + sort ----\nconst tItems = Array.isArray(b.transcript) ? b.transcript : [];\nconst lines = tItems\n .map(i => ({\n timestamp: toStr(i?.timestamp) || '00:00:00',\n seconds: tsToSec(toStr(i?.timestamp)),\n speaker: toStr(i?.speaker?.display_name) || 'Unknown',\n email: toStr(i?.speaker?.matched_calendar_invitee_email) || null,\n text: toStr(i?.text),\n }))\n .filter(x => x.text)\n .sort((a, c) => a.seconds - c.seconds)\n .map(({ seconds, ...rest }) => rest);\n\n// ---- Merge consecutive lines by the same person, but keep per-line timestamps ----\nconst norm = s => (s || '').trim().replace(/\\s+/g, ' ').toLowerCase();\nconst samePerson = (a, b) => {\n const ae = (a.email || '').toLowerCase();\n const be = (b.email || '').toLowerCase();\n if (ae && be) return ae === be;\n const an = norm(a.speaker);\n const bn = norm(b.speaker);\n if (!ae && !be && (an === 'unknown' || bn === 'unknown')) return false;\n return an === bn;\n};\n\nconst transcript_merged = [];\nfor (const line of lines) {\n const last = transcript_merged[transcript_merged.length - 1];\n const entry = { ts: line.timestamp, text: line.text.trim() };\n\n if (last && samePerson(last, line)) {\n last.lines.push(entry); // keep per-line timestamps\n last.texts.push(entry.text); // backwards-compat (array of strings)\n last.end_timestamp = line.timestamp;\n } else {\n transcript_merged.push({\n speaker: line.speaker,\n email: line.email || null,\n start_timestamp: line.timestamp,\n end_timestamp: line.timestamp,\n start_seconds: tsToSec(line.timestamp),\n lines: [entry], // <-- preferred for HTML rendering\n texts: [entry.text], // <-- legacy compatibility\n });\n }\n}\n\n// ---- Pretty text (one line per turn; keeps the start ts for the turn) ----\nconst SENTENCE_SEP = ' ';\nconst transcript_text = transcript_merged\n .map(m => `[${m.start_timestamp}] ${m.speaker}${m.email ? ` <${m.email}>` : ''}: ${m.lines.map(x => x.text).join(SENTENCE_SEP)}`)\n .join('\\n');\n\n// ---- Output ----\nreturn {\n json: {\n meeting_title: toStr(b.meeting_title) || toStr(b.title) || null,\n attendees,\n scheduled_start_time: toStr(b.scheduled_start_time) || null,\n scheduled_end_time: toStr(b.scheduled_end_time) || null,\n recording_start_time: toStr(b.recording_start_time) || null,\n recording_end_time: toStr(b.recording_end_time) || null,\n recording_url: toStr(b.share_url) || toStr(b.url) || null,\n transcript_merged, // now includes lines[{ts,text}] + texts[]\n transcript_text, // still available if you need it\n // summary_markdown: toStr(b?.default_summary?.markdown_formatted) || null, // optional\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "a0653858-8a8c-4cc2-a5e1-c67a0a6d192d",
"name": "设置字段",
"type": "n8n-nodes-base.set",
"position": [
432,
-112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "180a6cda-50cc-4533-91a8-0736d1a9cd1f",
"name": "output['Meeting Title']",
"type": "string",
"value": "={{ $json.output[\"Meeting Title\"] + \" - \" + $json.output[\"Scheduled Date/Time\"].replace(/:/g, \"-\") }}"
},
{
"id": "957ef493-cd8b-4359-bb67-25206ac2a6f1",
"name": "output['Recording URL']",
"type": "string",
"value": "={{ $json.output['Recording URL'] }}"
},
{
"id": "38301e62-074a-4206-824a-64b37da4dd91",
"name": "output['Scheduled Time']",
"type": "string",
"value": "={{ $json.output['Scheduled Date/Time'] }}"
},
{
"id": "9b4fa931-0fce-4882-91b2-0af0523005ae",
"name": "output['Recording Time']",
"type": "string",
"value": "={{ $json.output['Recording Date/Time'] }}"
},
{
"id": "38605fc1-6c2d-4d4a-b2a5-597197dc3bd1",
"name": "output.Attendees",
"type": "string",
"value": "={{ $json.output.Attendees }}"
},
{
"id": "bd1f7948-0e94-4834-9066-bb92901a3867",
"name": "output['Executive Summary']",
"type": "string",
"value": "={{ $json.output['Executive Summary'] }}"
},
{
"id": "2757b576-8558-4089-9c6b-9782a42c32ca",
"name": "output['Key Points']",
"type": "string",
"value": "={{ $json.output['Key Points'] }}"
},
{
"id": "38b5bebe-b7ad-4e03-bbb9-64818b18cde6",
"name": "output['Action Items']",
"type": "string",
"value": "={{ $json.output['Action Items'] }}"
},
{
"id": "d07cb155-8799-4110-a244-f052471614e5",
"name": "output.Decisions",
"type": "string",
"value": "={{ $json.output.Decisions }}"
},
{
"id": "7a63e1ae-209e-4d6b-a042-3e59b7f1fe1d",
"name": "output['Risks/Concerns']",
"type": "string",
"value": "={{ $json.output['Risks/Concerns'] }}"
},
{
"id": "4ea08434-1d26-4a05-95d8-12bf2270a4a3",
"name": "output['Open Questions']",
"type": "string",
"value": "={{ $json.output['Open Questions'] }}"
},
{
"id": "20424379-7edc-4f43-b304-814dff3e713e",
"name": "output['Entities — People']",
"type": "string",
"value": "={{ $json.output['Entities — People'] }}"
},
{
"id": "d7eb163b-2de3-4dc7-bc8a-70b2bbef2ea1",
"name": "output['Entities — Orgs/Places']",
"type": "string",
"value": "={{ $json.output['Entities — Orgs/Places'] }}"
},
{
"id": "a8b13e21-867c-49c1-a920-237317be64d9",
"name": "output['Entities — Numbers/Dates']",
"type": "string",
"value": "={{ $json.output['Entities — Numbers/Dates'] }}"
},
{
"id": "e7438bd6-dec3-4162-a66a-fe7fa5e17056",
"name": "transcript_merged",
"type": "array",
"value": "={{ $('Format Key Parts').item.json.transcript_merged }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "431be23c-a097-4cea-a77d-ee9e9a574ab5",
"name": "创建为 HTML",
"type": "n8n-nodes-base.code",
"position": [
704,
-112
],
"parameters": {
"jsCode": "// --- helpers ---\nconst esc = (s='') => s.replace(/[&<>]/g, c => ({'&':'&','<':'<','>':'>'}[c]));\nconst nl2li = s => s.split('\\n').map(x=>`<li>${esc(x.replace(/^-+\\s?/, ''))}</li>`).join('');\nconst chunk = (arr, n=3) => arr.reduce((a,_,i)=>(i%n?a[a.length-1].push(arr[i]):a.push([arr[i]]),a),[]);\n\n// --- inputs ---\nconst o = $json.output; // summary sections\nconst turns = ($node[\"Set Fields\"]?.json?.transcript_merged) || $json.transcript_merged || [];\n\n// --- transcript (speaker change + every 3 sentences; timestamp from first sentence in chunk) ---\nlet transcriptHtml = '—';\nif (Array.isArray(turns) && turns.length) {\n transcriptHtml = turns.map(t => {\n const parts = chunk((t.lines || []).filter(x => x && x.text), 3);\n return parts.map(group => {\n const stamp = group[0]?.ts || t.start_timestamp;\n const text = group.map(x => (x.text || '').trim()).join(' ');\n // email intentionally omitted\n return `<strong>[${esc(stamp)}] ${esc(t.speaker)}:</strong> ${esc(text)}<br>`;\n }).join('');\n }).join('\\n');\n}\n\n// --- HTML (H2/H3/H4; compact, readable) ---\nconst html = `\n <h2>${esc(o[\"Meeting Title\"])}</h2><br>\n\n <h3>Scheduled Time</h3><p>${esc(o[\"Scheduled Time\"])}</p><br>\n <h3>Recording Time</h3><p>${esc(o[\"Recording Time\"])}</p><br>\n <h3>Recording URL</h3><p>${o[\"Recording URL\"] === \"None identified in the transcript\" ? \"—\" : `<a href=\"${esc(o[\"Recording URL\"])}\">${esc(o[\"Recording URL\"])}</a>`}</p><br>\n\n <h3>Attendees</h3><ul>${nl2li(o[\"Attendees\"])}</ul><br>\n <h3>Executive Summary</h3><p>${esc(o[\"Executive Summary\"])}</p><br>\n <h3>Key Points</h3><ul>${nl2li(o[\"Key Points\"])}</ul><br>\n <h3>Action Items</h3><ul>${nl2li(o[\"Action Items\"])}</ul><br>\n <h3>Decisions</h3><ul>${nl2li(o[\"Decisions\"])}</ul><br>\n <h3>Risks/Concerns</h3><ul>${nl2li(o[\"Risks/Concerns\"])}</ul><br>\n <h3>Open Questions</h3><ul>${nl2li(o[\"Open Questions\"])}</ul><br>\n\n <h3>Entities</h3>\n <h4>People</h4><ul>${nl2li(o[\"Entities — People\"])}</ul>\n <h4>Orgs/Places</h4><ul>${nl2li(o[\"Entities — Orgs/Places\"])}</ul>\n <h4>Numbers/Dates</h4><ul>${nl2li(o[\"Entities — Numbers/Dates\"])}</ul><br>\n\n <br><br><hr><br>\n <h3>Full Transcript</h3>\n ${transcriptHtml}\n`.trim();\n\n// -> Binary for Drive Upload (Convert to Google Doc = ON)\nconst filename = `${o[\"Meeting Title\"]} - Meeting Notes.html`;\nconst buf = Buffer.from(html, 'utf8');\nconst data = await this.helpers.prepareBinaryData(buf, filename, 'text/html');\nreturn [{ json: { filename }, binary: { data } }];\n"
},
"typeVersion": 2
},
{
"id": "236d20f7-0deb-48bd-b255-b7d72595958a",
"name": "转换为 Google 文档",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
-112
],
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $json.id }}/copy",
"method": "POST",
"options": {},
"jsonBody": "={\n \"name\": \"{{ $json.name.replace('.html', '') }}\",\n \"mimeType\": \"application/vnd.google-apps.document\"\n }",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "googleDriveOAuth2Api"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 4.2
},
{
"id": "4c05b6b7-76ee-4747-8f5c-1fc8f679407b",
"name": "以 HTML 格式上传文件",
"type": "n8n-nodes-base.googleDrive",
"position": [
912,
-112
],
"parameters": {
"name": "={{ $json.filename }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultUrl": "https://drive.google.com/drive",
"cachedResultName": "/ (Root folder)"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "0387aca5-1023-4606-9983-5e32801bf771",
"name": "删除 HTML 文件",
"type": "n8n-nodes-base.googleDrive",
"position": [
1344,
16
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Upload File as HTML').item.json.id }}"
},
"options": {
"deletePermanently": true
},
"operation": "deleteFile"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "744b6d13-5fb4-4da2-8087-1d20a44bf548",
"name": "AI 会议分析",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
96,
-144
],
"parameters": {
"text": "=For the meeting transcript provided at the bottom, please follow the below template to write your reviewing comments about the meeting.\nNote that if there are sections below that you cannot identify in the transcript, then simply mention \"None identified in the transcript\"\n\n---\n\nMeeting:\nHeader line, nicely formatted and using the information exactly as provided.\nUse the official meeting title here (if provided): '{{ $json.meeting_title }}'\nOr, if there is no meeting title provided, create a title based on your analysis of the raw transcript provided at the end.\n\nRecording URL:\n{{ $json.recording_url }}\n\nScheduled Start Date/Time and End Time:\nFormatted as 'DD-MM-YYYY - HH:MM to HH:MM': {{ $json.scheduled_start_time }} - {{ $json.scheduled_end_time }} \n\nRecording Start Date/Time and End Time:\nFormatted as 'DD-MM-YYYY - HH:MM to HH:MM': {{ $json.recording_start_time }} - {{ $json.recording_end_time }}\n\n---\n\nAttendees:\n- names and email addresses, where available\nAttendee official list:{{ JSON.stringify($json.attendees) }}\nAlso check the transcript to identify additional speakers where possible\n\n\nExecutive Summary:\n- {1–5 sentences, no fluff. What’s the meeting about, key outcome(s), and immediate next step(s)?} \n\nKey Points:\n- {Concise point}.\n- {Another concise point}.\n(8 bullets max, but less is fine if more effective)\n\nAction Items:\n- List of each action item with any mentioned Owner, Due Date, Priority, and Source\n\nKey Decisions Made:\n- Decision:** {What was decided}. (By {who}, if stated) \n(6 bullets max, but less is fine if more effective)\n\n\nKey Risks / Concerns:\n- {Risk/issue}: {Context or impact in 1 line}\n(6 items maximum, but less is fine if more effective)\n\nOpen Questions:\n- {Question asked or unresolved point}\n- {Any missing info needed to proceed}\n(6 items maximum, but less is fine if more effective)\n\nEntities & References (quick extract):\n- People: {names} \n- Organizations/Places: {entities} \n- Numbers & Dates Mentioned (with brief context of why any numbers and dates are provided): {normalize money, dates, durations if present}\n\n\n**For Key Points, Action Items, Decisions, Risks/Concerns, Open Questions: return a single string. If items exist, output them as newline-separated lines (no bullets/numbers). If none, return the exact string “None identified in the transcript”.**\n\n---\n\n*** HERE IS THE TRANSCRIPT: ***\n\n{{ JSON.stringify($json.transcript_merged) }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are an expert meeting analyst. Produce a concise, executive-quality report from the transcript. Be precise, non-fluffy, and focus on important takeaways and outcomes from the meeting."
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "dc09aed6-a43b-470a-9463-72699cf38d4b",
"name": "存在转录文本?",
"type": "n8n-nodes-base.if",
"position": [
-176,
-96
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "validation-check-1",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ JSON.stringify($json.transcript_merged) }}",
"rightValue": ""
},
{
"id": "validation-check-2",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.transcript_merged.length }}",
"rightValue": 3
}
]
}
},
"typeVersion": 2.2
},
{
"id": "a7e3e5c0-64be-462c-a86c-2325e783f693",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-272
],
"parameters": {
"width": 640,
"height": 464,
"content": "## 捕获会议并验证"
},
"typeVersion": 1
},
{
"id": "ac4a64c4-6475-4b1e-a0bb-548a253350a0",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
32,
-272
],
"parameters": {
"color": 6,
"width": 576,
"height": 464,
"content": "## 执行会议分析(AI)"
},
"typeVersion": 1
},
{
"id": "9a58821a-8ff7-46cd-81e9-4407b69f04d3",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
624,
-272
],
"parameters": {
"color": 3,
"width": 944,
"height": 464,
"content": "## 转换为 HTML 输出并上传至 Google Drive"
},
"typeVersion": 1
},
{
"id": "bc8793a2-268d-4379-81de-057fe26b0ce7",
"name": "改善页面布局",
"type": "n8n-nodes-base.httpRequest",
"position": [
1344,
-160
],
"parameters": {
"url": "=https://docs.googleapis.com/v1/documents/{{$node[\"Convert to Google Doc\"].json.id}}:batchUpdate",
"method": "POST",
"options": {},
"jsonBody": "{\n \"requests\": [\n {\n \"updateDocumentStyle\": {\n \"documentStyle\": {\n \"marginTop\": {\"magnitude\": 36, \"unit\": \"PT\"},\n \"marginBottom\": {\"magnitude\": 36, \"unit\": \"PT\"},\n \"marginLeft\": {\"magnitude\": 36, \"unit\": \"PT\"},\n \"marginRight\": {\"magnitude\": 36, \"unit\": \"PT\"}\n },\n \"fields\": \"marginTop,marginBottom,marginLeft,marginRight\"\n }\n }\n ]\n}\n",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "googleDriveOAuth2Api"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "IjoB5flCkLlcfjdH",
"name": "Google Drive account"
}
},
"typeVersion": 4.2
},
{
"id": "76eeb8a0-d87a-442c-8cc9-924b7ee28b59",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1472,
-736
],
"parameters": {
"color": 7,
"width": 816,
"height": 1168,
"content": "# **Fathom 会议摘要与行动 AI Agent**"
},
"typeVersion": 1
},
{
"id": "ca149d7b-3a90-4882-bc9d-2dbddf83872c",
"name": "获取 Fathom 会议",
"type": "n8n-nodes-base.webhook",
"position": [
-560,
-96
],
"webhookId": "2fab6c8f-ade4-49ba-b160-7cf6aa11cb15",
"parameters": {
"path": "2fab6c8f-ade4-49ba-b160-7cf6aa11cb15",
"options": {
"rawBody": true,
"binaryPropertyName": "data"
},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "705471d5-b542-49f6-9342-660884907ea4",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
-496
],
"parameters": {
"color": 7,
"width": 640,
"height": 192,
"content": "## **快速故障排除**"
},
"typeVersion": 1
},
{
"id": "7fd24ad7-f811-42ee-9ca9-fb8490cdf8eb",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-640
],
"parameters": {
"color": 7,
"width": 816,
"height": 336,
"content": "## 示例文件和存储输出"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "NrO9p0iGYkywEkTP",
"executionOrder": "v1"
},
"versionId": "f8839c0b-a795-4745-bca5-dab6a00a5977",
"connections": {
"Set Fields": {
"main": [
[
{
"node": "Create as HTML",
"type": "main",
"index": 0
}
]
]
},
"Create as HTML": {
"main": [
[
{
"node": "Upload File as HTML",
"type": "main",
"index": 0
}
]
]
},
"Format Key Parts": {
"main": [
[
{
"node": "Transcript Present?",
"type": "main",
"index": 0
}
]
]
},
"Get Fathom Meeting": {
"main": [
[
{
"node": "Format Key Parts",
"type": "main",
"index": 0
}
]
]
},
"AI Meeting Analysis": {
"main": [
[
{
"node": "Set Fields",
"type": "main",
"index": 0
}
]
]
},
"Transcript Present?": {
"main": [
[
{
"node": "AI Meeting Analysis",
"type": "main",
"index": 0
}
]
]
},
"Upload File as HTML": {
"main": [
[
{
"node": "Convert to Google Doc",
"type": "main",
"index": 0
}
]
]
},
"Convert to Google Doc": {
"main": [
[
{
"node": "Delete HTML File",
"type": "main",
"index": 0
},
{
"node": "Improve Page Layout",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Meeting Analysis",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "AI Meeting Analysis",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
第一轮 Telegram 和 LinkedIn 快速通道 AI 招聘助手
AI候选人筛选流程:LinkedIn到Telegram,集成Gemini与Apify
If
Set
Code
+15
55 节点Dean Pike
人力资源
第一轮快速通道AI招聘助手
通过Gemini AI分析从Gmail到Slack和Google Sheets的快速简历筛选
If
Set
Code
+15
50 节点Dean Pike
文档代理模板
使用Gemini和Google Drive从模板创建自定义PDF文档
If
Set
Code
+13
36 节点Ozgur Karateke
文档提取
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
使用 Gemini AI 和 Airtable 从图片生成 Shopify 产品列表
使用 Gemini AI 和 Airtable 从图片生成 Shopify 产品列表
If
Set
Code
+16
33 节点MANISH KUMAR
内容创作
宠物店 4
🐶 宠物店预约 AI 代理
If
Set
Code
+41
187 节点Bruno Dias
人工智能
工作流信息
难度等级
高级
节点数量18
分类-
节点类型10
作者
Dean Pike
@deanjpVersatile problem-solver building scalable, AI-driven systems that replace manual, error-prone operations for high-growth companies. Specializing in operational strategy, project delivery, and practical AI and workflow automation solutions that free leaders to focus on strategic priorities while increasing margins without additional hires.
外部链接
在 n8n.io 查看 →
分享此工作流