n8n书籍扫描器
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 16 个节点。主要使用 Set, Code, Webhook, HttpRequest, OpenAi 等节点。 使用GPT-4o和Google Books从书架照片中提取并验证书名
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •可能需要目标 API 的认证凭证
- •OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "n1UbcJnl7I5rMDIe",
"meta": {
"instanceId": "7d302cb44fba0420b6a4deb04edff9d7c47e83ef1f3f66f89fe519337b882186",
"templateCredsSetupCompleted": true
},
"name": "n8n提交书籍扫描器",
"tags": [],
"nodes": [
{
"id": "8fc53cb4-d7bc-4fcb-8c6d-1ee90b4ad5b4",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-896,
1376
],
"webhookId": "365ea003-fe66-4211-ae03-69f1456d768e",
"parameters": {
"path": "365ea003-fe66-4211-ae03-69f1456d768e",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
},
{
"id": "a140d496-9098-43b2-97df-089a811a909d",
"name": "响应 Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
592,
1376
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{$json}}"
},
"typeVersion": 1.4
},
{
"id": "050a5432-4d7e-4855-b09f-5ca40a9e0999",
"name": "分析图片",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-448,
1376
],
"parameters": {
"text": "=You are a STRICT transformer. Analyze the image of book spines and return only clearly readable titles and authors. \nDo NOT guess. If the author isn't clearly visible, set \"author\": null.\nNormalize capitalization. Deduplicate by title. \nOutput STRICT JSON only:\n{\"books\":[{\"title\":\"string\",\"author\":\"string|null\"}]}\n",
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"resource": "image",
"imageUrls": "={{$json.image}}\n",
"operation": "analyze"
},
"credentials": {
"openAiApi": {
"id": "iJ4uczBur5RBMvV4",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "50c4d4b8-b164-47fb-b9c6-2234f3cb5952",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-992,
1280
],
"parameters": {
"height": 80,
"content": "Webhook连接到前端,传递包含imageURL(字符串)的JSON"
},
"typeVersion": 1
},
{
"id": "d245e1df-a5a2-487c-bd8f-41601be2f05c",
"name": "便签 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-736,
1520
],
"parameters": {
"height": 80,
"content": "输入被规范化"
},
"typeVersion": 1
},
{
"id": "2c44a9af-f395-45ff-bf4f-91a55c829d3e",
"name": "便签 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-512,
1280
],
"parameters": {
"height": 80,
"content": "图像被分析和转换。"
},
"typeVersion": 1
},
{
"id": "1ec82294-d70b-4ff6-ab34-c7ef156a41b2",
"name": "便签 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-288,
1520
],
"parameters": {
"content": "将输出(本例中为书籍)拆分为单独的项目,为下一步验证书籍与已知来源以确认标题和作者做准备。"
},
"typeVersion": 1
},
{
"id": "44f65fae-f829-4b6b-976b-001d071b82ee",
"name": "便签 4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
1280
],
"parameters": {
"height": 80,
"content": "针对Google Books确认每个标题"
},
"typeVersion": 1
},
{
"id": "917a2da3-3691-4904-8cbc-4c00ee4ed72e",
"name": "便签 5",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
1536
],
"parameters": {
"height": 80,
"content": "规范化数据"
},
"typeVersion": 1
},
{
"id": "62b507e0-5b7d-48a3-9e44-aa4ccf339331",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
304,
1280
],
"parameters": {
"height": 80,
"content": "重新聚合书籍列表并去重"
},
"typeVersion": 1
},
{
"id": "94b96cbc-3bd4-4db8-83ff-eb57b4e516c3",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
1520
],
"parameters": {
"height": 80,
"content": "将列表返回给前端。"
},
"typeVersion": 1
},
{
"id": "c4796062-4c64-474a-85b9-8306585c18b1",
"name": "输入规范化",
"type": "n8n-nodes-base.set",
"position": [
-672,
1376
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "94b88376-fed9-46cf-882f-d4c0d7670350",
"name": "image",
"type": "string",
"value": "={{ ($json.body?.imageUrl || $json.body?.image || $json.imageUrl || $json.image || '').trim() }}\n"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "dbe25007-44da-403b-89bf-bcbf57591d58",
"name": "项目列表拆分",
"type": "n8n-nodes-base.code",
"position": [
-240,
1376
],
"parameters": {
"jsCode": "const items = await $input.all();\nconst out = [];\n\nfunction stripCodeFence(s) {\n return String(s || '')\n .replace(/^```json\\s*/i, '')\n .replace(/^```\\s*/i, '')\n .replace(/```$/, '')\n .trim();\n}\n\nfunction firstAuthor(a) {\n if (!a) return null;\n // keep a single name for better \"inauthor:\" matching\n const s = String(a);\n const parts = s.split(/\\s*(?:,| and |&)\\s*/i);\n return (parts[0] || '').trim() || null;\n}\n\nfor (const item of items) {\n let books = null;\n\n // Case 1: you already have an object with books[]\n if (Array.isArray(item.json?.books)) {\n books = item.json.books;\n }\n\n // Case 2: you have a string in `content` with ```json ... ```\n if (!books && typeof item.json?.content === 'string') {\n const cleaned = stripCodeFence(item.json.content);\n try {\n const parsed = JSON.parse(cleaned);\n if (Array.isArray(parsed.books)) books = parsed.books;\n } catch (e) {\n // ignore; we'll fall back\n }\n }\n\n if (!books) continue;\n\n for (const b of books) {\n out.push({\n json: {\n title: b.title,\n author: b.author ?? null,\n // helper field only for the search query:\n searchAuthor: firstAuthor(b.author)\n }\n });\n }\n}\n\nreturn out;\n"
},
"typeVersion": 2
},
{
"id": "2017d011-6d85-4844-a08a-0a7e88ae052d",
"name": "标题验证",
"type": "n8n-nodes-base.httpRequest",
"position": [
-32,
1376
],
"parameters": {
"url": "https://www.googleapis.com/books/v1/volumes",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "=q",
"value": "={{ \n 'intitle:\"' + $json.title.replace(/\"/g,'') + '\"' +\n ($json.searchAuthor ? ' inauthor:\"' + $json.searchAuthor.replace(/\"/g,'') + '\"' : '')\n}}\n"
},
{
"name": "maxResults",
"value": "5"
},
{
"name": "printType",
"value": "books"
},
{
"name": "orderBy",
"value": "relevance"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "7d94ce36-fc7c-44cb-8df6-6f13293160a4",
"name": "数据规范化",
"type": "n8n-nodes-base.set",
"position": [
176,
1376
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "67464bb0-8615-41a5-8408-11a95708d200",
"name": "=title",
"type": "string",
"value": "={{ $json.items?.[0]?.volumeInfo?.title || $prevNode('Code').json.title }}\n"
},
{
"id": "8db9c2f0-3193-428e-adab-2745f397233c",
"name": "author",
"type": "string",
"value": "={{ $json.items?.[0]?.volumeInfo?.authors?.[0] || $prevNode('Code').json.author || null }}\n"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "99d74571-f35d-4086-93ce-f7f67768a8f0",
"name": "重新聚合列表",
"type": "n8n-nodes-base.code",
"position": [
384,
1376
],
"parameters": {
"jsCode": "const items = await $input.all();\nconst seen = new Set();\nconst books = [];\n\nfor (const it of items) {\n const t = (it.json.title || '').toLowerCase().trim();\n if (t && !seen.has(t)) {\n seen.add(t);\n books.push({ title: it.json.title, author: it.json.author ?? null });\n }\n}\n\nreturn [{ json: { books } }];\n"
},
"typeVersion": 2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "5f454fe8-f8b7-4302-820e-ec24a00f13bd",
"connections": {
"Webhook": {
"main": [
[
{
"node": "Input normalized",
"type": "main",
"index": 0
}
]
]
},
"Analyze image": {
"main": [
[
{
"node": "Item list split",
"type": "main",
"index": 0
}
]
]
},
"Data normalized": {
"main": [
[
{
"node": "Reaggregates list",
"type": "main",
"index": 0
}
]
]
},
"Item list split": {
"main": [
[
{
"node": "Title validation",
"type": "main",
"index": 0
}
]
]
},
"Input normalized": {
"main": [
[
{
"node": "Analyze image",
"type": "main",
"index": 0
}
]
]
},
"Title validation": {
"main": [
[
{
"node": "Data normalized",
"type": "main",
"index": 0
}
]
]
},
"Reaggregates list": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用GPT-4o-mini的技术SEO审计与多格式报告(Sheets-Email)
使用GPT-4o-mini的技术SEO审计与多格式报告(Sheets/Email)
Set
Xml
Code
+14
45 节点Oriol Seguí
内容创作
会议纪要和行动项跟踪器
基于AI的会议纪要:使用GPT-4、任务分配和多渠道分发
If
Set
Code
+10
38 节点Jitesh Dugar
内容创作
内容生成器
基于AI的社交媒体内容生成器,采用GPT-4模型的策略方法
Set
Code
Webhook
+6
22 节点inderjeet Bhambra
内容创作
自动化潜在客户呼叫:VAPI、Google Sheets记录与日历预约
自动化潜在客户呼叫:VAPI、Google Sheets记录与日历预约
Set
Code
Webhook
+7
13 节点Meak
内容创作
使用 AI 撰写 WordPress 文章(从几个关键词开始)
基于GPT-4、DALL-E和Wikipedia的自动化博客文章生成器(用于WordPress)
If
Set
Code
+9
37 节点Punit
内容创作
使用 OpenAI、LangChain 和 API 集成的工作流自动化初学者指南
使用 OpenAI、LangChain 和 API 集成的工作流自动化初学者指南
If
Set
Code
+13
33 节点Meelioo
内容创作