Skip to content

A TODO and reminder system that is way too over-engineered. Inspired by Laurie Hérault's article and Coding With Lewis' YouTube video.

License

Notifications You must be signed in to change notification settings

DeadPackets/FaxMeMaybe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔥 FaxMeMaybe 🔥

Proof that you can learn by over-engineering silly ideas!

FaxMeMaybe

Cloudflare Workers React TypeScript Python Hono Todoist

License GitHub Actions AWS SQS Raspberry Pi

Inspired by Laurie Hérault's article and Coding With Lewis' YouTube video

Live DemoReport BugRequest Feature


📖 Table of Contents


🎯 What is FaxMeMaybe?

FaxMeMaybe is a purposefully over-engineered TODO and reminder system that takes a simple concept, which is "send yourself a reminder", and turns it into a distributed, cloud-native, edge-computing masterpiece that physically prints your TODOs on thermal paper.

Instead of using a simple note-taking app, FaxMeMaybe:

  1. 📝 Accepts TODOs through a beautiful web interface
  2. 🌐 Runs on the edge using Cloudflare Workers
  3. 📋 Syncs with Todoist as the source of truth
  4. 🎨 Renders tickets using a headless browser (Puppeteer)
  5. 💾 Stores ID mappings in Cloudflare D1 (SQLite at the edge)
  6. 📤 Sends print jobs to AWS SQS
  7. 🍓 Polls messages on a Raspberry Pi
  8. 🖨️ Physically prints your TODO on a thermal printer

This is engineering for the sake of engineering, and I have learned alot from it! 🎉


🤔 Why build something so over-engineered?

Because we can! But also because it's a fantastic learning project that demonstrates:

  • Modern web development practices
  • Cloud infrastructure and edge computing
  • Serverless architecture
  • Message queue patterns
  • Hardware integration
  • CI/CD pipelines
  • Full-stack development

I did not know most of these technologies before starting this project. By combining them into a single, silly application, I was able to learn how they all work together in a real-world scenario.


🏗️ Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                          USER                                    │
│                            │                                     │
│                            ▼                                     │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │         React Frontend (Vite + TypeScript)                │  │
│  │  • shadcn/ui components • Dark/Light mode • QR codes     │  │
│  └──────────────────────────────────────────────────────────┘  │
│                            │                                     │
│                            ▼                                     │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │      Cloudflare Workers (Edge Runtime - Hono)            │  │
│  │  • API endpoints • Rate limiting • Authentication        │  │
│  └──────────────────────────────────────────────────────────┘  │
│            │                │                │                   │
│            ▼                ▼                ▼                   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │   Todoist   │  │ R2 Storage  │  │  Puppeteer  │            │
│  │  (Storage)  │  │  (Tickets)  │  │  (Headless) │            │
│  └─────────────┘  └─────────────┘  └─────────────┘            │
│        │                  │                                      │
│        │                  ▼                                      │
│        │         ┌─────────────────┐                           │
│        │         │    AWS SQS      │                           │
│        │         │  Message Queue  │                           │
│        │         └─────────────────┘                           │
│        │                  │                                      │
│        ▼                  ▼                                      │
│  ┌─────────────┐  ┌───────────────────────────────────┐        │
│  │ D1 Database │  │  Raspberry Pi Client (Python)     │        │
│  │ (ID Mapping)│  │  • SQS Polling • Image Download   │        │
│  └─────────────┘  └───────────────────────────────────┘        │
│                            │                                     │
│                            ▼                                     │
│                   ┌─────────────────┐                           │
│                   │ Thermal Printer │                           │
│                   │   (USB Device)  │                           │
│                   └─────────────────┘                           │
│                                                                   │
│         ┌───────────────────────────────────┐                   │
│         │    GitHub Actions (CI/CD)         │                   │
│         │  • Auto-deploy on push            │                   │
│         └───────────────────────────────────┘                   │
└─────────────────────────────────────────────────────────────────┘

🎓 Technology Explained (For Beginners)

🎨 Frontend Technologies

Technology Description Think of it as...
React A JavaScript library for building user interfaces
• Build reusable components
• Declarative UI updates
• Virtual DOM for performance
LEGO blocks for websites — you build components that work together
TypeScript JavaScript with type checking
• Catches bugs at compile time
• Better IDE support
• Self-documenting code
JavaScript with superpowers and safety rails
Vite Lightning-fast build tool
• Instant hot module replacement
• Optimized production builds
• Native ES modules
A sports car version of webpack — fast development, smooth builds
shadcn/ui Beautiful, accessible component library
• Built on Radix UI primitives
• Fully customizable
• Copy-paste ready
A designer's gift to developers — pre-made, gorgeous components

