A privacy-first personal note-taking system with Telegram bot integration, voice transcription, and calendar sync. Runs on a Raspberry Pi — no cloud required.
We live in an interesting time when producing code has become incredibly cheap. You can vibe-code any solution and solve your problem. This project is my personal answer to the shortcomings of modern information capture and storage systems. My current setup is a home server running on a Raspberry Pi where I keep all my notes. I have tried plenty of tools — Evernote, Obsidian, and others. They are great products, but I wanted more flexibility for my specific workflows. So I vibe-coded my own. If it turns out to be useful for someone else, I will consider the world a tiny bit better.
- Telegram Bot -- capture notes, voice messages, photos, and files from Telegram
- Voice Transcription -- local audio-to-text via Parakeet v3 (no cloud API, 25 languages)
- Audio Recording -- record voice notes directly in the browser, auto-transcribed
- Google Calendar Sync -- import events and get reminders via Telegram
- Tags -- organize documents and tasks with a flexible tagging system
- Tasks -- simple task management with due dates
- Markdown Editor -- write and preview Markdown with live toggle
- Search -- full-text search across all documents
- Privacy -- everything stays on your hardware, single-user design
| Dashboard | Documents |
|---|---|
![]() |
![]() |
| Tasks | Calendar |
|---|---|
![]() |
![]() |
| Component | Technology |
|---|---|
| Backend | Ruby on Rails 8.1 |
| Database | SQLite3 |
| Frontend | Stimulus.js, Tailwind CSS |
| Asset Pipeline | Propshaft, esbuild, cssbundling-rails |
| Background Jobs | SolidQueue / Sidekiq |
| Transcription | Parakeet v3 / onnx-asr (Python) |
| Containers | Docker Compose |
| Testing | RSpec, FactoryBot, SimpleCov |
- Docker and Docker Compose
- A Telegram bot token (from @BotFather)
git clone https://github.com/yourusername/inbox.git
cd inbox
# Create environment file
cp .env.example .envEdit .env and fill in your values:
SECRET_KEY_BASE=$(openssl rand -hex 64)
TELEGRAM_BOT_TOKEN=your_bot_token_from_botfather
TELEGRAM_BOT_NAME=your_bot_name
TELEGRAM_ALLOWED_USER_ID=your_telegram_user_id
TELEGRAM_WEBHOOK_URL=https://your-domain.com/api/telegram/webhookTip: To find your Telegram user ID, send a message to @userinfobot.
mkdir -p secrets
echo "your_bot_token" > secrets/telegram_bot_token
openssl rand -hex 32 > secrets/telegram_webhook_secret_token
chmod 600 secrets/*docker compose build
docker compose run --rm web bin/rails db:create db:migrate
docker compose up -dBOT_TOKEN=$(cat secrets/telegram_bot_token)
SECRET_TOKEN=$(cat secrets/telegram_webhook_secret_token)
curl -X POST "https://api.telegram.org/bot${BOT_TOKEN}/setWebhook" \
-H "Content-Type: application/json" \
-d "{\"url\": \"https://your-domain.com/api/telegram/webhook\", \"secret_token\": \"${SECRET_TOKEN}\"}"Navigate to http://localhost:3000 (or your domain if deployed).
- Ruby 3.3+ (via asdf, rbenv, or rvm)
- Node.js 22+
- pnpm
- SQLite3 3.43+
# Install dependencies
bundle install
pnpm install
# Setup database
bin/rails db:create db:migrate db:seed
# Build assets
pnpm run build
pnpm run build:css
# Start development server
bin/devbundle exec rspec # Full test suite
bin/rubocop # Code style
bin/brakeman --no-pager # Security scan| Variable | Required | Description |
|---|---|---|
SECRET_KEY_BASE |
Yes | Rails secret key (generate with openssl rand -hex 64) |
TELEGRAM_BOT_TOKEN |
Yes | Bot token from BotFather |
TELEGRAM_BOT_NAME |
Yes | Bot username (without @) |
TELEGRAM_ALLOWED_USER_ID |
Yes | Your Telegram user ID |
TELEGRAM_WEBHOOK_URL |
Yes | Public URL for webhook |
API_TOKEN |
No | Token for API authentication |
GIT_SHA |
No | Git commit SHA, baked at build time for version tracking |
TRANSCRIBER_URL |
No | Transcription service URL (default: http://transcriber:5000) |
TRANSCRIBER_LANGUAGE |
No | Force transcription language (default: auto-detect) |
GOOGLE_CLIENT_ID |
No | For Google Calendar sync |
GOOGLE_CLIENT_SECRET |
No | For Google Calendar sync |
GOOGLE_REFRESH_TOKEN |
No | For Google Calendar sync |
GOOGLE_CALENDAR_IDS |
No | Comma-separated calendar IDs (default: primary) |
Inbox collects information from multiple sources, processes it in the background, and presents everything through a clean web interface.
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Telegram Bot │ │ Google Calendar │ │ Web Editor │
│ text / voice / files│ │ OAuth / RPi sync │ │ web / quick capture │
└─────────┬───────────┘ └─────────┬───────────┘ └─────────┬───────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Webhook │ │ GCal Sync Job │ │ Rails Controller │
│ POST /api/telegram │ │ Sidekiq / cron │ │ Form / Turbo │
└─────────┬───────────┘ └─────────┬───────────┘ └─────────┬───────────┘
│ │ │
└────────────┬────────────┘──────────────────────────┘
▼
┌───────────────────────┐
│ SQLite Database │
│ documents · tasks │
│ calendar_events · tags │
└───────────┬───────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Parakeet v3 │ │ Redis │ │ Google │
│ Transcription │ │ Cache │ │ Cal API │
│ (local, CPU) │ │ + Queue │ │ (OAuth) │
└──────────────┘ └──────────┘ └──────────┘
- Capture -- Send a text message, voice note, photo, or file to your Telegram bot. Type directly in the web editor, or record audio from the browser.
- Process -- Voice messages are transcribed locally by Parakeet v3 with automatic punctuation and capitalization. All messages are saved as notes.
- Store -- Everything lands in SQLite as a document with Markdown content. Tasks get due dates and priorities. Calendar events sync from Google.
- Organize — Tag documents and tasks. Pin important notes. Filter by source, tag, or date.
- Access — Browse, search, and edit from any device through the web UI. Protected by HTTP Basic Auth over HTTPS.
For production deployment on a Raspberry Pi with Docker Compose, nginx, and WireGuard VPN, see the Deployment Quickstart.
See CONTRIBUTING.md for development setup, code style, and PR guidelines.
This project is licensed under the MIT License — see the LICENSE file for details.
If you find Inbox useful, consider supporting development via GitHub Sponsors.



