This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "AI Newsletter Composer",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 5"
}
]
}
},
"id": "a1b2c3d4-1004-4000-8000-000000000001",
"name": "Weekly Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
]
},
{
"parameters": {
"method": "GET",
"url": "https://your-blog.com/feed/rss",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
}
},
"id": "a1b2c3d4-1004-4000-8000-000000000002",
"name": "Fetch RSS Feed",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
500,
300
]
},
{
"parameters": {
"jsCode": "const xml = $input.first().json.data;\n// Extract recent articles from RSS XML\nconst articles = [];\nconst items = xml.match(/<item>([\\s\\S]*?)<\\/item>/g) || [];\nfor (const item of items.slice(0, 5)) {\n const title = (item.match(/<title>([^<]+)<\\/title>/) || [])[1] || '';\n const link = (item.match(/<link>([^<]+)<\\/link>/) || [])[1] || '';\n const description = (item.match(/<description>([^<]+)<\\/description>/) || [])[1] || '';\n articles.push({ title, link, description });\n}\nreturn [{ json: { articles: JSON.stringify(articles) } }];"
},
"id": "a1b2c3d4-1004-4000-8000-000000000003",
"name": "Parse RSS",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
750,
300
]
},
{
"parameters": {
"resource": "chat",
"model": "gpt-4",
"messages": {
"values": [
{
"content": "You are a newsletter editor. Create a weekly newsletter digest from these articles. Write an engaging subject line, a brief intro paragraph, and a summary of each article (2-3 sentences each). End with a call-to-action.\n\nArticles:\n{{ $json.articles }}\n\nReturn JSON with keys: subjectLine, introText, articleSummaries (array of {title, summary, link}), closingCta"
}
]
},
"options": {
"temperature": 0.7,
"maxTokens": 2000
}
},
"id": "a1b2c3d4-1004-4000-8000-000000000004",
"name": "OpenAI Compose Newsletter",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.3,
"position": [
1000,
300
]
},
{
"parameters": {
"jsCode": "const response = JSON.parse($input.first().json.message.content);\nlet htmlBody = `<h2>${response.introText}</h2>`;\nfor (const article of response.articleSummaries) {\n htmlBody += `<h3><a href=\"${article.link}\">${article.title}</a></h3><p>${article.summary}</p>`;\n}\nhtmlBody += `<p><strong>${response.closingCta}</strong></p>`;\nreturn [{\n json: {\n subjectLine: response.subjectLine,\n htmlBody: htmlBody,\n plainText: response.introText\n }\n}];"
},
"id": "a1b2c3d4-1004-4000-8000-000000000005",
"name": "Format Newsletter HTML",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1250,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://us1.api.mailchimp.com/3.0/campaigns",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ type: 'regular', recipients: { list_id: 'your-list-id' }, settings: { subject_line: $json.subjectLine, from_name: 'Your Newsletter', reply_to: 'newsletter@yourdomain.com' } }) }}"
},
"id": "a1b2c3d4-1004-4000-8000-000000000006",
"name": "Send via Mailchimp",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
1500,
300
]
},
{
"parameters": {
"channel": "#marketing",
"text": ":newspaper: Weekly newsletter sent!\n*Subject:* {{ $json.subjectLine }}\n*Time:* {{ new Date().toISOString() }}",
"otherOptions": {}
},
"id": "a1b2c3d4-1004-4000-8000-000000000007",
"name": "Slack Notify",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1750,
300
]
}
],
"connections": {
"Weekly Schedule": {
"main": [
[
{
"node": "Fetch RSS Feed",
"type": "main",
"index": 0
}
]
]
},
"Fetch RSS Feed": {
"main": [
[
{
"node": "Parse RSS",
"type": "main",
"index": 0
}
]
]
},
"Parse RSS": {
"main": [
[
{
"node": "OpenAI Compose Newsletter",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Compose Newsletter": {
"main": [
[
{
"node": "Format Newsletter HTML",
"type": "main",
"index": 0
}
]
]
},
"Format Newsletter HTML": {
"main": [
[
{
"node": "Send via Mailchimp",
"type": "main",
"index": 0
}
]
]
},
"Send via Mailchimp": {
"main": [
[
{
"node": "Slack Notify",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI Newsletter Composer. Uses httpRequest, openAi, slack. Scheduled trigger; 7 nodes.
Source: https://github.com/mlnjsh/n8n-workflows-mega/blob/main/workflows/ai-content/04-newsletter-composer.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
AI-Powered Short-Form Video Generator with OpenAI, Flux, Kling, and ElevenLabs and upload to all social networks. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 51 nodes.
AI Automated TikTok/Youtube Shorts/Reels Generator. Uses httpRequest, openAi, stickyNote, googleDrive. Scheduled trigger; 41 nodes.
Webhook Slack. Uses venafiTlsProtectCloud, stickyNote, respondToWebhook, httpRequest. Webhook trigger; 38 nodes.
Webhook Slack. Uses venafiTlsProtectCloud, stickyNote, respondToWebhook, httpRequest. Webhook trigger; 38 nodes.
Splitout Code. Uses googleSheetsTrigger, httpRequest, splitInBatches, googleSheets. Event-driven trigger; 35 nodes.