⚡ Backend Technologies

Technology Description Think of it as...
Cloudflare Workers Serverless code running at the edge
• Runs in 300+ cities worldwide
• Auto-scaling, zero config
• Pay only for what you use
• <1ms cold starts
Your code living in the cloud, close to users, automatically scaling
Hono Lightweight web framework
• Express.js-like API
• Built for edge runtimes
• Middleware support
• Ultra-fast routing
Express.js's speedy cousin built for the edge
Todoist Task management as a service
• Full-featured TODO storage
• Labels, priorities, due dates
• Cross-platform sync
• Powerful API
Your TODO database in the cloud with a beautiful UI
Cloudflare D1 Serverless SQLite database
• Stores QR code → Todoist ID mappings
• Global replication
• Zero-latency reads
• Automatic backups
A lightweight mapping table at the edge
Cloudflare R2 Object storage (S3-compatible)
• No egress fees
• Global distribution
• S3 API compatible
• Stores our ticket images
A hard drive in the cloud — upload files, get URLs
Puppeteer Headless browser automation
• Chrome/Chromium control
• Screenshot & PDF generation
• Web scraping & testing
• Renders our tickets
A robot that opens web pages and takes screenshots

📬 Message Queue

Technology Description Why use it?
AWS SQS Simple Queue Service
• Fully managed message queue
• Guaranteed delivery
• Automatic scaling
• Dead-letter queue support
Think of it as: A reliable post office
• Server doesn't need to know if printer is online
• Messages wait until printer is ready
• Automatic retries if something fails
• Decouples services for reliability

🖥️ Hardware & Client

Technology Description Perfect for...
Raspberry Pi Tiny, affordable Linux computer
• Size of a credit card
• Low power consumption
• GPIO pins for hardware
• Full Linux environment
IoT projects, home automation, learning Linux, and running our printer client!
Python Beginner-friendly programming language
• Easy to read and write
• Huge ecosystem of libraries
• Great for automation
• Hardware control via libraries
Scripting, automation, data processing, and controlling our thermal printer
python-escpos Python library for ESC/POS printers
• USB thermal printer control
• Image printing support
• Cross-platform
• Easy-to-use API
Controlling receipt printers and thermal printers with Python

🚀 DevOps & CI/CD

Technology Description What it does for us
GitHub Actions Automation for GitHub repositories
• Trigger on push/PR/schedule
• Matrix builds
• Secrets management
• Free for public repos
Think of it as: A robot assistant that:
• Watches for code changes
• Runs tests automatically
• Deploys to production
• Notifies you of issues
CI/CD Continuous Integration/Deployment
• Automate testing
• Automate deployment
• Catch bugs early
• Fast iteration
Push to main → Build → Test → Deploy
All automatic, no manual steps!

✨ Features

🌐 Web Interface

  • ✅ Beautiful, responsive React UI with dark/light mode
  • ✅ Real-time TODO submission with validation
  • ✅ Importance levels (Low, Medium, High, Urgent, Critical) with 🔥 indicators
  • ✅ Optional due dates with natural language support ("tomorrow", "next Friday")
  • ✅ Optional sender information and description
  • ✅ Todoist label selection with color support
  • ✅ Live counter showing total TODOs sent
  • ✅ Admin dashboard for managing TODOs

📋 Todoist Integration

  • ✅ Todoist as the source of truth for all TODOs
  • ✅ Automatic project creation ("FaxMeMaybe" project)
  • ✅ Label sync from your Todoist account
  • ✅ Priority mapping (importance levels → Todoist priorities)
  • ✅ Natural language due date parsing
  • ✅ Two-way sync via webhooks (optional)
  • ✅ Direct links to tasks in Todoist app

🎫 Ticket System

  • ✅ Automatic ticket generation with QR codes
  • ✅ Labels displayed on printed tickets
  • ✅ Printable ticket view optimized for thermal printers
  • ✅ QR code leads to ViewTodo page for easy completion tracking
  • ✅ Tickets stored as images in R2 storage

📱 ViewTodo Page

  • ✅ Access TODO details via QR code or direct link
  • ✅ View labels, description, and due dates
  • ✅ Mark TODOs as complete with one click (syncs to Todoist)
  • ✅ Direct link to open task in Todoist
  • ✅ Beautiful themed UI matching the main app
  • ✅ No authentication required (perfect for QR code access)

