{
  "name": "Remix 8: Morning podcast",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 7
            }
          ]
        }
      },
      "id": "d3cf60b2-abdc-4a1a-ab87-a0f244791991",
      "name": "Every morning at 7",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -448,
        -512
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "719f0d54-0488-4e76-8cba-bb5f7995e2a5",
              "name": "topics",
              "value": "AI agents, Gemini, n8n",
              "type": "string"
            },
            {
              "id": "f38fa2e0-0400-4d90-8f03-c7e6070f38f7",
              "name": "city",
              "value": "Paderborn",
              "type": "string"
            },
            {
              "id": "9f3683b7-8e56-4b76-9954-dd8153aa9b78",
              "name": "latitude",
              "value": 51.72,
              "type": "number"
            },
            {
              "id": "90c309bb-5bb1-4f8b-ade7-289f3367b804",
              "name": "longitude",
              "value": 8.76,
              "type": "number"
            },
            {
              "id": "a0e765cf-a0c3-43cb-9924-cd63c710cac8",
              "name": "email",
              "value": "you@example.com",
              "type": "string"
            },
            {
              "id": "1821ca09-8c0a-4ed7-ad8e-b7e25661043d",
              "name": "tts_voice",
              "value": "Kore",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "58c7a7a2-8a11-437a-89c4-900c4161a806",
      "name": "My settings",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -224,
        -512
      ]
    },
    {
      "parameters": {
        "url": "=https://api.open-meteo.com/v1/forecast?latitude={{ $('My settings').first().json.latitude }}&longitude={{ $('My settings').first().json.longitude }}&daily=temperature_2m_max,temperature_2m_min,precipitation_probability_max&timezone=auto&forecast_days=1",
        "options": {}
      },
      "id": "8c0b3d88-a71f-46f4-8630-994df1182dbf",
      "name": "Get weather",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        -512
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "e425d589-7c8f-44ec-831a-bf8eafabb7c8",
              "name": "temp_min",
              "value": "={{ $json.daily.temperature_2m_min[0] }}",
              "type": "number"
            },
            {
              "id": "acefaaae-c2da-4701-9519-c0a6d2a1c11f",
              "name": "temp_max",
              "value": "={{ $json.daily.temperature_2m_max[0] }}",
              "type": "number"
            },
            {
              "id": "5e1caa3f-6985-467f-9002-a498bba17eda",
              "name": "rain_chance",
              "value": "={{ $json.daily.precipitation_probability_max[0] }}",
              "type": "number"
            },
            {
              "id": "7efe963e-ab39-4f98-a039-edafe0b64074",
              "name": "summary",
              "value": "={{ $json.daily.temperature_2m_min[0] }} to {{ $json.daily.temperature_2m_max[0] }} °C, {{ $json.daily.precipitation_probability_max[0] }}% chance of rain",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "92375c84-9dd1-4643-b10a-2e9a54feea6b",
      "name": "Format weather",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        224,
        -512
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "0b58d2e0-cb7b-4257-ab3e-ace25cbd69e0",
              "leftValue": "={{ $json.rain_chance }}",
              "rightValue": 50,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cf019f07-6be0-403e-a99d-97238464816f",
      "name": "Rain over 50%?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        432,
        -512
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "7530c764-d124-467a-834d-72fc8cd628fc",
              "name": "umbrella_note",
              "value": "☔ Take an umbrella today.",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "b6e43a29-426a-4c71-ae10-f025535c484d",
      "name": "Umbrella note",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        656,
        -672
      ]
    },
    {
      "parameters": {
        "url": "=https://news.google.com/rss/search?q={{ encodeURIComponent($('My settings').first().json.topics.split(',').map(t => '\"' + t.trim() + '\"').join(' OR ') + ' when:1d') }}&hl=en-US&gl=US&ceid=US:en",
        "options": {}
      },
      "id": "d9a0468b-a3d2-4cd8-ad7f-dd25095bcd56",
      "name": "Google News",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        880,
        -512
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Write my morning brief for today, {{ $now.toFormat('cccc, d LLLL') }}.\n\nWeather in {{ $('My settings').first().json.city }}: {{ $('Format weather').first().json.summary }}\n\nNews on my topics from Google News:\n{{ $('Google News').all().slice(0, 15).map(item => '- ' + item.json.title + ' (' + item.json.link + ')').join('\\n') }}\n\nAlso check the Hacker News front page with your tool and include stories that fit my interests.",
        "options": {
          "systemMessage": "=You are my personal morning briefing assistant.\nMy interests: {{ $('My settings').first().json.topics }}.\n\nWrite a short brief in plain text, no Markdown:\n1. One line on today's weather.\n2. The 3 to 5 most relevant stories for my interests, each with one sentence and its link.\n\nOnly use stories from the news list in the message or from your tools.\nNever use your own knowledge for news. If there are no stories, write only the weather line.\nKeep the brief under 200 words."
        }
      },
      "id": "ec87721a-df92-4b81-9d66-cd05889586e2",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.8,
      "position": [
        1104,
        -512
      ],
      "executeOnce": true
    },
    {
      "parameters": {
        "modelName": "models/gemini-3.5-flash-lite",
        "options": {}
      },
      "id": "7a515adc-f9f7-4855-9e4b-0136d6b5a9ba",
      "name": "Gemini",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        1104,
        -272
      ]
    },
    {
      "parameters": {
        "toolDescription": "Returns the current Hacker News front page stories (title, url, points) as JSON.",
        "url": "https://hn.algolia.com/api/v1/search?tags=front_page&hitsPerPage=10&attributesToRetrieve=title,url,points&attributesToHighlight=%5B%5D",
        "options": {}
      },
      "id": "5cf622b5-0f6c-46ba-8f49-89c1394a2f92",
      "name": "Hacker News",
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.2,
      "position": [
        1248,
        -272
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $('My settings').first().json.email }}",
        "subject": "=Your daily brief, {{ $now.toFormat('ccc d LLL') }}",
        "emailType": "text",
        "message": "={{ $('Umbrella note').isExecuted ? $('Umbrella note').first().json.umbrella_note + '\\n\\n' : '' }}{{ $('AI Agent').first().json.output }}",
        "options": {
          "appendAttribution": false,
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        }
      },
      "id": "bd81a1a0-26aa-45ae-bd83-b56ad551e23a",
      "name": "Send brief",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1920,
        -512
      ],
      "webhookId": "1a5ac51b-cf30-41ec-a116-7b76bd1d479f"
    },
    {
      "parameters": {
        "content": "## 1. Settings and weather\nYour topics, city and email in one place. Then: get the weather, cut the JSON down, check for rain.",
        "height": 628,
        "width": 1296,
        "color": 7
      },
      "id": "2ab5ebde-b150-4982-8678-30f031871456",
      "name": "Stage 1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -512,
        -752
      ]
    },
    {
      "parameters": {
        "content": "## 3. News\nGoogle News (fixed) and Hacker News (a tool the agent can call).",
        "height": 640,
        "width": 200,
        "color": 6
      },
      "id": "31933266-af1b-45a0-9eac-62b983731eb2",
      "name": "Stage 3",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        816,
        -752
      ]
    },
    {
      "parameters": {
        "content": "## 2. The agent\nGemini writes the brief.",
        "height": 640,
        "width": 364,
        "color": 5
      },
      "id": "4763fab4-b7be-4559-90bf-6b5ce12a8ae6",
      "name": "Stage 2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1040,
        -752
      ]
    },
    {
      "parameters": {
        "content": "## 4. Send\nEmail to yourself. Then switch the workflow on.",
        "height": 644,
        "width": 644,
        "color": 4
      },
      "id": "649c17c2-6842-4c68-9ae2-de3f692609e6",
      "name": "Stage 4",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1424,
        -752
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-lite-tts:generateContent",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googlePalmApi",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ contents: [{ parts: [{ text: $json.output.replace(/\\(?https?:\\/\\/\\S+\\)?/g, '') }] }], generationConfig: { responseModalities: ['AUDIO'], speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: $('My settings').first().json.tts_voice } } } } }) }}",
        "options": {}
      },
      "id": "df58da2c-54be-4d9d-8455-e872248195af",
      "name": "Gemini speech",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1472,
        -512
      ]
    },
    {
      "parameters": {
        "jsCode": "// Gemini returns raw audio (PCM, 24 kHz, 16 bit, mono). Add a WAV header so any player can open it.\nconst b64 = $input.first().json.candidates[0].content.parts[0].inlineData.data;\nconst pcm = Buffer.from(b64, 'base64');\nconst rate = 24000, channels = 1, bits = 16;\nconst h = Buffer.alloc(44);\nh.write('RIFF', 0); h.writeUInt32LE(36 + pcm.length, 4); h.write('WAVE', 8);\nh.write('fmt ', 12); h.writeUInt32LE(16, 16); h.writeUInt16LE(1, 20); h.writeUInt16LE(channels, 22);\nh.writeUInt32LE(rate, 24); h.writeUInt32LE(rate * channels * bits / 8, 28);\nh.writeUInt16LE(channels * bits / 8, 32); h.writeUInt16LE(bits, 34);\nh.write('data', 36); h.writeUInt32LE(pcm.length, 40);\nconst wav = Buffer.concat([h, pcm]);\nreturn [{ json: {}, binary: { data: { data: wav.toString('base64'), mimeType: 'audio/wav', fileName: 'daily-brief.wav' } } }];"
      },
      "id": "207cb3b9-0464-4e27-987a-2a19a4654b08",
      "name": "Make WAV file",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1696,
        -512
      ]
    },
    {
      "parameters": {
        "content": "## Remix: Morning podcast\nGemini reads your brief aloud. The HTTP node calls the Gemini speech API with your Gemini credential, the Code node turns the raw audio into a WAV file, and Gmail attaches it.\n\nPick a voice in My settings (tts_voice). Voice names are listed in AI Studio.",
        "height": 176,
        "width": 360,
        "color": 3
      },
      "id": "9c42cafa-09d8-4a7e-a823-32d2a91b9422",
      "name": "Remix note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1040,
        -80
      ]
    }
  ],
  "pinData": {},
  "connections": {
    "Every morning at 7": {
      "main": [
        [
          {
            "node": "My settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get weather": {
      "main": [
        [
          {
            "node": "Format weather",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format weather": {
      "main": [
        [
          {
            "node": "Rain over 50%?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rain over 50%?": {
      "main": [
        [
          {
            "node": "Umbrella note",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Google News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Umbrella note": {
      "main": [
        [
          {
            "node": "Google News",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google News": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Hacker News": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Gemini speech",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "My settings": {
      "main": [
        [
          {
            "node": "Get weather",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini speech": {
      "main": [
        [
          {
            "node": "Make WAV file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Make WAV file": {
      "main": [
        [
          {
            "node": "Send brief",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  }
}