{"workflow":{"id":14265,"name":"Create AI travel journal stories from WhatsApp using Claude and Google Drive","views":48,"recentViews":1,"totalViews":48,"createdAt":"2026-03-23T09:52:04.552Z","description":"Automatically converts your daily WhatsApp messages and photos from travels into beautifully structured travel stories, saved as documents in Google Drive.\n\n### How it works\n\n1. **Receive WhatsApp Updates** - Webhook captures messages, photos, and locations from your travel day\n2. **Validate & Aggregate Content** - JavaScript organizes messages by day, extracts metadata, validates media\n3. **Fetch Previous Entries** - Retrieves existing journal from Google Drive for context and continuity\n4. **Prepare AI Context** - JavaScript builds comprehensive prompt with photos, messages, locations, and timeline\n5. **Claude AI Story Generation** - Transforms raw messages into narrative travel journal with insights\n6. **Parse & Format Story** - JavaScript structures the output into readable document format\n7. **Wait for Finalization** - Brief pause to ensure all processing completes\n8. **Save to Google Drive** - Creates or updates your travel journal document\n9. **Send Confirmation** - WhatsApp notification with preview of generated story\n10. **Respond to Webhook** - Returns success confirmation\n\n### Setup Steps\n\n1. Import workflow into n8n\n2. Configure credentials:\n   - **Anthropic API** - Claude AI for story generation\n   - **Google Drive** - Document storage and retrieval\n   - **WhatsApp Business API** or **Twilio WhatsApp** - Message integration\n3. Create a Google Drive folder for your travel journals\n4. Set up WhatsApp webhook integration:\n   - Point WhatsApp webhook to: `https://your-n8n-instance.com/webhook/travel-journal`\n   - Configure to send: messages, media, locations\n5. Update the \"Fetch Previous Journal\" node with your Drive folder ID\n6. Activate the workflow\n\n### Sample WhatsApp Input\n\n**Messages throughout the day:**\n- 09:30 AM: \"Just arrived in Kyoto! The train station architecture is stunning 🚄\"\n- 11:45 AM: \"Fushimi Inari shrine - thousands of orange torii gates going up the mountain\"\n- 📸 Photo: Torii gates pathway\n- 02:15 PM: \"Tried okonomiyaki for lunch. Amazing! The chef made it right in front of us\"\n- 📸 Photo: Okonomiyaki cooking\n- 05:30 PM: \"Gion district at sunset. Spotted two geishas!\"\n- 📍 Location: Gion, Kyoto, Japan\n- 08:45 PM: \"Dinner at an izakaya. Made friends with locals who taught us drinking games 😄\"\n\n### Generated Journal Output\n\n**Day 3: Kyoto - Ancient Temples and Modern Connections**\n\nThe day began with anticipation as the shinkansen pulled into Kyoto Station at 9:30 AM. The station itself was an architectural marvel—a blend of traditional Japanese aesthetics and contemporary design that set the tone for what would be an unforgettable day.\n\nBy mid-morning, I found myself at Fushimi Inari Taisha, one of Kyoto's most iconic sites. The seemingly endless tunnel of vermillion torii gates created a mesmerizing pathway up Mount Inari. Each gate, donated by individuals and businesses, bore inscriptions in black kanji. The experience was both spiritual and surreal—the way light filtered through the gates, creating dancing shadows on the stone path...\n\n[Full narrative continues with integrated photos, locations, and emotional insights]\n\n### Features\n- **Smart Aggregation** - Groups messages by day, even across time zones\n- **Photo Integration** - Embeds images inline with contextual descriptions\n- **Location Awareness** - Maps locations and adds geographical context\n- **Narrative Style** - Converts casual messages into polished travel prose\n- **Emotional Intelligence** - Captures mood and significance beyond literal text\n- **Timeline Coherence** - Maintains chronological flow and story arc\n- **Automatic Continuity** - Links to previous days for multi-day trip journals\n- **Format Flexibility** - Outputs as Google Docs with proper formatting\n\n### Privacy & Data\n- Messages are processed in real-time and not stored long-term\n- Photos are referenced but can be embedded or linked based on preference\n- Journal documents are private in your Google Drive\n- No message content is retained after journal generation","workflow":{"id":"DYwrdXRepewlWcH1","meta":{"instanceId":"dd69efaf8212c74ad206700d104739d3329588a6f3f8381a46a481f34c9cc281","templateCredsSetupCompleted":true},"name":"AI Travel Memory Journal Generator - WhatsApp to Drive Story","tags":[],"nodes":[{"id":"a9b2ea33-0b60-4c8e-b2b7-7aad386187bf","name":"Main Documentation","type":"n8n-nodes-base.stickyNote","position":[0,-384],"parameters":{"width":820,"height":1704,"content":"## AI Travel Memory Journal Generator\n\nAutomatically converts your daily WhatsApp messages and photos from travels into beautifully structured travel stories, saved as documents in Google Drive.\n\n### How it works\n\n1. **Receive WhatsApp Updates** - Webhook captures messages, photos, and locations from your travel day\n2. **Validate & Aggregate Content** - JavaScript organizes messages by day, extracts metadata, validates media\n3. **Fetch Previous Entries** - Retrieves existing journal from Google Drive for context and continuity\n4. **Prepare AI Context** - JavaScript builds comprehensive prompt with photos, messages, locations, and timeline\n5. **Claude AI Story Generation** - Transforms raw messages into narrative travel journal with insights\n6. **Parse & Format Story** - JavaScript structures the output into readable document format\n7. **Wait for Finalization** - Brief pause to ensure all processing completes\n8. **Save to Google Drive** - Creates or updates your travel journal document\n9. **Send Confirmation** - WhatsApp notification with preview of generated story\n10. **Respond to Webhook** - Returns success confirmation\n\n### Setup Steps\n\n1. Import workflow into n8n\n2. Configure credentials:\n   - **Anthropic API** - Claude AI for story generation\n   - **Google Drive** - Document storage and retrieval\n   - **WhatsApp Business API** or **Twilio WhatsApp** - Message integration\n3. Create a Google Drive folder for your travel journals\n4. Set up WhatsApp webhook integration:\n   - Point WhatsApp webhook to: `https://your-n8n-instance.com/webhook/travel-journal`\n   - Configure to send: messages, media, locations\n5. Update the \"Fetch Previous Journal\" node with your Drive folder ID\n6. Activate the workflow\n\n### Sample WhatsApp Input\n\n**Messages throughout the day:**\n- 09:30 AM: \"Just arrived in Kyoto! The train station architecture is stunning 🚄\"\n- 11:45 AM: \"Fushimi Inari shrine - thousands of orange torii gates going up the mountain\"\n- 📸 Photo: Torii gates pathway\n- 02:15 PM: \"Tried okonomiyaki for lunch. Amazing! The chef made it right in front of us\"\n- 📸 Photo: Okonomiyaki cooking\n- 05:30 PM: \"Gion district at sunset. Spotted two geishas!\"\n- 📍 Location: Gion, Kyoto, Japan\n- 08:45 PM: \"Dinner at an izakaya. Made friends with locals who taught us drinking games 😄\"\n\n### Generated Journal Output\n\n**Day 3: Kyoto - Ancient Temples and Modern Connections**\n\nThe day began with anticipation as the shinkansen pulled into Kyoto Station at 9:30 AM. The station itself was an architectural marvel—a blend of traditional Japanese aesthetics and contemporary design that set the tone for what would be an unforgettable day.\n\nBy mid-morning, I found myself at Fushimi Inari Taisha, one of Kyoto's most iconic sites. The seemingly endless tunnel of vermillion torii gates created a mesmerizing pathway up Mount Inari. Each gate, donated by individuals and businesses, bore inscriptions in black kanji. The experience was both spiritual and surreal—the way light filtered through the gates, creating dancing shadows on the stone path...\n\n[Full narrative continues with integrated photos, locations, and emotional insights]\n\n### Features\n- **Smart Aggregation** - Groups messages by day, even across time zones\n- **Photo Integration** - Embeds images inline with contextual descriptions\n- **Location Awareness** - Maps locations and adds geographical context\n- **Narrative Style** - Converts casual messages into polished travel prose\n- **Emotional Intelligence** - Captures mood and significance beyond literal text\n- **Timeline Coherence** - Maintains chronological flow and story arc\n- **Automatic Continuity** - Links to previous days for multi-day trip journals\n- **Format Flexibility** - Outputs as Google Docs with proper formatting\n\n### Privacy & Data\n- Messages are processed in real-time and not stored long-term\n- Photos are referenced but can be embedded or linked based on preference\n- Journal documents are private in your Google Drive\n- No message content is retained after journal generation"},"typeVersion":1},{"id":"141c7e92-e8ac-46f5-b259-bc14afb4aa03","name":"Section 1 - Input Processing","type":"n8n-nodes-base.stickyNote","position":[1008,152],"parameters":{"color":5,"width":480,"height":360,"content":"## 1. WhatsApp Input & Validation"},"typeVersion":1},{"id":"79206477-ca0f-4117-9459-68738620585b","name":"Section 2 - Context Building","type":"n8n-nodes-base.stickyNote","position":[1544,-20],"parameters":{"color":5,"width":880,"height":740,"content":"## 2. Journal Context & AI Processing"},"typeVersion":1},{"id":"1c179b32-2d4f-408c-8bef-1c1e9c29b838","name":"Section 3 - Storage & Delivery","type":"n8n-nodes-base.stickyNote","position":[2486,-76],"parameters":{"color":5,"width":1140,"height":796,"content":"## 3. Format, Save & Notify"},"typeVersion":1},{"id":"3d9a733f-dbf2-49d3-a367-bb38d1f7e443","name":"Receive WhatsApp Messages","type":"n8n-nodes-base.webhook","position":[1088,352],"webhookId":"travel-journal-whatsapp","parameters":{"path":"travel-journal","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"5f5f9590-776a-42e5-8214-b3a9c1cb4990","name":"JS #1: Validate & Aggregate Messages","type":"n8n-nodes-base.code","position":[1312,352],"parameters":{"mode":"runOnceForEachItem","jsCode":"// Extract WhatsApp webhook payload\nconst body = $input.item.json.body || $input.item.json;\n\n// WhatsApp Business API typically sends messages in this format\nconst entry = body.entry?.[0] || {};\nconst changes = entry.changes?.[0] || {};\nconst value = changes.value || {};\nconst messages = value.messages || [body]; // Fallback for direct message format\n\n// Process all messages in the batch\nconst processedMessages = [];\nconst mediaItems = [];\nconst locations = [];\n\nfor (const msg of messages) {\n  const messageData = {\n    messageId: msg.id || `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n    from: msg.from || body.from || 'UNKNOWN_USER',\n    timestamp: msg.timestamp || body.timestamp || Date.now(),\n    type: msg.type || body.type || 'text'\n  };\n\n  // Parse message content based on type\n  if (msg.type === 'text' || body.text) {\n    messageData.text = msg.text?.body || body.text || '';\n    processedMessages.push(messageData);\n  } \n  else if (msg.type === 'image' || body.image) {\n    const image = msg.image || body.image || {};\n    mediaItems.push({\n      ...messageData,\n      mediaType: 'image',\n      mediaId: image.id,\n      caption: image.caption || '',\n      mimeType: image.mime_type || 'image/jpeg',\n      sha256: image.sha256 || null\n    });\n  }\n  else if (msg.type === 'location' || body.location) {\n    const loc = msg.location || body.location || {};\n    locations.push({\n      ...messageData,\n      latitude: loc.latitude,\n      longitude: loc.longitude,\n      name: loc.name || 'Unknown Location',\n      address: loc.address || ''\n    });\n  }\n  else if (msg.type === 'video' || body.video) {\n    const video = msg.video || body.video || {};\n    mediaItems.push({\n      ...messageData,\n      mediaType: 'video',\n      mediaId: video.id,\n      caption: video.caption || '',\n      mimeType: video.mime_type || 'video/mp4'\n    });\n  }\n}\n\n// If this is a simple single message format (not WhatsApp API format)\nif (processedMessages.length === 0 && mediaItems.length === 0 && body.message) {\n  processedMessages.push({\n    messageId: `msg-${Date.now()}`,\n    from: body.phone || body.userId || 'USER',\n    timestamp: Date.now(),\n    type: 'text',\n    text: body.message\n  });\n}\n\n// Add any photos from direct uploads\nif (body.photos && Array.isArray(body.photos)) {\n  body.photos.forEach((photo, idx) => {\n    mediaItems.push({\n      messageId: `photo-${Date.now()}-${idx}`,\n      from: body.phone || body.userId || 'USER',\n      timestamp: Date.now(),\n      type: 'image',\n      mediaType: 'image',\n      mediaUrl: photo.url || photo,\n      caption: photo.caption || ''\n    });\n  });\n}\n\n// Add location if provided directly\nif (body.location) {\n  locations.push({\n    messageId: `loc-${Date.now()}`,\n    from: body.phone || body.userId || 'USER',\n    timestamp: Date.now(),\n    type: 'location',\n    latitude: body.location.lat || body.location.latitude,\n    longitude: body.location.lng || body.location.longitude,\n    name: body.location.name || 'Current Location',\n    address: body.location.address || ''\n  });\n}\n\n// Determine travel day (group by date in user's timezone)\nconst firstTimestamp = processedMessages[0]?.timestamp || mediaItems[0]?.timestamp || Date.now();\nconst messageDate = new Date(parseInt(firstTimestamp) * 1000 || firstTimestamp);\nconst travelDay = messageDate.toISOString().split('T')[0]; // YYYY-MM-DD\n\n// Extract user identifier\nconst userId = body.userId || processedMessages[0]?.from || 'DEFAULT_USER';\nconst tripId = body.tripId || `TRIP-${travelDay}`;\n\n// Build aggregated journal entry\nconst journalEntry = {\n  // Identifiers\n  entryId: `ENTRY-${Date.now()}-${Math.random().toString(36).substr(2, 9).toUpperCase()}`,\n  userId: userId,\n  tripId: tripId,\n  travelDay: travelDay,\n  \n  // Content\n  messages: processedMessages.sort((a, b) => a.timestamp - b.timestamp),\n  media: mediaItems.sort((a, b) => a.timestamp - b.timestamp),\n  locations: locations,\n  \n  // Metadata\n  totalMessages: processedMessages.length,\n  totalMedia: mediaItems.length,\n  totalLocations: locations.length,\n  dayStartTime: messageDate.toISOString(),\n  \n  // Context\n  timezone: body.timezone || 'UTC',\n  destination: body.destination || locations[0]?.name || 'Unknown',\n  tripName: body.tripName || `Journey to ${locations[0]?.name || 'Unknown'}`,\n  \n  // Processing\n  receivedAt: new Date().toISOString(),\n  status: 'VALIDATED'\n};\n\n// Validation\nif (journalEntry.totalMessages === 0 && journalEntry.totalMedia === 0) {\n  throw new Error('No valid messages or media found in WhatsApp payload');\n}\n\nreturn { json: { journalEntry } };"},"typeVersion":2},{"id":"5fce61fc-9b04-4c9d-b83f-18d81f861f6e","name":"Fetch Previous Journal Entries","type":"n8n-nodes-base.googleDrive","position":[1568,352],"parameters":{"operation":"search"},"credentials":{"googleDriveOAuth2Api":{"id":"credential-id","name":"Google Drive account - test"}},"typeVersion":3,"continueOnFail":true},{"id":"3fbf7371-d632-47e0-b116-17c4b257fb18","name":"JS #2: Prepare AI Context","type":"n8n-nodes-base.code","position":[1760,352],"parameters":{"jsCode":"// Get journal entry from validation step\nconst journalEntry = $('JS #1: Validate & Aggregate Messages').item.json.journalEntry;\n\n// Get previous journal data (if exists)\nconst previousJournals = $('Fetch Previous Journal Entries').all().map(i => i.json);\nconst hasPreviousEntries = previousJournals.length > 0;\n\n// Build chronological timeline of the day\nconst timeline = [];\n\n// Add all messages\njournalEntry.messages.forEach(msg => {\n  const time = new Date(parseInt(msg.timestamp) * 1000 || msg.timestamp);\n  timeline.push({\n    time: time.toISOString(),\n    timeFormatted: time.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }),\n    type: 'message',\n    content: msg.text\n  });\n});\n\n// Add all media with captions\njournalEntry.media.forEach(media => {\n  const time = new Date(parseInt(media.timestamp) * 1000 || media.timestamp);\n  timeline.push({\n    time: time.toISOString(),\n    timeFormatted: time.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }),\n    type: media.mediaType,\n    content: media.caption || `[${media.mediaType} - ${media.mediaId || 'uploaded'}]`,\n    mediaId: media.mediaId,\n    mediaUrl: media.mediaUrl || null\n  });\n});\n\n// Add all locations\njournalEntry.locations.forEach(loc => {\n  const time = new Date(parseInt(loc.timestamp) * 1000 || loc.timestamp);\n  timeline.push({\n    time: time.toISOString(),\n    timeFormatted: time.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }),\n    type: 'location',\n    content: `📍 ${loc.name}${loc.address ? ' - ' + loc.address : ''}`,\n    coordinates: `${loc.latitude}, ${loc.longitude}`\n  });\n});\n\n// Sort timeline chronologically\ntimeline.sort((a, b) => new Date(a.time) - new Date(b.time));\n\n// Build formatted timeline text for AI\nconst timelineText = timeline.map(item => \n  `${item.timeFormatted} - ${item.content}`\n).join('\\n');\n\n// Extract locations for context\nconst visitedLocations = journalEntry.locations.map(l => l.name).filter(Boolean);\nconst primaryLocation = visitedLocations[0] || journalEntry.destination;\n\n// Count media for AI awareness\nconst photoCount = journalEntry.media.filter(m => m.mediaType === 'image').length;\nconst videoCount = journalEntry.media.filter(m => m.mediaType === 'video').length;\n\n// Build context object for AI\nconst aiContext = {\n  journalEntry,\n  timeline,\n  timelineText,\n  primaryLocation,\n  visitedLocations,\n  photoCount,\n  videoCount,\n  hasPreviousEntries,\n  previousJournalCount: previousJournals.length,\n  previousJournalLink: previousJournals[0]?.webViewLink || null,\n  \n  // Metadata for AI\n  travelDayFormatted: new Date(journalEntry.travelDay).toLocaleDateString('en-US', {\n    weekday: 'long',\n    year: 'numeric',\n    month: 'long',\n    day: 'numeric'\n  }),\n  \n  // Instructions for AI\n  storyPrompt: {\n    tripName: journalEntry.tripName,\n    dayNumber: hasPreviousEntries ? previousJournals.length + 1 : 1,\n    destination: primaryLocation,\n    messageCount: journalEntry.totalMessages,\n    hasPhotos: photoCount > 0,\n    hasVideos: videoCount > 0,\n    hasLocations: journalEntry.totalLocations > 0\n  }\n};\n\nreturn [{ json: aiContext }];"},"typeVersion":2},{"id":"4c81e688-874c-4d19-abcb-c8a479c0e6ab","name":"Claude AI Story Generator","type":"@n8n/n8n-nodes-langchain.agent","position":[1984,352],"parameters":{"text":"=You are a creative travel writer who transforms everyday travel messages into engaging, narrative-style journal entries. Your writing is vivid, personal, and captures both experiences and emotions.\n\nTransform these WhatsApp messages from a day of travel into a beautifully written travel journal entry.\n\n**Trip Context:**\n- Trip Name: {{ $json.storyPrompt.tripName }}\n- Day Number: Day {{ $json.storyPrompt.dayNumber }}\n- Date: {{ $json.travelDayFormatted }}\n- Primary Destination: {{ $json.storyPrompt.destination }}\n- Has Previous Entries: {{ $json.hasPreviousEntries ? 'Yes' : 'No (this is the first day)' }}\n\n**Today's Activity Timeline:**\n```\n{{ $json.timelineText }}\n```\n\n**Content Available:**\n- Messages: {{ $json.storyPrompt.messageCount }}\n- Photos: {{ $json.photoCount }}\n- Videos: {{ $json.videoCount }}\n- Locations: {{ $json.visitedLocations.join(', ') || 'None recorded' }}\n\n**Writing Guidelines:**\n1. Create a cohesive narrative from the chronological messages\n2. Use vivid, sensory descriptions (sights, sounds, tastes, smells)\n3. Maintain first-person perspective and personal voice\n4. Integrate the timeline naturally — don't just list events\n5. Add emotional insights and reflections between factual descriptions\n6. Reference photos/videos where mentioned (e.g., \"As captured in the photo...\")\n7. Include specific locations and times when relevant to the story\n8. Create a story arc with a beginning, middle, and end for the day\n9. Write 300-600 words — detailed but not exhaustive\n10. End with a reflection or anticipation for tomorrow\n\n**Tone:** Personal, reflective, vivid, engaging — like a friend sharing their adventure\n\n**Response Format (JSON only, no markdown):**\n{\n  \"title\": \"Day X: [Engaging Title]\",\n  \"story\": \"[Full narrative text with paragraphs separated by \\\\n\\\\n]\",\n  \"highlights\": [\"Key moment 1\", \"Key moment 2\", \"Key moment 3\"],\n  \"locations\": [\"Location 1\", \"Location 2\"],\n  \"mood\": \"adventurous/relaxed/excited/contemplative/etc\",\n  \"tags\": [\"food\", \"culture\", \"nature\", \"etc\"],\n  \"photoMoments\": [\"Brief caption for each photo based on timeline\"],\n  \"tomorrowAnticipation\": \"Brief note about what's planned or hoped for next\",\n  \"wordCount\": 450\n}","options":{"systemMessage":"You are a skilled travel writer. Respond with valid JSON only — no markdown, no code blocks, no preamble. Your narratives should be vivid, personal, and emotionally resonant."},"promptType":"define"},"typeVersion":1.6},{"id":"1a9add1e-cb82-4b05-a795-104c5757c458","name":"Claude Sonnet 4 Model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[2056,576],"parameters":{"model":"=claude-sonnet-4-20250514","options":{"temperature":0.7}},"credentials":{"anthropicApi":{"id":"credential-id","name":"Anthropic account - test"}},"typeVersion":1},{"id":"211af710-b124-4441-90a1-f962bf4b925a","name":"Parse AI Story Response","type":"n8n-nodes-base.code","position":[2288,352],"parameters":{"mode":"runOnceForEachItem","jsCode":"const aiResponse = $input.item.json;\nlet aiText = aiResponse.response || aiResponse.output || aiResponse.text || '';\n\n// Handle Anthropic content array format\nif (aiResponse.content && Array.isArray(aiResponse.content)) {\n  aiText = aiResponse.content[0]?.text || '';\n}\n\n// Strip markdown code blocks\nconst cleanText = aiText\n  .replace(/```json\\s*/g, '')\n  .replace(/```\\s*/g, '')\n  .trim();\n\nlet story;\ntry {\n  story = JSON.parse(cleanText);\n} catch (error) {\n  throw new Error(`Failed to parse Claude story response: ${error.message}. Raw: ${cleanText.substring(0, 200)}`);\n}\n\n// Get context from previous steps\nconst aiContext = $('JS #2: Prepare AI Context').item.json;\nconst journalEntry = aiContext.journalEntry;\n\n// Build complete journal record\nconst journalRecord = {\n  // Story content\n  title: story.title,\n  story: story.story,\n  highlights: story.highlights || [],\n  locations: story.locations || aiContext.visitedLocations,\n  mood: story.mood || 'reflective',\n  tags: story.tags || [],\n  photoMoments: story.photoMoments || [],\n  tomorrowAnticipation: story.tomorrowAnticipation || '',\n  wordCount: story.wordCount || 0,\n  \n  // Original data\n  entryId: journalEntry.entryId,\n  tripId: journalEntry.tripId,\n  travelDay: journalEntry.travelDay,\n  dayNumber: aiContext.storyPrompt.dayNumber,\n  \n  // Metadata\n  messageCount: journalEntry.totalMessages,\n  photoCount: aiContext.photoCount,\n  videoCount: aiContext.videoCount,\n  locationCount: journalEntry.totalLocations,\n  \n  // Timeline\n  timeline: aiContext.timeline,\n  \n  // Processing info\n  generatedAt: new Date().toISOString(),\n  aiModel: 'claude-sonnet-4-20250514',\n  status: 'GENERATED'\n};\n\nreturn { json: { journalRecord, rawStory: story } };"},"typeVersion":2},{"id":"e7eac15d-657f-4b97-bb41-c74578ab0d72","name":"JS #3: Format Document","type":"n8n-nodes-base.code","position":[2560,352],"parameters":{"mode":"runOnceForEachItem","jsCode":"const record = $input.item.json.journalRecord;\n\n// Format story with proper paragraphs and spacing\nconst formattedStory = record.story.replace(/\\\\n\\\\n/g, '\\n\\n').trim();\n\n// Build complete document content\nconst documentContent = `${record.title}\n${'='.repeat(record.title.length)}\n\nDate: ${new Date(record.travelDay).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}\nDay ${record.dayNumber} of ${record.tripId}\nMood: ${record.mood}\nLocations: ${record.locations.join(', ')}\n\n${'-'.repeat(80)}\n\n${formattedStory}\n\n${'-'.repeat(80)}\n\n📌 HIGHLIGHTS OF THE DAY\n${record.highlights.map((h, i) => `${i + 1}. ${h}`).join('\\n')}\n\n📸 PHOTO MOMENTS (${record.photoCount} photos)\n${record.photoMoments.map((p, i) => `${i + 1}. ${p}`).join('\\n')}\n\n📍 LOCATIONS VISITED\n${record.locations.map((l, i) => `${i + 1}. ${l}`).join('\\n')}\n\n🏷️ TAGS\n${record.tags.join(', ')}\n\n💭 TOMORROW\n${record.tomorrowAnticipation || 'To be continued...'}\n\n${'-'.repeat(80)}\n\nJournal Entry ID: ${record.entryId}\nGenerated: ${new Date(record.generatedAt).toLocaleString()}\nAI Model: ${record.aiModel}\nWord Count: ${record.wordCount} words\nMessages Processed: ${record.messageCount}\nMedia Included: ${record.photoCount} photos, ${record.videoCount} videos\nLocations Tracked: ${record.locationCount}\n`;\n\n// Prepare for Google Drive\nconst fileName = `${record.tripId}_Day_${record.dayNumber}_${record.travelDay}.txt`;\nconst fileTitle = `${record.title} - ${record.travelDay}`;\n\nreturn {\n  json: {\n    journalRecord: record,\n    documentContent,\n    fileName,\n    fileTitle,\n    \n    // Preview for notification\n    preview: `${record.title}\\n\\n${formattedStory.substring(0, 200)}...`,\n    \n    // Stats summary\n    summary: {\n      title: record.title,\n      dayNumber: record.dayNumber,\n      date: record.travelDay,\n      wordCount: record.wordCount,\n      highlights: record.highlights.length,\n      locations: record.locations.length,\n      photos: record.photoCount\n    }\n  }\n};"},"typeVersion":2},{"id":"0723988f-508f-41fa-a632-c97a6bcc66d7","name":"Wait for Processing","type":"n8n-nodes-base.wait","position":[2784,352],"webhookId":"journal-wait","parameters":{"amount":2},"typeVersion":1.1},{"id":"2974d479-377b-4402-9512-a80cb8762b4f","name":"Create/Update Google Doc","type":"n8n-nodes-base.googleDrive","position":[3008,160],"parameters":{"name":"={{ $json.fileName }}","driveId":{"__rl":true,"mode":"id","value":"=bghy65432f"},"options":{"keepRevisionForever":true},"folderId":{"__rl":true,"mode":"list","value":"YOUR_TRAVEL_JOURNAL_FOLDER_ID"}},"credentials":{"googleDriveOAuth2Api":{"id":"credential-id","name":"Google Drive account - test"}},"typeVersion":3},{"id":"5cdce004-9f6c-42b7-a99f-fd43f6651b17","name":"Send WhatsApp Confirmation","type":"n8n-nodes-base.httpRequest","position":[3008,352],"parameters":{"url":"https://graph.facebook.com/v18.0/YOUR_PHONE_NUMBER_ID/messages","method":"POST","options":{},"sendBody":true,"sendHeaders":true,"authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"messaging_product","value":"whatsapp"},{"name":"to","value":"={{ $('JS #1: Validate & Aggregate Messages').item.json.journalEntry.userId }}"},{"name":"type","value":"text"},{"name":"text","value":"={{ JSON.stringify({ body: '✨ Your travel journal entry is ready!\\n\\n' + $json.summary.title + '\\n\\nWord count: ' + $json.summary.wordCount + ' words\\nHighlights: ' + $json.summary.highlights + '\\nLocations: ' + $json.summary.locations.length + '\\n\\nView in Drive: [Link will be in next update]' }) }}"}]},"headerParameters":{"parameters":[{"name":"Content-Type","value":"application/json"}]},"nodeCredentialType":"whatsAppApi"},"credentials":{"whatsAppApi":{"id":"credential-id","name":"WhatsApp-test "}},"typeVersion":4.2,"continueOnFail":true},{"id":"9eeb0e6c-4d15-444e-86c9-80cba3975ea1","name":"Send Email with Journal Link","type":"n8n-nodes-base.emailSend","position":[3008,544],"webhookId":"journal-email","parameters":{"options":{},"subject":"=✈️ {{ $json.summary.title }} - Your Travel Journal is Ready!","toEmail":"user@example.com","fromEmail":"user@example.com"},"credentials":{"smtp":{"id":"credential-id","name":"SMTP -test"}},"typeVersion":2.1,"continueOnFail":true},{"id":"5ae1b9f1-fac1-4e0d-8f89-299c0fe8a95d","name":"Build Success Response","type":"n8n-nodes-base.code","position":[3232,352],"parameters":{"mode":"runOnceForEachItem","jsCode":"const formatted = $('JS #3: Format Document').item.json;\nconst driveDoc = $('Create/Update Google Doc').item.json;\n\nreturn {\n  json: {\n    success: true,\n    message: 'Travel journal entry generated and saved successfully!',\n    journalEntry: {\n      id: formatted.journalRecord.entryId,\n      title: formatted.summary.title,\n      dayNumber: formatted.summary.dayNumber,\n      date: formatted.summary.date,\n      wordCount: formatted.summary.wordCount\n    },\n    document: {\n      name: formatted.fileName,\n      id: driveDoc.id || 'processing',\n      link: driveDoc.webViewLink || 'will be available shortly'\n    },\n    stats: formatted.summary,\n    processedAt: new Date().toISOString()\n  }\n};"},"typeVersion":2},{"id":"01ea1025-7af2-42a1-87b9-54171740e327","name":"Send Response to Webhook","type":"n8n-nodes-base.respondToWebhook","position":[3456,352],"parameters":{"options":{"responseHeaders":{"entries":[{"name":"Content-Type","value":"application/json"}]}},"respondWith":"json","responseBody":"={{ JSON.stringify($json, null, 2) }}"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"849c44c3-5cd2-445c-bc69-8f0444bdc186","connections":{"Wait for Processing":{"main":[[{"node":"Create/Update Google Doc","type":"main","index":0},{"node":"Send WhatsApp Confirmation","type":"main","index":0},{"node":"Send Email with Journal Link","type":"main","index":0}]]},"Claude Sonnet 4 Model":{"ai_languageModel":[[{"node":"Claude AI Story Generator","type":"ai_languageModel","index":0}]]},"Build Success Response":{"main":[[{"node":"Send Response to Webhook","type":"main","index":0}]]},"JS #3: Format Document":{"main":[[{"node":"Wait for Processing","type":"main","index":0}]]},"Parse AI Story Response":{"main":[[{"node":"JS #3: Format Document","type":"main","index":0}]]},"Create/Update Google Doc":{"main":[[{"node":"Build Success Response","type":"main","index":0}]]},"Claude AI Story Generator":{"main":[[{"node":"Parse AI Story Response","type":"main","index":0}]]},"JS #2: Prepare AI Context":{"main":[[{"node":"Claude AI Story Generator","type":"main","index":0}]]},"Receive WhatsApp Messages":{"main":[[{"node":"JS #1: Validate & Aggregate Messages","type":"main","index":0}]]},"Send WhatsApp Confirmation":{"main":[[{"node":"Build Success Response","type":"main","index":0}]]},"Send Email with Journal Link":{"main":[[{"node":"Build Success Response","type":"main","index":0}]]},"Fetch Previous Journal Entries":{"main":[[{"node":"JS #2: Prepare AI Context","type":"main","index":0}]]},"JS #1: Validate & Aggregate Messages":{"main":[[{"node":"Fetch Previous Journal Entries","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":18,"nodeTypes":{"n8n-nodes-base.code":{"count":5},"n8n-nodes-base.wait":{"count":1},"n8n-nodes-base.webhook":{"count":1},"n8n-nodes-base.emailSend":{"count":1},"n8n-nodes-base.stickyNote":{"count":4},"n8n-nodes-base.googleDrive":{"count":2},"n8n-nodes-base.httpRequest":{"count":1},"@n8n/n8n-nodes-langchain.agent":{"count":1},"n8n-nodes-base.respondToWebhook":{"count":1},"@n8n/n8n-nodes-langchain.lmChatAnthropic":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"Oneclick AI Squad","username":"oneclick-ai","bio":"The AI Squad Initiative is a pioneering effort to build, automate and scale AI-powered workflows using n8n.io. Our mission is to help individuals and businesses integrate AI agents seamlessly into their daily operations  from automating tasks and enhancing productivity to creating innovative, intelligent solutions. We design modular, reusable AI workflow templates that empower creators, developers and teams to supercharge their automation with minimal effort and maximum impact.","verified":true,"links":["https://www.oneclickitsolution.com/"],"avatar":"https://gravatar.com/avatar/848fca91367142f65f9e5c55d64e5c9952b160d7b060d103b52aa343c6bc7b3d?r=pg&d=retro&size=200"},"nodes":[{"id":11,"icon":"fa:envelope","name":"n8n-nodes-base.emailSend","codex":{"data":{"alias":["SMTP","email","human","form","wait","hitl","approval"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.sendemail/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/sendemail/"}]},"categories":["Communication","HITL","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"HITL":["Human in the Loop"]}}},"group":"[\"output\"]","defaults":{"name":"Send Email","color":"#00bb88"},"iconData":{"icon":"envelope","type":"icon"},"displayName":"Send Email","typeVersion":2,"nodeCategories":[{"id":6,"name":"Communication"},{"id":9,"name":"Core Nodes"},{"id":28,"name":"HITL"}]},{"id":19,"icon":"file:httprequest.svg","name":"n8n-nodes-base.httpRequest","codex":{"data":{"alias":["API","Request","URL","Build","cURL"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/world-poetry-day-workflow/","icon":"📜","label":"Celebrating World Poetry Day with a daily poem in Telegram"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/","icon":"🎨","label":"Automate Designs with Bannerbear and n8n"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/how-to-use-the-http-request-node-the-swiss-army-knife-for-workflow-automation/","icon":"🧰","label":"How to use the HTTP Request Node - The Swiss Army Knife for Workflow Automation"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"},{"url":"https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/","icon":"🤟","label":"Creating scheduled text affirmations with n8n"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"output\"]","defaults":{"name":"HTTP Request","color":"#0004F5"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MCAyMEM0MCA4Ljk1MzE0IDMxLjA0NjkgMCAyMCAwQzguOTUzMTQgMCAwIDguOTUzMTQgMCAyMEMwIDMxLjA0NjkgOC45NTMxNCA0MCAyMCA0MEMzMS4wNDY5IDQwIDQwIDMxLjA0NjkgNDAgMjBaTTIwIDM2Ljk0NThDMTguODg1MiAzNi45NDU4IDE3LjEzNzggMzUuOTY3IDE1LjQ5OTggMzIuNjk4NUMxNC43OTY0IDMxLjI5MTggMTQuMTk2MSAyOS41NDMxIDEzLjc1MjYgMjcuNjg0N0gyNi4xODk4QzI1LjgwNDUgMjkuNTQwMyAyNS4yMDQ0IDMxLjI5MDEgMjQuNTAwMiAzMi42OTg1QzIyLjg2MjIgMzUuOTY3IDIxLjExNDggMzYuOTQ1OCAyMCAzNi45NDU4Wk0xMi45MDY0IDIwQzEyLjkwNjQgMjEuNjA5NyAxMy4wMDg3IDIzLjE2NCAxMy4yMDAzIDI0LjYzMDVIMjYuNzk5N0MyNi45OTEzIDIzLjE2NCAyNy4wOTM2IDIxLjYwOTcgMjcuMDkzNiAyMEMyNy4wOTM2IDE4LjM5MDMgMjYuOTkxMyAxNi44MzYgMjYuNzk5NyAxNS4zNjk1SDEzLjIwMDNDMTMuMDA4NyAxNi44MzYgMTIuOTA2NCAxOC4zOTAzIDEyLjkwNjQgMjBaTTIwIDMuMDU0MTlDMjEuMTE0OSAzLjA1NDE5IDIyLjg2MjIgNC4wMzA3OCAyNC41MDAxIDcuMzAwMzlDMjUuMjA2NiA4LjcxNDA4IDI1LjgwNzIgMTAuNDA2NyAyNi4xOTIgMTIuMzE1M0gxMy43NTAxQzE0LjE5MzMgMTAuNDA0NyAxNC43OTQyIDguNzEyNTQgMTUuNDk5OCA3LjMwMDY0QzE3LjEzNzcgNC4wMzA4MyAxOC44ODUxIDMuMDU0MTkgMjAgMy4wNTQxOVpNMzAuMTQ3OCAyMEMzMC4xNDc4IDE4LjQwOTkgMzAuMDU0MyAxNi44NjE3IDI5LjgyMjcgMTUuMzY5NUgzNi4zMDQyQzM2LjcyNTIgMTYuODQyIDM2Ljk0NTggMTguMzk2NCAzNi45NDU4IDIwQzM2Ljk0NTggMjEuNjAzNiAzNi43MjUyIDIzLjE1OCAzNi4zMDQyIDI0LjYzMDVIMjkuODIyN0MzMC4wNTQzIDIzLjEzODMgMzAuMTQ3OCAyMS41OTAxIDMwLjE0NzggMjBaTTI2LjI3NjcgNC4yNTUxMkMyNy42MzY1IDYuMzYwMTkgMjguNzExIDkuMTMyIDI5LjM3NzQgMTIuMzE1M0gzNS4xMDQ2QzMzLjI1MTEgOC42NjggMzAuMTA3IDUuNzgzNDYgMjYuMjc2NyA0LjI1NTEyWk0xMC42MjI2IDEyLjMxNTNINC44OTI5M0M2Ljc1MTQ3IDguNjY3ODQgOS44OTM1MSA1Ljc4MzQxIDEzLjcyMzIgNC4yNTUxM0MxMi4zNjM1IDYuMzYwMjEgMTEuMjg5IDkuMTMyMDEgMTAuNjIyNiAxMi4zMTUzWk0zLjA1NDE5IDIwQzMuMDU0MTkgMjEuNjAzIDMuMjc3NDMgMjMuMTU3NSAzLjY5NDg0IDI0LjYzMDVIMTAuMTIxN0M5Ljk0NjE5IDIzLjE0MiA5Ljg1MjIyIDIxLjU5NDMgOS44NTIyMiAyMEM5Ljg1MjIyIDE4LjQwNTcgOS45NDYxOSAxNi44NTggMTAuMTIxNyAxNS4zNjk1SDMuNjk0ODRDMy4yNzc0MyAxNi44NDI1IDMuMDU0MTkgMTguMzk3IDMuMDU0MTkgMjBaTTI2LjI3NjYgMzUuNzQyN0MyNy42MzY1IDMzLjYzOTMgMjguNzExIDMwLjg2OCAyOS4zNzc0IDI3LjY4NDdIMzUuMTA0NkMzMy4yNTEgMzEuMzMyMiAzMC4xMDY4IDM0LjIxNzkgMjYuMjc2NiAzNS43NDI3Wk0xMy43MjM0IDM1Ljc0MjdDOS44OTM2OSAzNC4yMTc5IDYuNzUxNTUgMzEuMzMyNCA0Ljg5MjkzIDI3LjY4NDdIMTAuNjIyNkMxMS4yODkgMzAuODY4IDEyLjM2MzUgMzMuNjM5MyAxMy43MjM0IDM1Ljc0MjdaIiBmaWxsPSIjM0E0MkU5Ii8+Cjwvc3ZnPgo="},"displayName":"HTTP Request","typeVersion":4,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":47,"icon":"file:webhook.svg","name":"n8n-nodes-base.webhook","codex":{"data":{"alias":["HTTP","API","Build","WH"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/","label":"How to automate every step of an incident response workflow"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"trigger\"]","defaults":{"name":"Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Webhook","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":58,"icon":"file:googleDrive.svg","name":"n8n-nodes-base.googleDrive","codex":{"data":{"resources":{"generic":[{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Data & Storage"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\"]","defaults":{"name":"Google Drive"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgODEgNzMiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9Ii41IiB5PSIuNSIvPjxzeW1ib2wgaWQ9ImEiIG92ZXJmbG93PSJ2aXNpYmxlIj48ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0ibm9uZSI+PHBhdGggZmlsbD0iIzAwNjZkYSIgZD0ibTYuMDQ4IDYxLjI2IDMuNTI4IDYuMDk0Yy43MzMgMS4yODMgMS43ODcgMi4yOTEgMy4wMjQgMy4wMjRsMTIuNi0yMS44MUgwYTguMyA4LjMgMCAwIDAgMS4xIDQuMTI0eiIvPjxwYXRoIGZpbGw9IiMwMGFjNDciIGQ9Ik00MCAyMi45MSAyNy40IDEuMWMtMS4yMzcuNzMzLTIuMjkxIDEuNzQxLTMuMDI0IDMuMDI0TDEuMSA0NC40NDVBOC4zIDguMyAwIDAgMCAwIDQ4LjU2OGgyNS4yeiIvPjxwYXRoIGZpbGw9IiNlYTQzMzUiIGQ9Ik02Ny40IDcwLjM3OGMxLjIzNy0uNzMzIDIuMjkxLTEuNzQxIDMuMDI0LTMuMDI0bDEuNDY2LTIuNTIgNy4wMS0xMi4xNDJhOC4zIDguMyAwIDAgMCAxLjEtNC4xMjRINTQuNzk4bDUuMzYzIDEwLjUzOHoiLz48cGF0aCBmaWxsPSIjMDA4MzJkIiBkPSJNNDAgMjIuOTEgNTIuNiAxLjFDNTEuMzYzLjM2NyA0OS45NDMgMCA0OC40NzcgMEgzMS41MjRjLTEuNDY2IDAtMi44ODcuNDEyLTQuMTI0IDEuMXoiLz48cGF0aCBmaWxsPSIjMjY4NGZjIiBkPSJNNTQuNzk5IDQ4LjU2OEgyNS4ybC0xMi42IDIxLjgxYzEuMjM3LjczMyAyLjY1NyAxLjEgNC4xMjQgMS4xaDQ2LjU1MmMxLjQ2NiAwIDIuODg3LS40MTIgNC4xMjQtMS4xeiIvPjxwYXRoIGZpbGw9IiNmZmJhMDAiIGQ9Ik02Ny4yNjIgMjQuMjg0IDU1LjYyNCA0LjEyNEM1NC44OTEgMi44NDEgNTMuODM3IDEuODMzIDUyLjYgMS4xTDQwIDIyLjkxbDE0LjggMjUuNjU5aDI1LjE1NWE4LjMgOC4zIDAgMCAwLTEuMS00LjEyNHoiLz48L2c+PC9zeW1ib2w+PC9zdmc+"},"displayName":"Google Drive","typeVersion":3,"nodeCategories":[{"id":3,"name":"Data & Storage"}]},{"id":514,"icon":"fa:pause-circle","name":"n8n-nodes-base.wait","codex":{"data":{"alias":["pause","sleep","delay","timeout"],"resources":{"generic":[{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Flow"]}}},"group":"[\"organization\"]","defaults":{"name":"Wait","color":"#804050"},"iconData":{"icon":"pause-circle","type":"icon"},"displayName":"Wait","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":535,"icon":"file:webhook.svg","name":"n8n-nodes-base.respondToWebhook","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/"}]},"categories":["Core Nodes","Utility"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"transform\"]","defaults":{"name":"Respond to Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Respond to Webhook","typeVersion":2,"nodeCategories":[{"id":7,"name":"Utility"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":1119,"icon":"fa:robot","name":"@n8n/n8n-nodes-langchain.agent","codex":{"data":{"alias":["LangChain","Chat","Conversational","Plan and Execute","ReAct","Tools"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Agents","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"AI Agent","color":"#404040"},"iconData":{"icon":"robot","type":"icon"},"displayName":"AI Agent","typeVersion":3,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1145,"icon":"file:anthropic.svg","name":"@n8n/n8n-nodes-langchain.lmChatAnthropic","codex":{"data":{"alias":["claude","sonnet","opus"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatanthropic/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"Anthropic Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzdEN0Q4NyIgZD0iTTMyLjczIDBoLTYuOTQ1TDM4LjQ1IDMyaDYuOTQ1ek0xMi42NjUgMCAwIDMyaDcuMDgybDIuNTktNi43MmgxMy4yNWwyLjU5IDYuNzJoNy4wODJMMTkuOTI5IDB6bS0uNzAyIDE5LjMzNyA0LjMzNC0xMS4yNDYgNC4zMzQgMTEuMjQ2eiIvPjwvc3ZnPg=="},"displayName":"Anthropic Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":31,"name":"Content Creation"},{"id":51,"name":"Multimodal AI"}],"image":[]}}