Keep/n8n-tech-news-workflow.json
sepehr f0b41572bc feat: Memento avec dates, Markdown, reminders et auth
Tests Playwright validés :
- Création de notes: OK
- Modification titre: OK
- Modification contenu: OK
- Markdown éditable avec preview: OK

Fonctionnalités:
- date-fns: dates relatives sur cards
- react-markdown + remark-gfm
- Markdown avec toggle edit/preview
- Recherche améliorée (titre/contenu/labels/checkItems)
- Reminder recurrence/location (schema)
- NextAuth.js + User/Account/Session
- userId dans Note (optionnel)
- 4 migrations créées

Ready for production + auth integration
2026-01-04 16:04:24 +01:00

283 lines
10 KiB
JSON
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"name": "Tech News to Memento via MCP",
"nodes": [
{
"parameters": {
"url": "https://feeds.feedburner.com/TechCrunch/",
"options": {}
},
"id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"name": "RSS Feed - Tech News",
"type": "n8n-nodes-base.rssFeedRead",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"jsCode": "// Prepare RSS items for AI analysis\nconst items = $input.all();\n\n// Format articles for AI\nconst articles = items.map((item, index) => ({\n index: index + 1,\n title: item.json.title,\n description: item.json.contentSnippet || item.json.description || '',\n link: item.json.link,\n pubDate: item.json.pubDate,\n categories: item.json.categories || []\n}));\n\n// Create prompt for AI\nconst prompt = `Analysez ces ${articles.length} actualités technologiques et sélectionnez les 2 articles les PLUS PERTINENTS et IMPORTANTS.\n\nCritères de sélection :\n- Innovation majeure ou rupture technologique\n- Impact significatif sur l'industrie tech\n- Actualité récente et d'importance\n- Éviter les articles marketing ou promotionnels\n- Privilégier les annonces concrètes\n\nArticles disponibles :\n${articles.map(a => `\n[${a.index}] ${a.title}\nDescription: ${a.description.substring(0, 300)}...\nCatégories: ${a.categories.join(', ')}\nLien: ${a.link}\n`).join('\\n---\\n')}\n\nRépondez UNIQUEMENT au format JSON suivant (rien d'autre) :\n{\n \"selected\": [\n {\n \"index\": <numéro de l'article>,\n \"reason\": \"<courte raison de la sélection en 1-2 phrases>\"\n },\n {\n \"index\": <numéro de l'article>,\n \"reason\": \"<courte raison de la sélection en 1-2 phrases>\"\n }\n ]\n}`;\n\nreturn [{\n json: {\n prompt,\n articles\n }\n}];"
},
"id": "2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e",
"name": "Prepare AI Analysis",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [450, 300]
},
{
"parameters": {
"model": "gpt-4o-mini",
"options": {
"temperature": 0.3,
"maxTokens": 500
},
"messages": {
"values": [
{
"role": "system",
"content": "Tu es un expert en analyse d'actualités technologiques. Ta mission est de sélectionner les 2 articles les plus pertinents et importants parmi une liste d'actualités. Tu dois être objectif, privilégier l'innovation et l'impact réel. Réponds UNIQUEMENT en JSON valide, sans markdown ni texte supplémentaire."
},
{
"role": "user",
"content": "={{ $json.prompt }}"
}
]
}
},
"id": "3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f",
"name": "OpenAI - Select Best Articles",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.3,
"position": [650, 300],
"credentials": {
"openAiApi": {
"id": "1",
"name": "OpenAI Account"
}
}
},
{
"parameters": {
"jsCode": "// Parse AI response and match with articles\nconst aiResponse = $input.first().json.message?.content || $input.first().json.text;\nconst articles = $('Prepare AI Analysis').first().json.articles;\n\ntry {\n // Extract JSON from response (handles markdown code blocks)\n let jsonStr = aiResponse.trim();\n if (jsonStr.startsWith('```json')) {\n jsonStr = jsonStr.replace(/```json\\n?/g, '').replace(/```\\n?/g, '');\n } else if (jsonStr.startsWith('```')) {\n jsonStr = jsonStr.replace(/```\\n?/g, '');\n }\n \n const selection = JSON.parse(jsonStr);\n \n // Get selected articles\n const selectedArticles = selection.selected.map(sel => {\n const article = articles[sel.index - 1];\n return {\n ...article,\n selectionReason: sel.reason\n };\n });\n \n return selectedArticles.map(article => ({ json: article }));\n \n} catch (error) {\n console.error('Error parsing AI response:', error);\n console.error('AI Response:', aiResponse);\n \n // Fallback: return first 2 articles\n return articles.slice(0, 2).map(article => ({ json: article }));\n}"
},
"id": "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"name": "Parse Selection",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [850, 300]
},
{
"parameters": {
"jsCode": "// Format note for creation\nconst article = $input.first().json;\n\n// Create rich note content\nconst noteContent = `📰 **${article.title}**\n\n🔍 **Pourquoi cet article ?**\n${article.selectionReason}\n\n📝 **Résumé :**\n${article.description}\n\n🔗 **Lien :** ${article.link}\n\n📅 **Publié le :** ${new Date(article.pubDate).toLocaleDateString('fr-FR', { \n year: 'numeric', \n month: 'long', \n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n})}\n\n🏷 **Catégories :** ${article.categories.join(', ') || 'Non spécifié'}`;\n\nreturn [{\n json: {\n title: `📰 ${article.title.substring(0, 60)}${article.title.length > 60 ? '...' : ''}`,\n content: noteContent,\n color: 'blue',\n labels: ['Tech News', 'Auto-Generated', ...article.categories.slice(0, 3)],\n type: 'text'\n }\n}];"
},
"id": "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
"name": "Format Note",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1050, 300]
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:3001/sse",
"authentication": "none",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"jsonrpc\": \"2.0\",\n \"id\": {{ $now.toUnixInteger() }},\n \"method\": \"tools/call\",\n \"params\": {\n \"name\": \"create_note\",\n \"arguments\": {\n \"title\": {{ $json.title | tojson }},\n \"content\": {{ $json.content | tojson }},\n \"color\": {{ $json.color | tojson }},\n \"type\": {{ $json.type | tojson }},\n \"labels\": {{ $json.labels | tojson }}\n }\n }\n}",
"options": {
"timeout": 10000
}
},
"id": "6f7a8b9c-0d1e-2f3a-4b5c-6d7e8f9a0b1c",
"name": "MCP - Create Note",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [1250, 300]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "note_id",
"name": "note_id",
"value": "={{ $json.result?.content?.[0]?.text | fromjson | pick('id').id }}",
"type": "string"
},
{
"id": "note_title",
"name": "note_title",
"value": "={{ $json.result?.content?.[0]?.text | fromjson | pick('title').title }}",
"type": "string"
},
{
"id": "status",
"name": "status",
"value": "={{ $json.result ? 'success' : 'failed' }}",
"type": "string"
}
]
},
"options": {}
},
"id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d",
"name": "Extract Result",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [1450, 300]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e",
"name": "Schedule - Every 6 hours",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [50, 300]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "execution_time",
"name": "execution_time",
"value": "={{ $now.toISO() }}",
"type": "string"
},
{
"id": "notes_created",
"name": "notes_created",
"value": "={{ $('Extract Result').all().length }}",
"type": "number"
},
{
"id": "workflow_status",
"name": "workflow_status",
"value": "✅ Tech news workflow completed successfully",
"type": "string"
}
]
}
},
"id": "9c0d1e2f-3a4b-5c6d-7e8f-9a0b1c2d3e4f",
"name": "Summary",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [1650, 300]
}
],
"connections": {
"Schedule - Every 6 hours": {
"main": [
[
{
"node": "RSS Feed - Tech News",
"type": "main",
"index": 0
}
]
]
},
"RSS Feed - Tech News": {
"main": [
[
{
"node": "Prepare AI Analysis",
"type": "main",
"index": 0
}
]
]
},
"Prepare AI Analysis": {
"main": [
[
{
"node": "OpenAI - Select Best Articles",
"type": "main",
"index": 0
}
]
]
},
"OpenAI - Select Best Articles": {
"main": [
[
{
"node": "Parse Selection",
"type": "main",
"index": 0
}
]
]
},
"Parse Selection": {
"main": [
[
{
"node": "Format Note",
"type": "main",
"index": 0
}
]
]
},
"Format Note": {
"main": [
[
{
"node": "MCP - Create Note",
"type": "main",
"index": 0
}
]
]
},
"MCP - Create Note": {
"main": [
[
{
"node": "Extract Result",
"type": "main",
"index": 0
}
]
]
},
"Extract Result": {
"main": [
[
{
"node": "Summary",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [
{
"createdAt": "2026-01-04T14:00:00.000Z",
"updatedAt": "2026-01-04T14:00:00.000Z",
"id": "tech-automation",
"name": "Tech Automation"
}
],
"triggerCount": 0,
"updatedAt": "2026-01-04T14:00:00.000Z",
"versionId": "1"
}