A delightful Telegram-to-printer mailbox for kids. Family members message a Telegram bot, and messages (including photos!) magically print on a thermal receipt printer connected to a Raspberry Pi. Kids can reply using the keyboard!
Kid Fax turns a Raspberry Pi into a physical mailbox for Telegram messages:
💬 Family messages bot → 🖨️ Instant print → 📧 Physical message
- ⌨️ Kids reply from the keyboard
- 🛡️ Safe: Only approved chat IDs can send messages
- 📸 NEW! Prints photos as pixel art with Floyd-Steinberg dithering
- 💰 FREE! No per-message costs (unlike SMS)
- 🎨 Optional: E-ink display shows last message status
- 🏠 No screens, no web interface - just simple, magical communication
Perfect for:
- Kids too young for smartphones
- Grandparents who love sending messages and photos
- Teaching communication without screens
- Physical keepsakes of family messages
- International families (no SMS fees!)
Raspberry Pi (any model with GPIO, tested on Pi 400)
- Buy: Raspberry Pi Kit
Thermal Printer (58mm ESC/POS compatible)
- Buy: Netum 58mm Printer
- Alternative: Adafruit Mini Thermal Receipt Printer
Printer Paper
- Buy: 58mm Receipt Paper
Telegram Bot (for messaging)
- Create a bot via @BotFather on Telegram
- FREE - no fees, unlimited messages!
E-ink Display (2.9" Waveshare HAT for message counter)
- Shows "You have 3 new messages!" badge
Keyboard & Monitor for replies
- Buy: Bluetooth Keyboard/Mouse
- Buy: HDMI Monitor
Complete Setup Guide: See docs/TELEGRAM_SETUP.md
This guide walks you through everything step-by-step:
- ✅ Hardware assembly
- ✅ Software installation (copy/paste commands)
- ✅ Telegram bot creation via @BotFather
- ✅ Chat ID discovery for your family
- ✅ Testing your first message
- ✅ Troubleshooting common issues
Time: 20-30 minutes from unboxing to first printed message!
USB Printer:
- Connect thermal printer to Raspberry Pi via USB
- Power on the printer
Serial Printer (Adafruit Mini TTL):
- Connect TX→RX, RX→TX, GND→GND
- Connect separate 5-9V power supply to printer
- Enable serial:
sudo raspi-config→ Interface Options → Serial Port → Enable
Optional E-ink Display:
- Attach Waveshare 2.9" HAT to GPIO pins
- Enable SPI:
sudo raspi-config→ Interface Options → SPI → Enable
- Open Telegram and search for @BotFather
- Send
/newbotand follow prompts - Choose name: "Kid Fax Family Bot"
- Choose username:
kidfax_family_bot(must end inbot) - Save the bot token (looks like
123456789:ABCdef...) - See docs/TELEGRAM_SETUP.md for detailed instructions
# Install system dependencies
sudo apt-get update
sudo apt-get install -y python3-pip python3-dev libusb-1.0-0-dev
# Clone the repository
git clone https://github.com/yourusername/KID-FAX.git
cd KID-FAX
# Install Python dependencies
pip3 install -r requirements.txt
# Configure environment
cp .env.example .env
nano .env # Edit with your Telegram bot token# Have family members send "hello" to your bot
# Then discover their chat IDs:
python -m kidfax.discover_chats
# Copy the output to your .env file
# Add the CONTACTS and ALLOWLIST lines
# Start the Telegram poller
python -m kidfax.telegram_poller
# Send a message to your bot
# Watch it print!Receiving Messages:
📱 Family Member's Phone
↓
Message to Telegram Bot
↓
☁️ Telegram Bot API
↓
🔄 Kid Fax Telegram Poller (long polling, 30s timeout - instant!)
↓
🛡️ Allowlist Check (kid safety - only approved chat IDs)
↓
📸 Photo Download & Dithering (optional, pixel art!)
↓
🖨️ Thermal Printer
↓
📄 Physical Receipt with Text + Photo
🎨 Optional: E-ink display updates
Sending Replies:
⌨️ Option 1: CLI
python -m kidfax.send_telegram grandma "Hi!"
🎹 Option 2: Interactive Keyboard Mode
Press F1 (Grandma) → Type message → Press Enter → Send!
📺 E-ink display shows recipient and message in real-time
Copy .env.example to .env and configure:
# Twilio credentials
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_NUMBER=+15551234567
# Security: Only these numbers can send messages (kid safety!)
ALLOWLIST=+15551112222,+15553334444
# Friendly names for contacts
CONTACTS=grandma:+15551112222,uncle:+15553334444
# Printer type: usb, serial, network, bluetooth
PRINTER_TYPE=usb# Find your printer's vendor and product IDs
lsusb # Look for your printer (e.g., ID 0416:5011)
# In .env:
USB_VENDOR=0x0416
USB_PRODUCT=0x5011# In .env:
PRINTER_TYPE=serial
SERIAL_PORT=/dev/serial0
SERIAL_BAUD=19200See .env.example for all configuration options.
Set up Kid Fax to run automatically on boot:
# Create systemd service
sudo nano /etc/systemd/system/kidfax.serviceSee SYSTEMD_SETUP.md for complete service configuration.
Start the service:
sudo systemctl enable kidfax
sudo systemctl start kidfaxView logs:
sudo journalctl -u kidfax -fOption 1: Command Line (quick replies)
# Reply by contact name
python -m kidfax.send_sms grandma "Thanks for the message!"
# Reply by phone number
python -m kidfax.send_sms +15551112222 "Hi Grandma!"Option 2: Interactive Keyboard Mode (kid-friendly!)
Press function keys to select recipients - perfect for kids on Raspberry Pi 400!
# Start interactive keyboard mode
python -m kidfax.interactive_keyboardHow it works:
- Press F1-F12 to select a recipient (each key = family member)
- Type your message and watch it appear on e-ink display
- Press Enter to send
- ✓ Message sent! (optional receipt prints)
Physical Setup:
- Add stickers above F1-F12 keys with contact names
- Perfect for Raspberry Pi 400 Computer Kit (built-in keyboard)
- E-ink display shows recipient and message in real-time
See KEYBOARD_MODE.md for complete interactive mode guide including:
- Physical sticker templates
- F-key contact mapping
- E-ink display layouts
- Troubleshooting keyboard shortcuts
Admin Web Interface (easiest way to manage contacts!)
Start the admin UI:
python -m kidfax.admin_webOpen browser: http://localhost:5000/admin
Features:
- 🌐 Browser-based UI for managing contacts and allowlist
- ✏️ Add, edit, and delete contacts with validation
- 🛡️ Manage security allowlist (who can send messages)
- 📊 See F-key mapping (F1-F12 for keyboard mode)
- 🔄 Restart service to apply changes
- 🔐 Password-protected (set
ADMIN_PASSWORDin .env)
Alternative: Manual .env Editing
For advanced users or when the web UI isn't available:
nano .env
# Edit CONTACTS and ALLOWLIST manually
sudo systemctl restart kidfaxSee ADMIN_WEB.md for complete admin interface guide including:
- Setup instructions
- Phone number format (E.164)
- Security best practices
- Troubleshooting
Add pixel art portraits to printed receipts! Avatars appear between the header and message text.
Upload avatars via admin UI:
- Start admin UI:
python -m kidfax.admin_web - Open:
http://localhost:5000/admin - Click "Add Avatar" next to any contact
- Upload a square PNG image (will be converted to pixel art)
- Avatar prints on all messages from that contact
Tips for best results:
- Use square images (64x64 to 128x128 pixels recommended)
- High contrast images work best (faces, logos, simple icons)
- Images are automatically converted to black/white pixel art
- PNG format only (max 5MB)
Configuration (in .env):
AVATAR_ENABLED=true # Enable/disable avatar printing
AVATAR_SIZE=96 # Avatar size in pixels (64, 96, or 128)
AVATAR_DIR=/home/pi/.kidfax_avatars # Storage directoryReceipt with avatar:
Kid Fax [header]
2024-01-15 14:30 [timestamp]
--------------------------------
[96x96 pixel avatar] [centered]
From: Grandma (+1555...) [sender]
Thanks for the cookies! [message]
- Allowlist: Only approved phone numbers can send messages
- No web exposure: Everything runs locally on your Pi
- No screen time: Physical receipts instead of screens
- Supervised: Parents control who can communicate
- SMS not encrypted: Avoid sharing sensitive information
- Twilio security: Industry-standard SMS gateway
- Local storage: Message state stored on Pi only
- No cloud logging: Messages aren't stored in databases
# Strict allowlist (recommended)
ALLOWLIST=+15551112222,+15553334444
# Empty allowlist accepts all (NOT recommended for kids)
# ALLOWLIST=USB Printer:
# Check if printer is detected
lsusb
# Check permissions
sudo usermod -a -G lp,dialout pi
# Log out and log back in
# Try different USB portsSerial Printer:
# Check serial port exists
ls /dev/serial*
# Enable serial interface
sudo raspi-config- Check Twilio credentials: Test with
python -m kidfax.send_sms +1... "test" - Check allowlist: Ensure sender is in
ALLOWLIST - Check state file: May have already processed message - delete
~/.kidfax_state.jsonto reset - Check printer:
python -c "from kidfax.printer import get_printer; print(get_printer())"
# Use dummy printer mode for testing
export ALLOW_DUMMY_PRINTER=true
python -m kidfax.sms_pollerSee full troubleshooting guide in DEPLOYMENT.md
KID-FAX/
├── kidfax/ # Core Kid Fax module
│ ├── printer.py # Printer abstraction (USB/Serial/Network/Bluetooth)
│ ├── sms_poller.py # Twilio SMS polling service
│ ├── send_sms.py # CLI tool for sending replies
│ ├── interactive_keyboard.py # Interactive keyboard messaging mode
│ ├── keyboard_input.py # Keyboard event handling and F-key mapping
│ ├── eink_display.py # E-ink display utilities
│ ├── admin_web.py # Admin web interface (Flask)
│ ├── config_manager.py # .env file utilities
│ └── templates/
│ └── admin.html # Admin UI template
├── .env.example # Configuration template
├── requirements.txt # Python dependencies
├── QUICK_START.md # 15-minute setup guide
├── KEYBOARD_MODE.md # Interactive keyboard mode guide
├── ADMIN_WEB.md # Admin web interface guide
├── TWILIO_SETUP.md # Twilio configuration
├── SYSTEMD_SETUP.md # Auto-start service setup
├── DEPLOYMENT.md # Complete deployment guide
├── SETUP_BLUETOOTH.md # Bluetooth printer setup
└── CONFIGURE_BLUETOOTH_PRINTER.md
See SETUP_BLUETOOTH.md and CONFIGURE_BLUETOOTH_PRINTER.md
Configure optional status display:
EINK_STATUS_ENABLED=true
EINK_DRIVER_PACKAGE=e-Paper.RaspberryPi_JetsonNano.python.lib.waveshare_epd
EINK_DRIVER_MODULE=epd2in9dRequires Waveshare e-Paper library installed.
Kid Fax supports:
- USB - Plug and play (most common)
- Serial/TTL - GPIO pins (Adafruit Mini)
- Network - WiFi/Ethernet printers
- Bluetooth - Wireless printers
- Dummy - Testing without hardware
See DEPLOYMENT.md for configuration details.
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Areas for contribution:
- Testing with different printer models
- E-ink display improvements
- MMS support (print images)
- Group messaging features
- Message scheduling
- Additional hardware integrations
See CHANGELOG.md for version history and migration guides.
This project is licensed under the MIT License - see LICENSE file for details.
- Built on python-escpos for printer support
- SMS powered by Twilio
- Inspired by the joy of receiving physical mail
- Created for kids who deserve magical communication experiences
- 📖 Documentation: Start with QUICK_START.md
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Made with ❤️ for kids and families who love staying connected
Note: As of v2.0.0, Kid Fax is focused exclusively on SMS mailbox functionality. The previous web ticket printing interface has been archived in archive/ directory.