Swirls

SWIRLS_

  • How it works
  • Pricing

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6
← Content & MediaScheduleView on GitHub

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.