Daily News Digest
Fetches top Hacker News stories daily, summarizes with AI, and emails a digest.
httpmapaiemail
Source
/**
* Fetches top stories daily, summarizes them with AI,
* and emails a digest.
*/
schedule morning_digest {
label: "Morning Digest"
cron: "0 7 * * *"
timezone: "America/New_York"
}
workflow build_digest {
label: "Build Daily Digest"
root {
type: code
label: "Start"
code: @ts { return { timestamp: new Date().toISOString() } }
outputSchema: @json {
{
"type": "object",
"properties": {
"timestamp": { "type": "string" }
}
}
}
}
node fetch_tech {
type: http
label: "Fetch tech news"
url: @ts { return "https://hacker-news.firebaseio.com/v0/topstories.json?limitToFirst=10&orderBy=%22$key%22" }
}
node fetch_stories {
type: code
label: "Extract story IDs"
code: @ts {
const ids = context.nodes.fetch_tech.output
return { ids: Array.isArray(ids) ? ids.slice(0, 5) : [] }
}
}
node fetch_details {
type: map
label: "Fetch each story"
items: @ts { return context.nodes.fetch_stories.output.ids }
maxItems: 5
subgraph {
root {
type: http
label: "Fetch story"
inputSchema: @json { { "type": "number" } }
url: @ts { return "https://hacker-news.firebaseio.com/v0/item/" + context.iteration.item + ".json" }
}
}
}
node collect_stories {
type: code
label: "Collect story titles"
code: @ts {
const rows = context.nodes.fetch_details.output || []
const stories = rows
.map(function(row) { return row.root })
.filter(function(story) { return story && story.title })
.map(function(story) { return { title: story.title, url: story.url || "", score: story.score || 0 } })
return { stories: stories }
}
}
node summarize {
type: ai
label: "Summarize headlines"
kind: text
model: "google/gemini-2.5-flash"
prompt: @ts {
const stories = context.nodes.collect_stories.output.stories
const list = stories.map(function(s) { return "- " + s.title + " (" + s.score + " points) " + s.url }).join("\n")
return "Write a brief daily tech news digest for " + context.nodes.root.output.timestamp + ". Open with a 2-3 sentence intro, then list each story with a one-line takeaway.\n\nToday's top Hacker News stories:\n" + list
}
temperature: 0.7
}
node send_digest {
type: email
label: "Send digest email"
from: @ts { return "[email protected]" }
to: @ts { return "[email protected]" }
subject: @ts {
const d = new Date(context.nodes.root.output.timestamp)
return "Daily Tech Digest - " + d.toLocaleDateString()
}
text: @ts { return context.nodes.summarize.output }
}
flow {
root -> fetch_tech
fetch_tech -> fetch_stories
fetch_stories -> fetch_details
fetch_details -> collect_stories
collect_stories -> summarize
summarize -> send_digest
}
}
trigger daily_trigger {
schedule:morning_digest -> build_digest
enabled: true
}
Flow
Trigger to workflow
morning_digestschedule
build_digest
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Workflow nodes
CODE
Code Node
Start
HTTP
HTTP Node
Fetch tech news
CODE
Code Node
Extract story IDs
MAP
Map Node
Fetch each story
CODE
Code Node
Collect story titles
AI
AI Node
Summarize headlines
EMAIL
Email Node
Send digest email
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.