🛡️ Security & Performance

  • ✅ Rate limiting (10 requests per minute)
  • ✅ Input validation and sanitization
  • ✅ CORS configuration
  • ✅ Edge computing for global low latency
  • ✅ SQLite database at the edge (D1)

🤖 Automation

  • ✅ Automated deployments via GitHub Actions
  • ✅ Automatic server rebuild on code changes
  • ✅ SQS message polling on Raspberry Pi
  • ✅ Automatic ticket rendering and storage

🖨️ Physical Printing

  • ✅ USB thermal printer support
  • ✅ Automatic paper size detection
  • ✅ Image preprocessing for optimal print quality
  • ✅ Error handling and retry logic

🔄 How It Works

1️⃣ User Creates a TODO

  1. Visit remind.deadpackets.pw
  2. Fill out the TODO form (importance, message, due date, labels, sender)
  3. Click "Send TODO"
  4. The form validates input and sends a POST request to the API

2️⃣ Server Processes the Request

  1. Cloudflare Worker receives the request
  2. Rate limiting checks (max 10 per minute)
  3. Task is created in Todoist (in "FaxMeMaybe" project)
  4. A mapping (QR UUID → Todoist ID) is saved to D1 database
  5. A headless browser (Puppeteer) renders a ticket page as an image
  6. The ticket image is uploaded to R2 storage
  7. A message is sent to AWS SQS with the image URL

3️⃣ Raspberry Pi Polls for Jobs

  1. Python client continuously polls SQS for new messages
  2. When a message arrives, it downloads the ticket image
  3. The image is preprocessed (resized, converted to 1-bit)
  4. The USB thermal printer receives the data and prints!

4️⃣ User Scans QR Code

  1. The printed ticket includes a QR code
  2. Scanning it opens the ViewTodo page
  3. User can see full TODO details (including labels and description)
  4. Clicking "Mark as Complete" updates Todoist
  5. The TODO is now tracked as done in both FaxMeMaybe and Todoist!

📁 Project Structure

FaxMeMaybe/
├── 📂 fax-me-maybe-server/          # Cloudflare Workers backend + React frontend
│   ├── 📂 src/
│   │   ├── 📂 worker/               # Hono backend (TypeScript)
│   │   │   ├── index.ts             # Main API routes
│   │   │   ├── rate-limit.ts        # Rate limiting middleware
│   │   │   ├── api.types.ts         # TypeScript type definitions
│   │   │   └── 📂 services/
│   │   │       └── todoist.ts       # Todoist API integration
│   │   ├── 📂 react-app/            # React frontend
│   │   │   ├── App.tsx              # Main TODO submission page
│   │   │   ├── AdminDashboard.tsx   # Admin panel for managing TODOs
│   │   │   ├── TodoTicket.tsx       # Printable ticket view
│   │   │   ├── ViewTodo.tsx         # QR code accessible TODO viewer
│   │   │   └── main.tsx             # React router setup
│   │   ├── 📂 components/           # shadcn/ui components
│   │   │   └── ui/                  # Reusable UI components
│   │   │       ├── label-selector.tsx   # Todoist label picker
│   │   │       └── smart-date-input.tsx # Natural language date input
│   │   └── 📂 lib/
│   │       └── utils.ts             # Utility functions
│   ├── 📂 public/                   # Static assets
│   │   ├── og-image.png             # OpenGraph preview image
│   │   └── flame.svg                # Logo/icon
│   ├── 📂 migrations/               # D1 database migrations
│   │   └── 0001_todoist_integration.sql # Todoist mapping table
│   ├── package.json                 # Node.js dependencies
│   ├── wrangler.json                # Cloudflare Workers configuration
│   ├── vite.config.ts               # Vite build configuration
│   └── tsconfig.json                # TypeScript configuration
│
├── 📂 fax-me-maybe-client/          # Raspberry Pi printer client
│   ├── main.py                      # SQS polling and printer control
│   ├── pyproject.toml               # Python dependencies
│   ├── Dockerfile                   # Container configuration
│   └── docker-compose.yml           # Docker Compose setup
│
├── 📂 .github/
│   └── 📂 workflows/                # GitHub Actions CI/CD
│       ├── build-server-on-push.yml # Auto-deploy server
│       └── build-client-on-push.yml # Build client
│
├── LICENSE                          # MIT License
├── README.md                        # You are here! 👋
└── TODO.md                          # Project roadmap

