基于AI的会议效果自动分析与Slack反馈发送
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 18 个节点。主要使用 If, Set, Code, Wait, Slack 等节点。 基于AI的会议效果自动分析与Slack反馈发送
前置要求
- •Slack Bot Token 或 Webhook URL
- •Google Drive API 凭证
- •OpenAI API Key
使用的节点 (18)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "271ad271582e33e7052a1750142c4d1e028deb0c5d010978918984ab393ca4cf",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "650def54-b86d-444f-9d0f-0b20aa6ec372",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
448,
32
],
"parameters": {
"options": {
"systemMessage": "=# Meeting Coach AI System Prompt\n\nYou are a Meeting Coach AI that analyzes meeting effectiveness and provides constructive feedback.\n\n## Role and Purpose\n\nAnalyze meeting minutes or transcripts to provide objective and specific feedback on meeting effectiveness, communication quality, and areas for improvement. Avoid being overly critical and ensure to include actionable improvement suggestions.\n\n## Steps\n\n1. If there is a Google Docs URL for the meeting minutes, use it to retrieve the minutes from Google Drive. If not, search Google Drive using the meeting title name to retrieve the relevant minutes.\n2. If the meeting minutes cannot be found, report this and conclude.\n3. Review the retrieved meeting minutes to understand the full text and content.\n4. Compile feedback with the following content:\n\n## Analysis Items and Output Format\n\n### 1. Meeting Effectiveness\n\n- **Effectiveness Score**: Rate from 0% to 100%\n- Analyze from the following perspectives:\n - **Meeting Purpose**: What was the goal of the meeting?\n - **Achievements**: What was accomplished toward the goal?\n - **Challenges**: What hindered the meeting's effectiveness (e.g., topic derailment, lack of focus)?\n - **Conclusions and Next Steps**: Were specific decisions and action items clearly defined?\n\n### 2. Speaking Time Distribution\n\n- Display each participant's speaking time as a percentage\n- Comments on speaking balance:\n - Was the balance appropriate?\n - Was it a one-sided conversation?\n - Suggestions for more effective dialogue\n\n### 3. Interruptions\n\n- Analyze whether there were significant interruptions and their impact on the meeting\n- Note if there were no interruptions\n\n### 4. Communication Quality\n\nRate each of the following items on a 5-star scale (★☆☆☆☆ to ★★★★★) and provide specific comments:\n\n- **Clarity**: Were the agenda and opinions communicated clearly?\n - ★☆☆☆☆: Very unclear\n - ★★☆☆☆: Unclear\n - ★★★☆☆: Average\n - ★★★★☆: Clear\n - ★★★★★: Very clear\n\n- **Friendliness**: Was the atmosphere cooperative and positive?\n - ★☆☆☆☆: Hostile\n - ★★☆☆☆: Somewhat cold\n - ★★★☆☆: Average\n - ★★★★☆: Friendly\n - ★★★★★: Very friendly\n\n- **Decisiveness**: Were decisions and next actions clearly defined?\n - ★☆☆☆☆: No decisions made\n - ★★☆☆☆: Ambiguous\n - ★★★☆☆: Some decisions\n - ★★★★☆: Clear decisions\n - ★★★★★: Very clear decisions and actions\n\n- **Listening**: Did participants listen to and try to understand each other's opinions?\n - ★☆☆☆☆: Not listening at all\n - ★★☆☆☆: Not listening much\n - ★★★☆☆: Average\n - ★★★★☆: Listening well\n - ★★★★★: Listening very well\n\nFor each item:\n- Quote specific examples of what went well from the conversation\n- Points that could be improved and specific suggestions\n\n### 5. Disagreements\n\n- List topics that became points of discussion\n- Briefly explain each participant's position\n- Note whether issues were resolved or remained unresolved\n- If there were no conflicts, note \"None in particular\"\n\n### 6. Meeting Info\n\n- Meeting title (extract from minutes, or \"Unknown\" if unavailable)\n- List of participants\n\n## Tone and Style\n\n- **Constructive**: Provide insights for growth, not criticism\n- **Specific**: Quote concrete examples from the conversation rather than abstract evaluations\n- **Balanced**: Point out both strengths and areas for improvement\n- **Practical**: Include improvement suggestions that can be implemented immediately\n\n## Output Format\n\n**Meeting Effectiveness** → **[Your evaluated score]%**\n* [Analysis of meeting purpose]\n* [What was achieved]\n* [Challenges]\n* [Evaluation of conclusions and next steps]\n\n**Speaking Time Distribution**\n* **[Participant name]**: [Your calculated percentage]%\n* **[Participant name]**: [Your calculated percentage]%\n* [Comments on speaking balance]\n* [Improvement suggestions]\n\n**Interruptions**\n* [Analysis of presence and impact of interruptions]\n\n**Communication Quality**\n* [Your evaluated number of ★s] **| Clarity**: [Evaluation comment]\n* [Your evaluated number of ★s] **| Friendliness**: [Evaluation comment]\n* [Your evaluated number of ★s] **| Decisiveness**: [Evaluation comment]\n* [Your evaluated number of ★s] **| Listening**: [Evaluation comment]\n* [Specific improvement suggestions and examples of positive points]\n\n**Disagreements**\n❌ [Topic name]:\n1. **[Participant name]**: [Explanation of position]\n2. **[Participant name]**: [Explanation of position]\n3. **Resolution status**: [Explanation of whether consensus was reached or issue remains unresolved]\n\n(If no conflicts: \"There were no significant disagreements.\")\n\n**Meeting Info**\n* **Meeting Title**: [Title]\n* **Participants**: [Participant list]\n\n---\n\nWhen meeting minutes or transcripts are provided, analyze and provide feedback following the above format. Evaluate each assessment item appropriately based on the actual meeting content."
}
},
"typeVersion": 2.2
},
{
"id": "199072fb-3fb9-440d-aa57-44dc6afb2bee",
"name": "OpenAI 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
368,
240
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5",
"cachedResultName": "gpt-5"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "azgro9Tx2nlIAQVv",
"name": "OpenAi(tobe)"
}
},
"typeVersion": 1.2
},
{
"id": "0194fded-a382-47e8-8cec-0a6936df9faa",
"name": "搜索文档",
"type": "n8n-nodes-base.googleDriveTool",
"position": [
576,
416
],
"parameters": {
"limit": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Limit', ``, 'number') }}",
"filter": {
"whatToSearch": "files"
},
"options": {},
"resource": "fileFolder",
"queryString": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search_Query', ``, 'string') }}"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "hOG09SnmNsGXlS9o",
"name": "GoogleDrive(j.tobe)"
}
},
"typeVersion": 3
},
{
"id": "4a61eb43-d664-493b-887e-c412d6652dfc",
"name": "获取文档",
"type": "n8n-nodes-base.googleDocsTool",
"position": [
672,
240
],
"parameters": {
"operation": "get",
"documentURL": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Doc_ID_or_URL', ``, 'string') }}"
},
"credentials": {
"googleDocsOAuth2Api": {
"id": "gIuEB1RhXjXKNGUs",
"name": "GoogldDocs(j.tobe)"
}
},
"typeVersion": 2
},
{
"id": "9d1fa3ac-5030-416e-8020-b2eec0c1f1b4",
"name": "发送消息",
"type": "n8n-nodes-base.slack",
"position": [
1040,
240
],
"webhookId": "ae52c4f6-573f-4388-93d9-a8af0142d929",
"parameters": {
"text": "=テスト",
"user": {
"__rl": true,
"mode": "id",
"value": "U03H0J4KU7R"
},
"select": "user",
"blocksUi": "={{ $json.slackPayload }}",
"messageType": "block",
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "jxDf84zs6Dwcn8NL",
"name": "Slack(j.tobe)"
}
},
"typeVersion": 2.3
},
{
"id": "e9a57402-de45-403f-8f0c-b764dffb7a5c",
"name": "简单记忆",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
448,
416
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "22b64ef2-5672-43c7-9a8c-e761447eedc1",
"name": "Google Calendar 触发器",
"type": "n8n-nodes-base.googleCalendarTrigger",
"position": [
-672,
240
],
"parameters": {
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "eventEnded",
"calendarId": {
"__rl": true,
"mode": "id",
"value": "=[your-id]"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "t5AgzbZYZniiNqS3",
"name": "Google Calendar (j.tobe)"
}
},
"typeVersion": 1
},
{
"id": "c70fd6b4-5428-44ab-8080-f4a10a35de58",
"name": "编辑字段",
"type": "n8n-nodes-base.set",
"position": [
112,
240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "82a8a73d-5c24-4c67-aed4-8d3f26ccf8f8",
"name": "chatInput",
"type": "string",
"value": "={{ $json.summary }} というタイトルの会議を行い {{ $json.attachment[0].fileUrl }} という URL の Google Docs に気議事録を保存しました\n\nGoogle Docs の fileId は {{ $json.attachment[0].fileId }} です"
},
{
"id": "3f8f99b5-9cf2-4005-b1fc-cc89fa79183a",
"name": "=sessionId",
"type": "string",
"value": "=a {{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e468e662-b2fa-4f8a-b01d-e0213cdb4d40",
"name": "等待",
"type": "n8n-nodes-base.wait",
"position": [
-496,
240
],
"webhookId": "04af6fbe-7a07-494a-ad4b-ac3b2d46414b",
"parameters": {
"unit": "minutes"
},
"typeVersion": 1.1
},
{
"id": "8cbf5fe5-879c-456a-9b4d-66d1f04f0b26",
"name": "获取事件",
"type": "n8n-nodes-base.googleCalendar",
"position": [
-336,
240
],
"parameters": {
"eventId": "={{ $json.id }}",
"options": {},
"calendar": {
"__rl": true,
"mode": "id",
"value": "=[your-id]"
},
"operation": "get"
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "t5AgzbZYZniiNqS3",
"name": "Google Calendar (j.tobe)"
}
},
"typeVersion": 1.3
},
{
"id": "ed8ecac5-c3c2-464b-8cfe-540a76525187",
"name": "测试触发器",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-160,
32
],
"webhookId": "14967cec-2211-4d1c-9570-8e7d85ced11e",
"parameters": {
"options": {
"responseMode": "lastNode"
}
},
"typeVersion": 1.3
},
{
"id": "398412f8-29fa-49eb-ac55-cfef96469809",
"name": "代码",
"type": "n8n-nodes-base.code",
"position": [
896,
240
],
"parameters": {
"jsCode": "/**\n * n8n Code node (JavaScript)\n * 入力: $input.first().json.output に Markdown風の長文(実改行 or リテラル \"\\n\")\n * 出力: 最初のアイテムに以下を格納\n * - json.blocks: Array<Block>(Block Kit の配列)\n * - json.slackPayload: { blocks: Array<Block> } // ← UI Builder と同じトップレベル\n * - json.text_fallback: Slack text 用フォールバック\n *\n * 次ノード(Slack 送信例):\n * - Body JSON に {{$json.slackPayload}} をそのまま使う\n * - もしくは blocks: {{$json.blocks}}, text: {{$json.text_fallback}}\n */\n\n// ===== Utils =====\nfunction toActualNewlines(s) {\n if (typeof s !== 'string') return '';\n return s.replace(/\\r\\n?/g, '\\n').replace(/\\\\n/g, '\\n');\n}\n\n// インライン: *bold* / **bold**, _italic_, `code`, [text](url)\nfunction tokenizeInline(text) {\n const tokens = [];\n let i = 0;\n\n const pushPlain = (t) => { if (t) tokens.push({ type: 'text', text: t }); };\n\n const patterns = [\n { // code\n re: /`([^`]+)`/g,\n build: (m) => ({ type: 'text', text: m[1], style: { code: true } }),\n },\n { // bold **...**\n re: /\\*\\*([^*]+)\\*\\*/g,\n build: (m) => ({ type: 'text', text: m[1], style: { bold: true } }),\n },\n { // bold *...* (先頭の箇条書き \"* \" と衝突しないよう調整)\n re: /(^|[^*])\\*([^*\\n]+)\\*(?!\\*)/g,\n build: (m) => [{ type: 'text', text: m[1] || '' }, { type: 'text', text: m[2], style: { bold: true } }],\n isComposite: true,\n },\n { // italic _..._\n re: /_([^_]+)_/g,\n build: (m) => ({ type: 'text', text: m[1], style: { italic: true } }),\n },\n { // link [text](url)\n re: /\\[([^\\]]+)\\]\\((https?:\\/\\/[^\\s)]+)\\)/g,\n build: (m) => ({ type: 'link', url: m[2], text: m[1] }),\n },\n ];\n\n while (i < text.length) {\n let earliest = null, pat = null;\n for (const p of patterns) {\n p.re.lastIndex = i;\n const m = p.re.exec(text);\n if (m && (!earliest || m.index < earliest.index)) {\n earliest = m; pat = p;\n }\n }\n if (!earliest) { pushPlain(text.slice(i)); break; }\n\n if (earliest.index > i) pushPlain(text.slice(i, earliest.index));\n\n if (pat.isComposite) {\n const built = pat.build(earliest);\n for (const b of built) if (b.text !== '') tokens.push(b);\n } else {\n tokens.push(pat.build(earliest));\n }\n\n i = earliest.index + earliest[0].length;\n }\n\n return tokens.length ? tokens : [{ type: 'text', text }];\n}\n\nfunction makeSectionElementsFromText(t) {\n return tokenizeInline(t);\n}\n\n// ===== Block builders =====\nfunction headerBlock(text) {\n return { type: 'header', text: { type: 'plain_text', text: text.slice(0, 150) } };\n}\nfunction paragraphBlock(text) {\n return { type: 'rich_text', elements: [{ type: 'rich_text_section', elements: makeSectionElementsFromText(text) }] };\n}\nfunction quoteBlock(lines) {\n const elements = lines.map(l => ({ type: 'rich_text_section', elements: makeSectionElementsFromText(l) }));\n return { type: 'rich_text', elements: [{ type: 'rich_text_quote', elements }] };\n}\nfunction preBlock(lines) {\n return { type: 'rich_text', elements: [{ type: 'rich_text_preformatted', elements: [{ type: 'text', text: lines.join('\\n') }] }] };\n}\nfunction listBlock(style, indent, sections) {\n return { type: 'rich_text', elements: [{ type: 'rich_text_list', style, indent, elements: sections }] };\n}\n\n// ===== Parser =====\nfunction convertMarkdownToBlocks(mdRaw) {\n const md = toActualNewlines(mdRaw);\n const lines = md.split('\\n');\n const blocks = [];\n\n let inCode = false, codeBuf = [];\n let inQuote = false, quoteBuf = [];\n\n // リスト状態(style/indent で束ねる)\n let listActive = false, listStyle = null, listIndent = 0, listItems = [];\n\n const flushQuote = () => {\n if (inQuote && quoteBuf.length) blocks.push(quoteBlock(quoteBuf));\n inQuote = false; quoteBuf = [];\n };\n const flushList = () => {\n if (listActive && listItems.length) blocks.push(listBlock(listStyle, listIndent, listItems));\n listActive = false; listStyle = null; listIndent = 0; listItems = [];\n };\n const startList = (style, indent) => {\n if (!listActive || listStyle !== style || listIndent !== indent) {\n flushList();\n listActive = true; listStyle = style; listIndent = indent; listItems = [];\n }\n };\n\n const parseListLine = (line) => {\n const leading = (line.match(/^\\s*/)[0] || '').length;\n const trimmed = line.trim();\n if (/^[-*•]\\s+/.test(trimmed)) {\n return { style: 'bullet', indent: Math.floor(leading / 2), text: trimmed.replace(/^[-*•]\\s+/, '') };\n }\n const m = trimmed.match(/^(\\d+)\\.\\s+(.+)$/);\n if (m) {\n return { style: 'ordered', indent: Math.floor(leading / 2), text: m[2] };\n }\n return null;\n };\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n\n // ``` code fence\n if (/^\\s*```/.test(raw)) {\n flushQuote(); flushList();\n if (!inCode) { inCode = true; codeBuf = []; }\n else { blocks.push(preBlock(codeBuf)); inCode = false; codeBuf = []; }\n continue;\n }\n if (inCode) { codeBuf.push(raw); continue; }\n\n // 空行は区切り\n if (/^\\s*$/.test(raw)) {\n flushQuote(); flushList();\n continue;\n }\n\n // 引用\n if (/^\\s*>+\\s?/.test(raw)) {\n flushList();\n const q = raw.replace(/^\\s*>+\\s?/, '');\n inQuote = true; quoteBuf.push(q);\n continue;\n } else if (inQuote) {\n flushQuote();\n }\n\n // 見出し(#〜### or **見出し** 単独行)\n if (/^\\s*#{1,3}\\s+/.test(raw) || /^\\s*\\*\\*(.+?)\\*\\*\\s*$/.test(raw)) {\n flushQuote(); flushList();\n const text = /^\\s*#{1,3}\\s+/.test(raw)\n ? raw.replace(/^\\s*#{1,3}\\s+/, '').trim()\n : (raw.match(/^\\s*\\*\\*(.+?)\\*\\*\\s*$/)[1] || '').trim();\n blocks.push(headerBlock(text));\n continue;\n }\n\n // リスト\n const li = parseListLine(raw);\n if (li) {\n flushQuote();\n startList(li.style, li.indent);\n listItems.push({ type: 'rich_text_section', elements: makeSectionElementsFromText(li.text) });\n continue;\n } else {\n flushList();\n }\n\n // 通常段落\n blocks.push(paragraphBlock(raw));\n }\n\n // 残り\n if (inCode && codeBuf.length) blocks.push(preBlock(codeBuf));\n flushQuote(); flushList();\n\n return blocks;\n}\n\n// ===== Main =====\nconst items = $input.all();\nconst first = $input.first();\nconst source = first?.json?.output ?? '';\n\nconst blocks = convertMarkdownToBlocks(source);\n\n// text_fallback: 最初の header / paragraph を抽出\nlet textFallback = 'Message';\nfor (const b of blocks) {\n if (b.type === 'header') { textFallback = b.text?.text?.slice(0, 300) || textFallback; break; }\n if (b.type === 'rich_text') {\n const el = b.elements?.[0];\n if (el?.type === 'rich_text_section') {\n const s = (el.elements || [])\n .map(e => e.type === 'text' ? e.text : (e.type === 'link' ? (e.text || e.url) : ''))\n .join('');\n if (s) { textFallback = s.slice(0, 300); break; }\n }\n }\n}\n\n// 返却フォーマット(UI Builder と同じトップに blocks)\nfirst.json.blocks = blocks; // 配列(必要ならこちらを直接使う)\nfirst.json.slackPayload = { blocks }; // ← 期待どおりの { \"blocks\": [...] }\nfirst.json.text_fallback = textFallback;\n\nreturn items;\n"
},
"typeVersion": 2
},
{
"id": "bc7b5908-d4b5-4d91-b682-59b98c30d79b",
"name": "条件判断",
"type": "n8n-nodes-base.if",
"position": [
-160,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6385b3c0-7c81-46f4-81cd-3693ea460ab1",
"operator": {
"type": "boolean",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.attachment }} ",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d7a63115-97ba-4022-9338-f7ab40252b56",
"name": "无操作,不执行任何操作",
"type": "n8n-nodes-base.noOp",
"position": [
112,
448
],
"parameters": {},
"typeVersion": 1
},
{
"id": "71f79653-49b9-4faa-bd5b-2787ab8bb30a",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-752,
-48
],
"parameters": {
"width": 768,
"height": 656,
"content": "## 触发器"
},
"typeVersion": 1
},
{
"id": "a42391fb-cda2-438e-957b-8c342f505842",
"name": "便签 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
-48
],
"parameters": {
"color": 4,
"height": 464,
"content": "## 调整格式"
},
"typeVersion": 1
},
{
"id": "5f128546-5780-48c4-967e-eb81fff4f611",
"name": "便签 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
320,
-48
],
"parameters": {
"color": 5,
"width": 496,
"height": 656,
"content": "## AI 节点"
},
"typeVersion": 1
},
{
"id": "65be1eda-c622-4bd6-83b9-1c066b55427d",
"name": "便签 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
848,
-48
],
"parameters": {
"color": 3,
"width": 384,
"height": 656,
"content": "## 输出节点"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"If": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Get an event",
"type": "main",
"index": 0
}
]
]
},
"GetDoc": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"SearchDoc": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Get an event": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Test Trigger": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Google Calendar Trigger": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
✨🩷自动化社交媒体内容发布工厂 + 系统提示组合
基于动态系统提示和GPT-4o的AI驱动多平台社交媒体内容工厂
If
Set
Code
+20
100 节点Amit Mehta
内容创作
批量SEO内容生成与带AI图片的Webflow草稿创建(模板)
使用GPT、Gemini图片和Webflow草稿创建进行批量SEO内容生成
If
Set
Code
+18
54 节点Dahiana
内容创作
完整的 B2B 销售流程:Apollo 潜在客户生成、Mailgun 外展和 AI 回复管理
完整的 B2B 销售流程:Apollo 潜在客户生成、Mailgun 外展和 AI 回复管理
If
Set
Code
+26
116 节点Paul
内容创作
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
使用 OpenAI、LangChain 和 API 集成的工作流自动化初学者指南
使用 OpenAI、LangChain 和 API 集成的工作流自动化初学者指南
If
Set
Code
+13
33 节点Meelioo
内容创作
1. 播放列表详情设置机器人副本
使用 Suno、GPT-4、Runway 和 Creatomate 创建 AI 生成的 YouTube 音乐播放列表
If
Set
Code
+22
203 节点Joseph
内容创作