# AGENTS.md - Readbetter Instructions for AI Agents > This file provides instructions for AI agents to help users set up and configure Readbetter, as well as development guidance for AI agents working on the codebase. ## Overview **Readbetter** converts email newsletters, web articles, and other content into Kindle-optimized e-books and delivers them directly to users' Kindle devices. It supports: - **Email forwarding**: Forward newsletters to a personal inbox address - **Quick Send**: Paste article URLs to send directly to Kindle - **Magazines**: Batch multiple articles into daily or weekly magazine-style deliveries - **Chrome Extension**: Send paywalled content from the browser --- ## Plan Mode - Make the plan extremely concise. Sacrifice grammar for the sake of concision. - At the end of each plan, give me a list of unresolved questions to answer, if any. --- ## Tech Stack - **Framework**: Next.js 14 (App Router) - **Language**: TypeScript - **Database/Auth**: Firebase (Firestore + Authentication) - **Background Jobs**: Trigger.dev v4 (task-based async processing) - **Email**: SendGrid, Resend - **Payments**: LemonSqueezy - **UI**: Tailwind CSS, Radix UI, shadcn/ui components - **Package Manager**: pnpm --- ## Development Setup ### Prerequisites 1. Node.js 22.x 2. pnpm (package manager) 3. Firebase project with Firestore and Authentication enabled 4. Trigger.dev account and project ### Installation ```bash # Install dependencies pnpm --dir apps/web install # Run development server (Next.js + Trigger.dev dev) pnpm --dir apps/web dev ``` If your shell is already in `apps/web`, run the same commands without `--dir apps/web`. The repo uses isolated app installs, so web dependency changes should stay in `apps/web/pnpm-lock.yaml`. ### Environment Variables Required environment variables (set in `.env.local` or Vercel): - `FIREBASE_*` - Firebase configuration - `SENDGRID_API_KEY` - For email delivery - `LEMONSQUEEZY_*` - Payment processing - `TRIGGER_SECRET_KEY` - Trigger.dev authentication ### Project Structure ``` src/ ├── app/ # Next.js App Router pages and API routes │ ├── api/ # API endpoints │ └── app/ # Authenticated app pages (dashboard, magazines, etc.) ├── components/ # React components ├── lib/ # Shared utilities and Firebase helpers └── trigger/ # Trigger.dev background tasks ├── helpers/ # Task utility functions ├── magazines/ # Magazine-related tasks └── scheduled-tasks/ # Cron jobs ``` --- ## Trigger.dev Architecture Readbetter uses Trigger.dev v4 for all background processing. Key patterns: ### Core Tasks | Task | Purpose | |------|---------| | `page-to-epub-to-mail` | Convert URL → EPUB → Send to Kindle | | `page-to-epub-to-magazine` | Convert URL → Store for magazine delivery | | `html-to-epub-to-mail` | Convert HTML content → EPUB → Send | | `handle-incoming-mail` | Process forwarded newsletters | | `send-magazine` | Batch send magazine articles | | `generate-preview-from-url` | Generate article preview | | `sync-sendgrid-user` | Sync one user to SendGrid when marketing fields change (`sendgridSyncHash` skip) | ### Scheduled (cron) tasks | Task ID | Cron | Purpose | |---------|------|---------| | `check-rss-feeds` | `*/15 * * * *` | RSS checks | | `clean-cache` | `0 * * * *` | Cache cleanup | | `retry-og-fetch` | `0 */4 * * *` | OG retry | | `update-popularity-stats` | `0 4 * * *` | Popularity stats | | `process-magazine-sends` | `*/30 * * * *` | Auto magazine sends (unlimited plans) | | `reset-usage` | `0 * * * *` | Hourly usage-cycle reset on `accounts` | | `reconcile-sendgrid-users` | `0 3 * * 0` | Weekly batched backfill of stale SendGrid contacts | | `fail-stuck-sending-activities` | `0 5 * * *` | Mark stale `sending` activities as `failed` | ### Task Configuration Tasks are configured in `trigger.config.ts`: - **Runtime**: Node.js - **Max Duration**: 3600s (1 hour) - **Retries**: 3 attempts with exponential backoff - **Build Extensions**: Puppeteer (for web scraping), Vercel env sync ### Triggering Tasks from API Routes ```typescript import { tasks } from "@trigger.dev/sdk" import type { pageToEpubToMail } from "@/trigger/page-to-epub-to-mail" // Type-only import to prevent bundling issues const handle = await tasks.trigger("page-to-epub-to-mail", { url: "https://example.com/article", userId: "user123" }) ``` ### Helper Functions Task helpers are organized in `src/trigger/helpers/`: - `cache/` - EPUB caching with Vercel KV - `mail-parsing/` - Newsletter parsing (Substack, Beehiiv, ConvertKit, etc.) - `generateEpub/` - EPUB generation with readbetter-epub-gen - `makeReadable/` - Content extraction and transformation --- ## User Setup Guide ### Prerequisites Before setting up Readbetter, users need: 1. A **Kindle device** (any Kindle e-reader or Kindle app) 2. An **Amazon account** linked to the Kindle 3. Access to **Amazon's "Manage Your Content and Devices"** settings 4. A **Readbetter account** (free signup at https://readbetter.io/signup) --- ## Setup Instructions (Browser Actions) ### Step 1: Create a Readbetter Account 1. Navigate to `https://readbetter.io/signup` 2. Enter email address and create password 3. Complete email verification if required ### Step 2: Add Readbetter as an Approved Sender in Amazon This step is required because Amazon only accepts documents from pre-approved email addresses. 1. **Navigate to Amazon's device settings:** - US users: `https://www.amazon.com/hz/mycd/myx#/home/settings/personal` - UK users: `https://www.amazon.co.uk/hz/mycd/myx#/home/settings/personal` - DE users: `https://www.amazon.de/hz/mycd/myx#/home/settings/personal` - Other countries: Go to your local Amazon site → Account → "Manage Your Content and Devices" → "Preferences" tab → "Personal Document Settings" 2. **Scroll to "Personal Document Settings" section** 3. **Find "Approved Personal Document E-mail List"** 4. **Click "Add a new approved e-mail address"** 5. **Enter the Readbetter sender address:** ``` {INBOX_CODE}@readbetter.io ``` - The `{INBOX_CODE}` is shown in the user's Readbetter dashboard/setup page - This is a unique identifier assigned to each user - It MUST be the exact address shown in their Readbetter account 6. **Click "Add Address" to confirm** ### Step 3: Find and Enter Kindle Email Address 1. **On the same Amazon page**, locate "Send-to-Kindle E-mail Address" - This is typically just above the "Approved Personal Document E-mail List" 2. **Copy the Kindle email address** - Usually ends in `@kindle.com` - Example: `username_abc@kindle.com` 3. **Return to Readbetter setup** (https://readbetter.io/app/setup) 4. **Paste the Kindle email address** into the input field 5. **Click "Save & Continue"** ### Step 4: Verify Setup 1. Click **"Send Test Email"** in Readbetter 2. Wait 1-2 minutes 3. Check Kindle device for the test document 4. If received, setup is complete --- ## Using Readbetter ### Method 1: Forward Newsletters Forward any newsletter email to the user's Readbetter inbox: ``` {INBOX_CODE}@inbox.readbetter.io ``` **Note:** This is different from the approved sender address: - **Sender address** (for Amazon approval): `{INBOX_CODE}@readbetter.io` - **Inbox address** (for forwarding): `{INBOX_CODE}@inbox.readbetter.io` ### Method 2: Quick Send (URL) 1. Go to https://readbetter.io/app/dashboard 2. Find the "Quick Send" card 3. Paste an article URL 4. Click "Preview" to see how it will look 5. Click "Send to Kindle" **Limitation:** Quick Send cannot access paywalled content. For paid articles, use the Chrome Extension. ### Method 3: Chrome Extension 1. Install from Chrome Web Store: https://chromewebstore.google.com/detail/readbetterio-chrome-exten/hflkmcicpjkbialnmicelkdolddoaphk 2. Navigate to any article (including paywalled content you have access to) 3. Click the Readbetter extension icon 4. Click "Send to Kindle" ### Method 4: Magazines (Batch Delivery) For users with an unlimited plan: 1. Go to https://readbetter.io/app/magazines 2. Configure daily or weekly magazine schedules 3. Articles are batched and delivered at scheduled times 4. Add articles via: - Quick Send → "Add to Daily/Weekly Magazine" - Forwarded emails (if configured) --- ## Advanced: Setting Up Gmail Auto-Forwarding This allows automatic delivery of newsletters without manual forwarding. ### Step 1: Create a Gmail Filter 1. Open Gmail (https://mail.google.com) 2. Click the **gear icon** → **"See all settings"** 3. Go to **"Filters and Blocked Addresses"** tab 4. Click **"Create a new filter"** ### Step 2: Configure the Filter Set filter criteria for newsletters you want to forward: **Option A - Forward specific sender:** ``` From: newsletter@substack.com ``` **Option B - Forward based on subject:** ``` Subject: "Weekly Digest" ``` **Option C - Forward all newsletters (use with caution):** ``` Has the words: unsubscribe ``` Click **"Create filter"** ### Step 3: Set Forward Action 1. Check **"Forward it to:"** 2. Enter: `{INBOX_CODE}@inbox.readbetter.io` 3. Click **"Create filter"** ### Step 4: Verify Forwarding Address (First Time Only) Gmail requires verification for new forwarding addresses: 1. Go to **Settings** → **"Forwarding and POP/IMAP"** 2. Click **"Add a forwarding address"** 3. Enter: `{INBOX_CODE}@inbox.readbetter.io` 4. Click **"Next"** → **"Proceed"** 5. Gmail sends a verification email to Readbetter 6. Readbetter automatically forwards verification emails to the user's registered email 7. Click the verification link or enter the code in Gmail 8. Return to filter setup and select the forwarding address ### Filter Examples for Popular Newsletters **Substack newsletters:** ``` From: @substack.com ``` **Beehiiv newsletters:** ``` From: @mail.beehiiv.com ``` **Medium Daily Digest:** ``` From: noreply@medium.com Subject: "Daily Digest" ``` **Specific newsletter:** ``` From: newsletter@stratechery.com ``` --- ## Troubleshooting ### Test Email Not Received 1. **Check Kindle is online** - Connect to WiFi 2. **Check spam/junk folder** in Amazon 3. **Verify approved sender** - Ensure `{INBOX_CODE}@readbetter.io` is in Amazon's approved list 4. **Check Kindle email** - Ensure correct @kindle.com address is saved in Readbetter 5. **Wait longer** - Delivery can take up to 5 minutes ### Articles Not Converting Properly 1. **Use Chrome Extension** for paywalled content 2. **Try Quick Send** instead of email forwarding 3. **Report the article** via Readbetter dashboard for investigation ### Gmail Forwarding Not Working 1. **Verify forwarding address** is confirmed in Gmail settings 2. **Check filter criteria** - Test with a specific sender first 3. **Ensure filter action** is set to forward to `@inbox.readbetter.io` (with "inbox.") --- ## Key Addresses Reference | Purpose | Format | Example | | ---------------------------- | ---------------------------------- | ---------------------------- | | Approved sender (for Amazon) | `{INBOX_CODE}@readbetter.io` | `abc123@readbetter.io` | | Inbox (for forwarding) | `{INBOX_CODE}@inbox.readbetter.io` | `abc123@inbox.readbetter.io` | | Kindle email | User's Amazon Kindle email | `user_xyz@kindle.com` | --- ## API Endpoints (For Advanced Automation) Readbetter provides API endpoints for programmatic access: - **POST `/api/page-to-epub-to-mail`** - Convert URL to EPUB and send to Kindle - **POST `/api/quick-add-to-magazine`** - Add URL to magazine queue Authentication: Requires Firebase ID token. --- ## Browser Automation for AI Agents When performing browser-based setup tasks (adding approved senders to Amazon, configuring Gmail filters, etc.), AI agents can use browser automation tools. ### Option 1: agent-browser (Recommended) [agent-browser](https://github.com/vercel-labs/agent-browser) is a headless browser automation CLI designed specifically for AI agents. **Installation:** ```bash npm install -g agent-browser agent-browser install # Download Chromium ``` **Core Workflow:** ```bash # 1. Navigate to page agent-browser open https://www.amazon.com/hz/mycd/myx # 2. Get accessibility tree with element refs agent-browser snapshot -i # 3. Interact using refs from snapshot agent-browser click @e2 agent-browser fill @e3 "abc123@readbetter.io" # 4. Re-snapshot after page changes agent-browser snapshot -i ``` **Useful Commands:** - `agent-browser open ` - Navigate to URL - `agent-browser snapshot -i` - Get interactive elements with refs (@e1, @e2) - `agent-browser click @e1` - Click element by ref - `agent-browser fill @e2 "text"` - Fill input field - `agent-browser screenshot page.png` - Take screenshot - `agent-browser close` - Close browser For full documentation, visit: https://github.com/vercel-labs/agent-browser ### Option 2: Existing Tooling If agent-browser is not available or practical to install, AI agents should use their existing browser automation capabilities (e.g., Playwright MCP, built-in browser tools, or other available tooling). ### When to Use Browser Automation Browser automation is helpful for: - Adding Readbetter as an approved sender in Amazon's device settings - Finding the user's Kindle email address - Setting up Gmail filters and forwarding rules - Verifying setup by checking if test emails were delivered - Troubleshooting delivery issues --- ## Support - Email: hello@support.readbetter.io - Website: https://readbetter.io - FAQ: https://readbetter.io/faq --- ## Changelog - **2026-01-15**: Added Plan Mode section, development setup, tech stack overview, Trigger.dev architecture documentation, and project structure guide. - **2026-01-12**: Added browser automation section with agent-browser instructions and fallback to existing tooling. - **2025-01-12**: Initial AGENTS.md created with setup instructions, Gmail forwarding guide, and usage methods.