product-hunt-mailer

A Python CLI tool that fetches Product Hunt's daily top launches, generates AI-powered summaries using Gemini, and sends a beautifully formatted email digest via Resend.

000Python
ai-daily-newsai-toolsdaily-tasksemailernewsletterproducthunt

Last updated:

🚀 Product Hunt Daily Emailer

A Python CLI tool that fetches Product Hunt's daily top launches, generates AI-powered summaries using Gemini, and sends a beautifully formatted email digest via Resend.

Python License

image image image

✨ Features

  • 🔍 Fetches top products from Product Hunt API
  • 🤖 AI-powered summaries using Gemini 3 Flash Preview (free tier)
  • 📧 Beautiful HTML email templates
  • ⚙️ YAML-based configuration
  • 🍓 Raspberry Pi cron job ready

⚡ One-Line Install (Raspberry Pi / Linux)

curl -fsSL https://raw.githubusercontent.com/eyupucmaz/product-hunt-mailer/main/install.sh | bash

This interactive script will:

  • Install uv package manager
  • Clone the repository
  • Configure your API keys and email settings
  • Set up a cron job for scheduled emails

📋 Prerequisites

🚀 Manual Setup

1. Clone the repository

git clone https://github.com/eyupucmaz/product-hunt-mailer.git
cd product-hunt-mailer

2. Install dependencies

# Install uv if you haven't
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install project dependencies
uv sync

3. Configure environment variables

cp .env.example .env

Edit .env and add your API keys:

GEMINI_API_KEY=your_gemini_api_key_here
RESEND_API_KEY=your_resend_api_key_here
PRODUCT_HUNT_TOKEN=your_product_hunt_token_here

4. Configure email settings

cp config.example.yaml config.yaml

Edit config.yaml to set your recipients and sender email:

email:
  from: "Product Hunt Digest <digest@yourdomain.com>"
  subject_prefix: "🚀 Product Hunt Daily"

recipients:
  - name: "Your Name"
    email: "you@example.com"

Note: The sender email domain must be verified in your Resend dashboard.

5. Run

uv run python -m src.main

🍓 Raspberry Pi Deployment

Install uv on Raspberry Pi

curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env

Clone and Setup

cd ~
git clone https://github.com/eyupucmaz/product-hunt-mailer.git
cd product-hunt-mailer

uv sync

cp .env.example .env
cp config.example.yaml config.yaml
# Edit both files with your settings

Test

uv run python -m src.main

Setup Cron Job

crontab -e

Add one of these lines:

# Daily at 9:00 AM
0 9 * * * cd /home/pi/product-hunt-mailer && /home/pi/.local/bin/uv run python -m src.main >> /home/pi/product-hunt-mailer/cron.log 2>&1

# Daily at 8:00 AM and 6:00 PM
0 8,18 * * * cd /home/pi/product-hunt-mailer && /home/pi/.local/bin/uv run python -m src.main >> /home/pi/product-hunt-mailer/cron.log 2>&1

# Weekdays only at 9:00 AM
0 9 * * 1-5 cd /home/pi/product-hunt-mailer && /home/pi/.local/bin/uv run python -m src.main >> /home/pi/product-hunt-mailer/cron.log 2>&1

Note: Replace /home/pi with your actual home directory (echo $HOME)

📁 Project Structure

product-hunt-mailer/
├── .env.example          # Environment variables template
├── config.example.yaml   # Configuration template
├── pyproject.toml        # Dependencies
├── README.md
└── src/
    ├── __init__.py
    ├── main.py           # CLI entry point
  ├── scraper.py        # Product Hunt API client
    ├── summarizer.py     # Gemini AI integration
    └── mailer.py         # Resend email sender

⚙️ Configuration Options

config.yaml

OptionDescription
email.fromSender email (must be verified in Resend)
email.subject_prefixEmail subject prefix
recipientsList of recipients with name and email
settings.product_countNumber of products to include (1-10)
gemini.modelGemini model to use

Environment Variables

VariableDescription
GEMINI_API_KEYGemini API key
RESEND_API_KEYResend API key
PRODUCT_HUNT_TOKENProduct Hunt developer token or OAuth access token

Gemini Models

ModelDescription
gemini-3-flash-previewLatest, fastest, recommended (free)
gemini-2.5-flashPrevious generation (free)

🔧 Troubleshooting

IssueSolution
invalid_oauth_tokenToken is invalid or expired. Use a valid developer token or refresh OAuth token.
GEMINI_API_KEY requiredMake sure .env file exists and contains your API key (uncommented)
Cron not runningUse absolute paths for uv in crontab. Check with which uv
No email receivedCheck Resend dashboard for delivery status. Verify sender domain.

📄 License

MIT License - feel free to use this for your own projects!

🙏 Credits