🚀 Technologies Used

  • Node.js 24+ (for the server)
  • Python 3.14+ (for the client)
  • npm or yarn (package manager)
  • Cloudflare account (free tier works!)
  • AWS account (for SQS)
  • Raspberry Pi (optional, for physical printing)
  • USB Thermal Printer (optional)

⚙️ Configuration

Cloudflare Workers (wrangler.json)

  • name: Your worker name
  • compatibility_date: Cloudflare runtime version
  • routes: Custom domain mapping
  • d1_databases: Database binding (for ID mappings)
  • r2_buckets: Storage binding
  • browser: Puppeteer browser binding

Environment Variables / Secrets

Variable Description Required
TODOIST_API_TOKEN Your Todoist API token Yes
TODOIST_PROJECT_NAME Todoist project name (default: "FaxMeMaybe") No
TODOIST_WEBHOOK_SECRET Secret for webhook verification No
HONO_API_KEY API key for protected endpoints Yes
AWS_ACCESS_KEY_ID AWS credentials for SQS Yes
AWS_SECRET_ACCESS_KEY AWS credentials for SQS Yes
AWS_REGION AWS region for SQS Yes
SQS_QUEUE_URL SQS queue URL Yes

Todoist Setup

  1. Get your API token from Todoist Developer Settings
  2. Set the secret: wrangler secret put TODOIST_API_TOKEN
  3. (Optional) Configure webhook at Todoist App Console pointing to /api/webhooks/todoist

Rate Limiting

Edit src/worker/rate-limit.ts:

simple: {
    limit: 10,      // Max requests
    period: 60      // Time window (seconds)
}

AWS SQS

  1. Create an SQS queue in AWS Console
  2. Set visibility timeout to 60 seconds
  3. Enable server-side encryption (optional)
  4. Copy the queue URL to .dev.vars

📖 Usage

Creating a TODO

  1. Visit your deployed site (e.g., remind.deadpackets.pw)
  2. Select importance level (🔥 Low → 🔥🔥🔥🔥🔥 Critical)
  3. Enter your TODO message (max 64 characters)
  4. (Optional) Add a description (max 500 characters)
  5. (Optional) Set a due date (supports natural language like "tomorrow", "next Friday")
  6. (Optional) Select labels from your Todoist account
  7. (Optional) Add your name in "From" field
  8. Click "Send TODO"
  9. Your TODO is created in Todoist and queued for printing!

Viewing TODOs (Admin)

  1. Navigate to /admin
  2. View all pending and completed TODOs (synced from Todoist)
  3. See labels, descriptions, and due dates
  4. Filter by completion status or labels
  5. Mark items as complete/incomplete (syncs to Todoist)
  6. Open tasks directly in Todoist
  7. Delete TODOs

Accessing via QR Code

  1. Print a TODO ticket
  2. Scan the QR code with your phone
  3. View full TODO details
  4. Click "Mark as Complete" when done

API Endpoints

Public Endpoints

POST   /api/todos                    # Create new TODO (syncs to Todoist)
GET    /api/todos/count              # Get total TODO count
GET    /api/todos/:id                # Get TODO by ID (fetches from Todoist)
GET    /api/todos/:id/complete       # Mark TODO as complete (syncs to Todoist)

Protected Endpoints (require X-API-Key header)

GET    /api/todos                    # List all TODOs from Todoist
GET    /api/labels                   # Get available Todoist labels
PATCH  /api/todos/:id/incomplete     # Mark as incomplete (syncs to Todoist)
DELETE /api/todos/:id                # Delete TODO (removes from Todoist)
POST   /api/webhooks/todoist         # Todoist webhook receiver

Example: Create TODO with Labels

curl -X POST https://remind.deadpackets.pw/api/todos \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -d '{
    "todo": "Review the design mockups",
    "importance": 3,
    "description": "Check the new landing page designs",
    "dueDate": "next Friday",
    "labels": ["work", "design"],
    "from": "Design Team"
  }'

🤝 Contributing

Contributions are welcome! This is a learning project, so don't be shy.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

  • Laurie Hérault - Original inspiration from "A receipt printer cured my procrastination"
  • Coding With Lewis - YouTube tutorial that sparked the idea
  • Cloudflare - For amazing edge computing tools
  • python-escpos - For making thermal printer integration easy
  • shadcn/ui - For beautiful, accessible components
  • The open-source community ❤️

Made with ☕ and way too much engineering

If you found this project helpful or entertaining, give it a ⭐!

Report IssuesRequest Features

About

A TODO and reminder system that is way too over-engineered. Inspired by Laurie Hérault's article and Coding With Lewis' YouTube video.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors 3

  •  
  •  
  •