ScheduleView on GitHub
Newsletter Generator
Scrapes your blog and industry news, composes a weekly newsletter with human review.
firecrawlairesend
Source
/**
* Generates a weekly newsletter from scraped content and AI summarization.
*/
schedule weekly_newsletter {
label: "Weekly Newsletter"
cron: "0 8 * * 1"
timezone: "America/Los_Angeles"
}
graph generate_newsletter {
label: "Generate Newsletter"
root {
type: code
label: "Start"
code: @ts {
return { week_of: new Date().toISOString().split("T")[0] }
}
outputSchema: @json {
{
"type": "object",
"properties": {
"week_of": { "type": "string" }
}
}
}
}
node scrape_blog {
type: firecrawl
label: "Scrape company blog"
url: @ts { return "https://byteslice.co/blog" }
selector: ".post-list"
onlyMainContent: true
formats: ["markdown"]
}
node scrape_industry {
type: firecrawl
label: "Scrape industry news"
url: @ts { return "https://news.ycombinator.com" }
selector: ".headlines"
onlyMainContent: true
formats: ["markdown"]
}
node compose {
type: ai
label: "Compose newsletter"
kind: object
model: "google/gemini-2.5-flash"
prompt: @ts {
const blog = context.nodes.scrape_blog.output
const news = context.nodes.scrape_industry.output
return "Write a weekly newsletter for the week of " + context.nodes.root.output.week_of + ".\n\nOur blog content:\n" + JSON.stringify(blog) + "\n\nIndustry news:\n" + JSON.stringify(news) + "\n\nFormat: intro paragraph, 3-5 highlights with brief summaries, closing note."
}
schema: @json {
{
"type": "object",
"required": ["subject", "body_html"],
"properties": {
"subject": { "type": "string" },
"body_html": { "type": "string" },
"preview_text": { "type": "string" }
}
}
}
temperature: 0.8
}
node review_draft {
type: code
label: "Review draft"
code: @ts {
return {
subject: context.nodes.compose.output.subject,
preview: context.nodes.compose.output.preview_text || "",
body: context.nodes.compose.output.body_html
}
}
review: {
enabled: true
title: "Review newsletter draft"
description: "Approve or request changes to this week's newsletter."
actions: [
{ id: "send", label: "Send", outcome: "approve" },
{ id: "revise", label: "Needs Changes", outcome: "reject" }
]
}
}
node send_newsletter {
type: resend
label: "Send newsletter"
from: @ts { return "[email protected]" }
to: @ts { return "[email protected]" }
subject: @ts { return context.nodes.compose.output.subject }
html: @ts { return context.nodes.compose.output.body_html }
}
flow {
root -> scrape_blog
root -> scrape_industry
scrape_blog -> compose
scrape_industry -> compose
compose -> review_draft
review_draft -> send_newsletter
}
}
trigger on_weekly {
schedule:weekly_newsletter -> generate_newsletter
enabled: true
}
Flow
Trigger → graph
Graph nodes