Skip to content

Instantly share code, notes, and snippets.

@zalez
Last active December 16, 2025 16:07
Show Gist options
  • Select an option

  • Save zalez/941e52d8df0a6feea488578427923d72 to your computer and use it in GitHub Desktop.

Select an option

Save zalez/941e52d8df0a6feea488578427923d72 to your computer and use it in GitHub Desktop.
AI news briefing generator, using RSS and llm with Perplexity and Claude plugins.
# Define a function for creating an AI-generated news briefing.
#
# Prerequisites:
# - fish: https://fishshell.com/
# - Python: https://python.org/
# - uv: https://docs.astral.sh/uv/
# - llm: https://github.com/simonw/llm
# - llm-perplexity: https://github.com/hex/llm-perplexity
# - llm-anthropic: https://github.com/simonw/llm-anthropic
# - API keys for Perplexity (https://www.perplexity.ai/api-platform) and Claude (https://claude.com/platform/api)
#
# Installation:
# `source briefing.fish``
#
# Usage:
# `briefing >briefing.md`
# `cat briefing.md`
#
# Use `glow -p <briefing.md` for a nicer experience (https://github.com/charmbracelet/glow)
#
function briefing
set -gx today (date)
set -gx location "Munich, Germany"
set -gx reader "Constantin, a German freelance advisor born on 1971 and based in Munich, Germany, with a wide variety of knowledge and interests including cloud computing, AI and ML, technology in general, public speaking, health and fitness, science-fiction, electronic music, blogging, YouTube film making, and more. He is married, has two daughters and a Dachshund called Elvis. He enjoys coding up pet projects, programming synths, cooking, and running barefoot."
set -gx briefing_dir (mktemp -d)
set feeds \
"https://www.tagesschau.de/infoservices/alle-meldungen-100~rss2.xml" \
"https://www.spiegel.de/schlagzeilen/rss/0,5291,,00.xml" \
"https://rss.sueddeutsche.de/rss/Topthemen" \
"https://feeds.cms.handelsblatt.com/schlagzeilen" \
"https://rss.dw.com/atom/rss-en-all" \
"https://feeds.bbci.co.uk/news/world/rss.xml" \
"https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" \
"https://feeds.washingtonpost.com/rss/world" \
"https://www.ft.com/rss/home/international" \
"https://www.heise.de/rss/heise-atom.xml" \
"https://www.cnet.com/rss/news/" \
"https://news.mit.edu/rss" \
"https://news.smol.ai/rss.xml" \
"https://news.ycombinator.com/rss" \
"https://www.positive.news/feed/" \
"https://feeds.feedburner.com/azquotes/quoteoftheday"
# Utility script in Python to use feedparser to extract the newest 10 items,
# Then print as Markdown.
set rss_to_md_script "
import sys, feedparser, time
f = feedparser.parse(sys.stdin.read())
entries = sorted(
f.entries,
key=lambda e: e.get('published_parsed') or e.get('updated_parsed') or (0,)
)
for e in entries[-10:][::-1]:
ts = e.get('published_parsed') or e.get('updated_parsed')
date = time.strftime('%Y-%m-%d %H:%M:%S', ts) if ts else ''
title = (e.get('title') or '').replace('\n', ' ').strip()
link = e.get('link') or ''
# Prefer summary, then description, then full content; keep all text
content = e.get('summary', '')
if not content:
content = e.get('description', '')
if not content and e.get('content'):
content = ' '.join(
(c.get('value') or '') for c in e.get('content') if isinstance(c, dict)
)
content = content.strip()
if content:
print(f'- [{title}]({link}) ({date})\\n\\n {content}\\n')
else:
print(f'- [{title}]({link}) ({date})')
"
echo "Gathering information..." >&2
# Create a temporary venv with feedparser installed to run our Python code.
set venv_dir $briefing_dir/venv
uv venv $venv_dir 2> /dev/null
uv pip install --python $venv_dir feedparser 2> /dev/null
set python_bin $venv_dir/bin/python
# Download all feeds in parallel (the & after end)
set counter 0
echo "Starting news feed download jobs..." >&2
for feed in $feeds
set file $briefing_dir/newsfeed-$counter.txt
echo -e "Feed: $feed\n\n" >>$file
curl -s $feed | \
$python_bin -c "$rss_to_md_script" >> $file 2> /dev/null &
set counter (math $counter + 1)
end
# Get additional information from Perplexity in parallel
echo "Starting Perplexity query jobs..." >&2
llm -m sonar-pro "Provide the weather forecast for today, $today in $location, including UV index and best times to go outdoors." >>$briefing_dir/weather.txt &
llm -m sonar-pro "Compile a list of 10 recently published AI productivity tips from sources like the Claude team, the OpenAI team, from Ethan Mollick or similar. Make it diverse and instructive." >>$briefing_dir/ai-tips.txt &
llm -m sonar-pro "Compile a list of 10 recently published personal productivity tips from people similar to or including Merlin Mann, Leo Babauta, Cal Newport, and Ryder Carroll. Make it diverse and instructive." >>$briefing_dir/productivity-tips.txt &
llm -m sonar-pro "Today is $today. List any German or international holidays for today, as well as any other interesting facts for this day, famous birthdays or interesting historic events that happened on the same day." >>$briefing_dir/todays-facts.txt &
# Wait for all parallel jobs to finish
set total (count (jobs))
while true
set remaining (count (jobs))
if test $remaining -eq 0
echo -e "\r\033[KAll jobs done." >&2
echo >&2
break
end
set done (math $total - $remaining)
echo -ne "\r\033[K$done / $total jobs finished, $remaining remaining..." >&2
sleep 1
end
echo "Combining news data..." >&2
for file in $briefing_dir/*.txt
echo -e "$file:\n" >>$briefing_dir/all-news.txt
cat $file >>$briefing_dir/all-news.txt
echo -e "\n---\n" >>$briefing_dir/all-news.txt
end
set total_size (wc -c < $briefing_dir/all-news.txt | string trim)
set approx_tokens (math "$total_size / 4" )
echo "Total news data size: $total_size Bytes (approx. $approx_tokens tokens)" >&2
set briefing_prompt "
Review the previously provided information carefully, then create a daily briefing for the current date in Munich, Germany, based on this information.
Rules:
- This report is for: $reader
- For each section, focus on the most relevant, significant or impactful information
- Always use English language, translate if necessary into English
- Format in clean Markdown
- Feel free to add emojis to lighten things up
Use this exact structure:
# πŸ“… [Today's day of week], [Today's date]
[If there are any German or international holidays, or other interesting facts for today, mention them here. Otherwise skip this line.]
---
## πŸ’­ Quote of the Day
[Provide ONE random inspirational quote, fortune cookie wisdom, or daily wisdom. Include author if applicable. Make it relevant and motivational.]
---
## 🌑️ Munich Weather
[Current weather for Munich: temperature, conditions, UV index if relevant, best time for outdoor activities]
---
## πŸ“° News
### πŸ‡©πŸ‡ͺTop 3 Germany
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL]
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
### 🌍 Top 3 World
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
### πŸ’° Top 3 Economy and Finance
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
### πŸ€– Top 3 Science/Tech/AI
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
### 🎬 Top 3 Entertainment
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
### 😊 Top 3 Positive News
1. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
2. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
3. **[Headline]** - [2-3 sentence summary] (Source: [main source URL])
---
## πŸ’‘ AI Productivity Tip
[Choose one AI productivity tip. Mention the author/source. 2-3 sentences maximum.]
---
## ⚑ Personal Productivity Tip
[Choose one personal productivity tip. Mention the author/source. 2-3 sentences maximum.]
---
## 🎴 Oblique Strategy
[Provide one Oblique Strategy card from Brian Eno & Peter Schmidt's deck. Just the strategy text, no explanation needed.]
---
## ✍️ Writing Prompt
[Generate ONE creative writing prompt suitable for a blog post or YouTube video script. Make it specific, actionable, and interesting. One sentence.]
---
## 🀑 Editor's Corner
[Write a funny, but respectful comment or joke about the news you just provided as an editor.]
"
# Construct prompt
echo "Constructing prompt and sending to Claude for final editing..." >&2
echo -e "Today is: $today\n\nRead the following collection of news and other information carefully:\n<INFORMATION_BLOCK>\n" >$briefing_dir/prefix.txt
echo -e "\n<\INFORMATION_BLOCK>\n\nInstructions:\n" >$briefing_dir/end-news.txt
echo -e "$briefing_prompt" >$briefing_dir/briefing-prompt.txt
cat \
$briefing_dir/prefix.txt \
$briefing_dir/all-news.txt \
$briefing_dir/end-news.txt \
$briefing_dir/briefing-prompt.txt \
| llm -m claude-sonnet-4.5
echo "Done." >&2
echo >&2
echo "Cleaning up..." >&2
/bin/rm -rf $briefing_dir
# echo $briefing_dir >&2 # For debugging
echo "Done." >&2
echo >&2
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment