旅行故事讲述器
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 19 个节点。主要使用 Set, Code, Merge, Webhook, SplitOut 等节点。 使用GPT-4O Vision将旅行照片转换为叙事故事
前置要求
- •HTTP Webhook 端点(n8n 会自动生成)
- •OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "LvEhaVWxPx14FYiD",
"meta": {
"instanceId": "3c35a703d75886d08705c211ee107a7513430dd05494ec0c569f28570a3768fa",
"templateCredsSetupCompleted": true
},
"name": "TripTeller",
"tags": [
{
"id": "TOmp11D0RTZnlXKe",
"name": "Creator Hub",
"createdAt": "2025-07-27T06:39:31.509Z",
"updatedAt": "2025-07-27T06:39:31.509Z"
}
],
"nodes": [
{
"id": "split-photos",
"name": "拆分照片数组",
"type": "n8n-nodes-base.splitOut",
"position": [
384,
112
],
"parameters": {
"options": {
"destinationFieldName": "data"
},
"fieldToSplitOut": "photos"
},
"typeVersion": 1
},
{
"id": "analyze-image",
"name": "视觉分析",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
896,
-16
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o"
},
"options": {},
"resource": "image",
"inputType": "base64",
"operation": "analyze"
},
"credentials": {
"openAiApi": {
"id": "PzzLblAykQPFIDZf",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "generate-story",
"name": "生成旅行故事",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1600,
112
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1",
"cachedResultName": "GPT-4.1"
},
"options": {
"topP": 1,
"temperature": 0.7,
"presence_penalty": 0,
"frequency_penalty": 0
},
"messages": {
"values": [
{
"content": "=Based on these trip photos and analysis, create an engaging travel story:\n\n{{ JSON.stringify($json.tripDays, null, 2) }}\n\nFormat the output as a structured story with:\n\n1. Trip title\n2. Brief introduction\n3. Day-by-day narrative with titles\n4. Memorable moments highlights\n5. Closing reflection"
},
{
"role": "system",
"content": "=You are a professional storyteller crafting a first-person narrative using the user's photo sequence. Write in a narrative style that brings the journey to life. Include sensory details, emotions, and cultural observations. \n\n**Structure the story by days** with creative titles for each day. Make it personal and immersive. \n\n**Context Summary**\n- Submission Time: {{ $now.toUTC()}}\n- Number of Photos: {{ $json.totalPhotos }}\n- Time Range: {{ $json.dateRange.start }} to {{ $json.dateRange.end }}\n\n**Photos Provided (chronological order):**\n\n\n**Your Task**\n- Create an immersive travel or personal story based on the moments captured in the photos\n- Title the story creatively and meaningfully\n- Write in **first-person past tense**\n- Include **sensory details** (sights, sounds, feelings, etc.)\n- Format using **Markdown**: use headings, paragraphs, and line breaks\n- Do **not** reference filenames or technical details\n- **focus** on emotion, story, and setting\n- Conclude with a reflective insight or emotional takeaway\n\n**Tone & Style Options**\nChoose one based on image mood:\n- Warm and nostalgic\n- Playful and lighthearted\n- Poetic and introspective\n- Adventurous and energetic\n\n**Output Format**\nTitle: <Title for Day 1>\n<Story for the tripDay 1>\n\nTitle: <Title for Day 2>\n<Story for the tripDay 2>\n\nTitle: <Title for Day 3>\n<Story for the tripDay 3>\n\nSummary: <Summarize all trip days in less than 500 words>\n\n"
}
]
},
"jsonOutput": true
},
"credentials": {
"openAiApi": {
"id": "PzzLblAykQPFIDZf",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "format-response",
"name": "格式化最终响应",
"type": "n8n-nodes-base.set",
"position": [
2016,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "success",
"name": "success",
"type": "boolean",
"value": true
},
{
"id": "storybook",
"name": "storybook",
"type": "object",
"value": "={{ $json.message.content }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "1bc0b873-5253-4768-8c82-5e33e8834a25",
"name": "转换为文件",
"type": "n8n-nodes-base.convertToFile",
"position": [
656,
-16
],
"parameters": {
"options": {
"fileName": "={{ $json.data.filename }}"
},
"operation": "toBinary",
"sourceProperty": "data.data"
},
"typeVersion": 1.1
},
{
"id": "edit-fields",
"name": "获取照片数组",
"type": "n8n-nodes-base.set",
"position": [
112,
112
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "photos",
"name": "photos",
"type": "array",
"value": "={{ $item(\"0\").$node[\"Photo Upload Webhook\"].json[\"body\"][\"photos\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ed9d8186-d2fe-462d-bc6d-1471e7ef59ce",
"name": "设置照片属性",
"type": "n8n-nodes-base.set",
"position": [
656,
384
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "df19c366-e65d-4614-a3c5-f1a317b3c1e7",
"name": "filename",
"type": "string",
"value": "={{ $json.data.filename }}"
},
{
"id": "1177488a-ba24-4a04-9cfc-fde61cbfbeb0",
"name": "size",
"type": "number",
"value": "={{ $json.data.size }}"
},
{
"id": "6c83cb35-d22e-4074-b685-a5a229f3edb0",
"name": "timestamp",
"type": "string",
"value": "={{ $json.data.lastModified }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9108850e-3a7a-482d-9f6c-de02e39d2da1",
"name": "合并",
"type": "n8n-nodes-base.merge",
"position": [
1136,
112
],
"parameters": {
"mode": "combine",
"options": {
"clashHandling": {
"values": {
"resolveClash": "preferLast"
}
}
},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "0dfdbab7-3250-4f33-9340-7ee247b0d30c",
"name": "按日期分组照片",
"type": "n8n-nodes-base.code",
"position": [
1344,
112
],
"parameters": {
"jsCode": "// Group photos by date\nconst photosByDate = {};\n\nfor (const item of $input.all()) {\n const dateFormatted = new Date (item.json.timestamp).toDateString();\n const date = dateFormatted;\n if (!photosByDate[date]) {\n photosByDate[date] = [];\n }\n photosByDate[date].push(item.json);\n}\n\n// Sort dates and create day entries\nconst sortedDates = Object.keys(photosByDate).sort();\nconst dayEntries = [];\n\nfor (const date of sortedDates) {\n const photos = photosByDate[date];\n \n // Sort photos by timestamp within each day\n photos.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));\n \n // Extract themes for the day\n const dayThemes = [...new Set(photos.flatMap(p => p.themes))];\n \n dayEntries.push({\n date: date,\n dayNumber: sortedDates.indexOf(date) + 1,\n photos: photos,\n themes: dayThemes,\n photoCount: photos.length\n });\n}\n\nreturn [{\n json: {\n tripDays: dayEntries,\n totalDays: dayEntries.length,\n totalPhotos: $input.all().length,\n dateRange: {\n start: sortedDates[0],\n end: sortedDates[sortedDates.length - 1]\n }\n }\n}];"
},
"typeVersion": 2
},
{
"id": "1867d2c7-1505-4ac6-926a-d072a5dcc219",
"name": "照片上传 Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-160,
112
],
"webhookId": "9b3252c9-6cc8-4ac4-9723-0334a8a76923",
"parameters": {
"path": "tripteller-upload",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2.1
},
{
"id": "3e8ff04a-792d-4a04-99d7-e6b10c8aa105",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-256,
-112
],
"parameters": {
"width": 304,
"height": 416,
"content": "📌 入口点"
},
"typeVersion": 1
},
{
"id": "c35d16d4-226b-4a38-9214-3b9bbc7aca47",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
64,
-112
],
"parameters": {
"height": 416,
"content": "📌 数据提取"
},
"typeVersion": 1
},
{
"id": "617d4322-bddb-4c82-92aa-649c85ebc714",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
320,
-112
],
"parameters": {
"height": 416,
"content": "📌 照片分离"
},
"typeVersion": 1
},
{
"id": "fe77f420-c0b9-4a87-8c83-9b98b4530fdf",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
576,
-256
],
"parameters": {
"height": 400,
"content": "📌 二进制转换"
},
"typeVersion": 1
},
{
"id": "54a27f54-7b44-48ff-ad0c-b00e402a641d",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
576,
160
],
"parameters": {
"height": 368,
"content": "📌 元数据提取"
},
"typeVersion": 1
},
{
"id": "9ffe7801-4a33-4015-b2cd-22a1b7a9874d",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
832,
-256
],
"parameters": {
"height": 400,
"content": "📌 AI 图像分析"
},
"typeVersion": 1
},
{
"id": "e1619f17-e377-43fd-8c92-c9b7ecd65cda",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
-256
],
"parameters": {
"width": 256,
"height": 544,
"content": "📌 时间顺序组织"
},
"typeVersion": 1
},
{
"id": "b073140d-6aec-4314-8f4f-35cbe692aae9",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
-256
],
"parameters": {
"width": 352,
"height": 544,
"content": "📌 AI 故事创作"
},
"typeVersion": 1
},
{
"id": "59dcd8e4-8970-464c-a002-aef80df9dd49",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1904,
-48
],
"parameters": {
"width": 304,
"height": 336,
"content": "📌 输出格式化"
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"executionTimeout": 300,
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all"
},
"versionId": "496dfebf-ab04-45dd-a011-2695e4baaa83",
"connections": {
"Combine": {
"main": [
[
{
"node": "Group Photos by Day",
"type": "main",
"index": 0
}
]
]
},
"Convert to File": {
"main": [
[
{
"node": "Vision Analysis",
"type": "main",
"index": 0
}
]
]
},
"Vision Analysis": {
"main": [
[
{
"node": "Combine",
"type": "main",
"index": 0
}
]
]
},
"Get Photos Array": {
"main": [
[
{
"node": "Split Photos Array",
"type": "main",
"index": 0
}
]
]
},
"Set Photo Attribs": {
"main": [
[
{
"node": "Combine",
"type": "main",
"index": 1
}
]
]
},
"Split Photos Array": {
"main": [
[
{
"node": "Convert to File",
"type": "main",
"index": 0
},
{
"node": "Set Photo Attribs",
"type": "main",
"index": 0
}
]
]
},
"Group Photos by Day": {
"main": [
[
{
"node": "Generate Travel Story",
"type": "main",
"index": 0
}
]
]
},
"Photo Upload Webhook": {
"main": [
[
{
"node": "Get Photos Array",
"type": "main",
"index": 0
}
]
]
},
"Format Final Response": {
"main": [
[]
]
},
"Generate Travel Story": {
"main": [
[
{
"node": "Format Final Response",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
微学习创建器(改进版)
使用 GPT-4 和 Google Docs 将长内容转换为碎片化学习模块
If
Set
Code
+9
25 节点inderjeet Bhambra
内容创作
内容生成器
基于AI的社交媒体内容生成器,采用GPT-4模型的策略方法
Set
Code
Webhook
+6
22 节点inderjeet Bhambra
内容创作
使用OpenAI、RunwayML和ElevenLabs自动化无脸短视频
使用OpenAI、RunwayML和ElevenLabs自动化无脸短视频:从脚本到社交媒体
Set
Code
Wait
+18
56 节点LeeWei
内容创作
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
If
Set
Code
+15
40 节点Adam Crafts
内容创作
使用GPT-4O的AI安全管道
使用GPT-4O安全防御系统防止提示注入攻击
If
Set
Code
+7
26 节点inderjeet Bhambra
安全运维
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
每日 WhatsApp 群组智能分析:GPT-4.1 分析与语音消息转录
If
Set
Code
+20
52 节点Daniel Lianes
杂项
工作流信息
难度等级
高级
节点数量19
分类2
节点类型8
作者
inderjeet Bhambra
@idsinghbhambraI am on a journey to learn and spread the automations through n8n workflows.
外部链接
在 n8n.io 查看 →
分享此工作流