N
n8n Store
Workflow Market
Transform Event Notes to LinkedIn-ready Post

Transform Event Notes to LinkedIn-ready Post

by xyzhang0 views

説明

Categories

🤖 AI & Machine Learning

Nodes Used

n8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.mergen8n-nodes-base.mergen8n-nodes-base.supabasen8n-nodes-base.telegramn8n-nodes-base.stickyNoten8n-nodes-base.stickyNote
Price無料
Views0
最終更新11/28/2025
workflow.json
{
  "id": "yLOJtzWgLAn6ALXD",
  "meta": {
    "instanceId": "91e9d2c12dbfcdc2cb30d3665a714f8a4ee901c9fd6527015006b21570a93b53",
    "templateCredsSetupCompleted": true
  },
  "name": "Transform Event Notes to LinkedIn-ready Post",
  "tags": [],
  "nodes": [
    {
      "id": "18ddd825-6107-4a79-bde6-a428c630513f",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        820,
        -160
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-opus-4-20250514",
          "cachedResultName": "Claude Opus 4"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "id": "EMBM016jYvf2Fzc3",
          "name": "Anthropic account 2"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9fb73872-e932-4598-b663-d5806fedd120",
      "name": "Format the message",
      "type": "n8n-nodes-base.code",
      "position": [
        -440,
        -80
      ],
      "parameters": {
        "jsCode": "// Simplified message parsing\nconst message = $input.first().json?.message?.text;\n\nif (!message) {\n  return { event_name: '', notes: 'No message received' };\n}\n\nconst colonIndex = message.indexOf(':');\nif (colonIndex === -1) {\n  return { event_name: '', notes: message.trim() };\n}\n\nreturn {\n  event_name: message.substring(0, colonIndex).trim(),\n  notes: message.substring(colonIndex + 1).trim()\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "06b083f5-4df0-4463-a587-d70a5bfc9914",
      "name": "Telegram Trigger: receive a message",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -700,
        -80
      ],
      "webhookId": "89da3802-d59f-442a-b94e-a503d137901a",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "uwQBbjwjNC7ybVU7",
          "name": "Telegram account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "73a84589-6a39-40f8-85cc-8288190e1b50",
      "name": "Merge the message and events",
      "type": "n8n-nodes-base.merge",
      "position": [
        200,
        -80
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "9b740fee-2e84-41f2-84e5-7d0239cfcbaa",
      "name": "Match the message and event",
      "type": "n8n-nodes-base.code",
      "position": [
        420,
        -80
      ],
      "parameters": {
        "jsCode": "// Improved event matching with fuzzy search\nconst allData = $input.all();\n\n// Get parsed message data\nconst parseData = allData.find(item => \n  item.json?.event_name !== undefined\n)?.json;\n\nif (!parseData) {\n  return { error: \"No parsed message data found\" };\n}\n\n// Get calendar events\nconst calendarEvents = allData.filter(item => \n  item.json?.summary && item.json?.start\n);\n\n// Enhanced matching function\nfunction findBestMatch(searchTerm, events) {\n  const search = searchTerm.toLowerCase();\n  \n  // Exact match first\n  let match = events.find(e => e.json.summary.toLowerCase() === search);\n  if (match) return match.json;\n  \n  // Contains match\n  match = events.find(e => e.json.summary.toLowerCase().includes(search));\n  if (match) return match.json;\n  \n  // Reverse contains (search term contains event name)\n  match = events.find(e => search.includes(e.json.summary.toLowerCase()));\n  if (match) return match.json;\n  \n  // Word-based matching\n  const searchWords = search.split(/\\s+/);\n  match = events.find(e => {\n    const eventTitle = e.json.summary.toLowerCase();\n    return searchWords.some(word => eventTitle.includes(word) && word.length > 2);\n  });\n  \n  return match?.json;\n}\n\nconst matchedEvent = findBestMatch(parseData.event_name, calendarEvents);\n\nif (matchedEvent) {\n  return {\n    event_found: true,\n    event_title: matchedEvent.summary,\n    event_date: matchedEvent.start.dateTime || matchedEvent.start.date,\n    event_timezone: matchedEvent.start.timeZone || 'Europe/Berlin',\n    event_location: matchedEvent.location || 'No location specified',\n    event_description: matchedEvent.description || '',\n    event_attendees: matchedEvent.attendees?.map(a => a.email).join(', ') || 'No attendees listed',\n    personal_notes: parseData.notes,\n    event_id: matchedEvent.id\n  };\n} else {\n  return {\n    event_found: false,\n    event_title: parseData.event_name,\n    event_date: 'Event not found in calendar',\n    event_timezone: 'Unknown',\n    event_location: 'Unknown',\n    event_description: '',\n    event_attendees: '',\n    personal_notes: parseData.notes,\n    event_id: null\n  };\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "d08bea64-f81b-4e17-96ee-a6486165413b",
      "name": "Format the matched event",
      "type": "n8n-nodes-base.code",
      "position": [
        620,
        -80
      ],
      "parameters": {
        "jsCode": "const data = $json;\n\nconst prompt = `Transform this event information and personal notes into an engaging LinkedIn post:\n\nEvent: ${data.event_title}\nDate: ${data.event_date}\nLocation: ${data.event_location}\nMy Personal Notes: ${data.personal_notes}\n\nCreate a professional LinkedIn post that highlights key insights and takeaways from this event. Include relevant hashtags and make it engaging for my professional network.`;\n\n// Return both the prompt and preserve the original data\nreturn {\n  chatInput: prompt,\n  // Preserve all original data\n  event_title: data.event_title,\n  event_date: data.event_date,\n  event_location: data.event_location,\n  personal_notes: data.personal_notes,\n  event_found: data.event_found,\n  event_id: data.event_id\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "39ee8836-51f2-49bc-89e6-252cf66af237",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        820,
        -380
      ],
      "parameters": {
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "You are my personal event notes organizer. Your job is, after I send you the event link and my notes to the event, you extract the event date, location and short introduction, at the same time, tranform my notes to a logical and professional LinkedIn-like post. The tone should be a mix of formal and fun, not too dry. Keep each paragraph short and get to the point. "
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "63365a25-3319-4d87-ad58-df6ed9b737cd",
      "name": "Merge the event info and LinkedIn post",
      "type": "n8n-nodes-base.merge",
      "position": [
        1160,
        -60
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.1
    },
    {
      "id": "84a5db76-6e60-48a0-9059-48f870e9bfc1",
      "name": "Format the event info and LinkedIn post",
      "type": "n8n-nodes-base.code",
      "position": [
        1420,
        -60
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\n\n// Format date helper - fixed to prevent 24:xx hour format\nfunction formatDate(dateString) {\n  if (!dateString || dateString.includes('not found')) return 'Unknown';\n  try {\n    const date = new Date(dateString);\n    const year = date.getFullYear();\n    const month = String(date.getMonth() + 1).padStart(2, '0');\n    const day = String(date.getDate()).padStart(2, '0');\n    const hours = String(date.getHours()).padStart(2, '0');\n    const minutes = String(date.getMinutes()).padStart(2, '0');\n    return `${month}/${day}/${year}, ${hours}:${minutes}`;\n  } catch {\n    return dateString;\n  }\n}\n\n// Clean text helper\nfunction cleanText(text) {\n  return String(text || '')\n    .replace(/\\\\n/g, ' ')\n    .replace(/\\n/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim();\n}\n\n// Get current date with guaranteed correct format\nconst now = new Date();\nconst currentDate = `${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')}/${now.getFullYear()}, ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;\n\n// Return formatted data\nreturn {\n  'Event Date': formatDate(data.event_date),\n  'Event Title': data.event_title || 'Unknown Event',\n  'Location': data.event_location || 'Unknown Location',\n  'Personal Notes': cleanText(data.personal_notes),\n  'LinkedIn Post': cleanText(data.output),\n  'Created Date': currentDate\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "84a63197-aed5-4417-ab29-ea18ff36c53a",
      "name": "Save to Supabase",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1800,
        -60
      ],
      "parameters": {
        "tableId": "Event notes neu",
        "dataToSend": "autoMapInputData"
      },
      "credentials": {
        "supabaseApi": {
          "id": "ot0Q4Due2nUmSxKx",
          "name": "Supabase account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "54c54571-ea30-4735-bf64-d64e13634d01",
      "name": "Send conformation to Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2060,
        -60
      ],
      "webhookId": "bbdbac24-504a-49c3-80d7-4d59fa20996c",
      "parameters": {
        "text": "=✅ Event saved successfully!\n\n[Event]: {{ $json['Event Title'] }}\n\n[Date]: {{ $json['Event Date'] }}\n\nSaved to database at {{ new Date().toLocaleTimeString() }}",
        "chatId": "1276853208",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "uwQBbjwjNC7ybVU7",
          "name": "Telegram account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8a88a2f2-97b0-4408-bb22-6211a6e73f6c",
      "name": "Search for Google Calendar",
      "type": "n8n-nodes-base.googleCalendar",
      "position": [
        -40,
        40
      ],
      "parameters": {
        "options": {},
        "timeMax": "={{ $now }}",
        "timeMin": "={{ $now.minus({ days: 7 }) }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "ae67e70c333e1c1793becc22cd2672cbcb83b90cdcd3a6fb4986c0abfd73500d@group.calendar.google.com",
          "cachedResultName": "Events"
        },
        "operation": "getAll"
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "id": "VLNoBzZLyRLLKXRc",
          "name": "Google Calendar account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3ef55282-1f75-4844-ade8-9f22ee7dde51",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1560,
        -540
      ],
      "parameters": {
        "width": 540,
        "height": 1120,
        "content": "# Transform Your Event Notes to LinkedIn-ready Post \n\nThis workflow transforms your quick event notes into polished LinkedIn posts automatically. Simply send a message via Telegram with your event name and personal notes, and the system will match it with your calendar events, generate a professional LinkedIn post using AI, and save everything to your database for future reference.\n\n## How it works\n\n* Telegram Input: Send a message to your Telegram bot with the format \"Event Name: Your personal notes\"\n* Message Parsing: The system extracts the event name and your personal notes from the message\n* Calendar Matching: Searches your Google Calendar for events from the past 7 days that match the event name\n* Data Enrichment: Combines your personal notes with event details (date, location, attendees) from your calendar\n* AI Content Generation: Uses Claude Opus 4 to transform your notes into a professional LinkedIn post with relevant hashtags\n* Database Storage: Saves the complete event information and generated LinkedIn post to Supabase\n* Ready to Post: Provides you with a polished LinkedIn post ready for publication\n\n\n## Good to know\n\nThis workflow helps you build your build a personal library of your professional networking activities and insights. All your event experiences are saved in Supabase for future reference.\n\n\n## Requirements\n\n* n8n (Cloud or self-hosted)\n* Telegram Bot (Create via @BotFather)\n* Google Calendar API (OAuth2 credentials)\n* Anthropic API (Claude access)\n* Supabase (Database and API credentials)\n\n\n## Customizing this workflow\n\n* Modify the system prompt to ajdust to your own writing stlye.\n* Add more columns to fetch more details of the event, like types of events, main speakers etc. "
      },
      "typeVersion": 1
    },
    {
      "id": "0f672fff-1d86-47d7-9882-e1244831f514",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1000,
        -340
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 1. Telegram message trigger\n\nWhen you send a message with the format \"Event Name: Your personal notes\" to your Telegram bot, it will trigger this workflow. "
      },
      "typeVersion": 1
    },
    {
      "id": "2267b9b8-5889-47dd-a2f5-be7769c884f7",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -540,
        -340
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 2. Format your message\n\nThis code extracts the event name and your personal notes from the message."
      },
      "typeVersion": 1
    },
    {
      "id": "d940ee1b-60f0-4286-bef3-282f999dc9eb",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        220
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 3. Get events in the last 7 days\n\nThis code extracts the event name and your personal notes from the message."
      },
      "typeVersion": 1
    },
    {
      "id": "98b8881f-ad50-42a9-ad77-59ed70e66178",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        120,
        -380
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 4. Match events in the calendar\n\nIt searches your Google Calendar for events from the past 7 days that match the event name. "
      },
      "typeVersion": 1
    },
    {
      "id": "bf36470f-035a-4f76-867a-80e7e010e12e",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        500,
        140
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 5. Format the matched event as user prompt for AI agent\n\nIt combines your personal notes with event details (date, location, attendees) from your calendar and works as user prompt for the AI Agent."
      },
      "typeVersion": 1
    },
    {
      "id": "cd0ea09f-2b11-4a67-b958-dd7029aa0752",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -620
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "height": 220,
        "content": "\n\n## 6. Draft LinkedIn post based on the event info and your notes\n\nIt uses Claude Opus 4 to transform your notes into a professional LinkedIn post with relevant hashtags."
      },
      "typeVersion": 1
    },
    {
      "id": "1c3e5097-2a99-4337-ac90-92caf6c929d7",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        160
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "content": "\n\n## 7. Merge and format the LinkedIn post and event info extracted from Google Calendar"
      },
      "typeVersion": 1
    },
    {
      "id": "4821e6b8-3658-42ab-91b3-b15dce464d9e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        -300
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "content": "\n\n## 8. Save the complete event information and generated LinkedIn post to Supabase"
      },
      "typeVersion": 1
    },
    {
      "id": "16407b26-ee48-4ac2-a6ab-e7ba3ff55283",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2300,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 440,
        "content": "\n\n## 9. Send confirmation message to your Telegram\nIt sends you a confirmation message through your Telegram Bot, when it's successfully saved in Supabase. "
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "de763a51-cf19-48ad-af8f-979c56c2e7a2",
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Merge the event info and LinkedIn post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Supabase": {
      "main": [
        [
          {
            "node": "Send conformation to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format the message": {
      "main": [
        [
          {
            "node": "Merge the message and events",
            "type": "main",
            "index": 0
          },
          {
            "node": "Search for Google Calendar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Format the matched event": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge the event info and LinkedIn post",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Search for Google Calendar": {
      "main": [
        [
          {
            "node": "Merge the message and events",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Match the message and event": {
      "main": [
        [
          {
            "node": "Format the matched event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge the message and events": {
      "main": [
        [
          {
            "node": "Match the message and event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger: receive a message": {
      "main": [
        [
          {
            "node": "Format the message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge the event info and LinkedIn post": {
      "main": [
        [
          {
            "node": "Format the event info and LinkedIn post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format the event info and LinkedIn post": {
      "main": [
        [
          {
            "node": "Save to Supabase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

相关工作流