A local Discord Bot pipeline to turn your doom scrolling into an Obsidian knowledge base.
- Motivation: The Saved Collections feature in Instagram is so hidden and disorganized that I've resorted to sharing links of Instagram reels in my private Discord server, in hopes of referring to them later on... Of course, this was rarely the case. I would end up lost in a sea of links, which were supposed to be organized categories, frantically trying to find a tutorial about Photoshop, a movie recommendation, or even a recipe.
- Outcome: This eventually inspired NORA, a way to summarize what's in those reels into a structured, interconnected Obsidian vault.
- Non-goals: NORA is not a full social archive, hosted backup service, or guaranteed legal/compliance layer for third-party content — you own your vault and tooling choices.
- Expansion: Despite the local limitations, you're free to build on top of this architecture—hosting, sync, extra automation, different models, or anything else your workflow needs.
Goal: run the bot on your PC so Discord slash commands (e.g. /save, /saveall) run the pipeline and write notes into a folder you choose (typically an Obsidian vault). Use NORA-open or any clone; remember to keep .env and your vault off GitHub.
Who gets the files: markdown and assets are written only on the machine that runs bot.py, under OBSIDIAN_VAULT_PATH. Everyone else in the server sees Discord replies (paths, errors, progress)—not your vault—unless you share that folder yourself (sync, git, network drive, etc.). Details: docs/setup.md#shared-servers-where-notes-live.
| Requirement | Why |
|---|---|
| Python 3.10+ | Runs the bot and pipeline |
| ffmpeg on your PATH | Extracts audio from reels (ffmpeg -version should work) |
| A Discord bot | Slash commands and replies |
| A folder for notes | OBSIDIAN_VAULT_PATH — vault root folder (the one that contains or will contain Instagram Notes/, not the .obsidian folder) |
| An LLM (pick one) | OpenRouter (API key, optional free models) or Ollama (local, no OpenRouter key) |
First run will download Whisper weights and can take a few minutes. Optional extras (OCR, stronger models): docs/setup.md.
Note: By default, “visual” context is keyframes + Tesseract OCR—the LLM gets OCR text in its prompts, not images through a vision model, so results can be thin or noisy on busy or stylized reels. Install Tesseract for that path (see docs/setup.md); disable it with VISUAL_CONTEXT_ENABLED=false in .env (docs/configuration.md#visual-keyframes-and-ocr). Limits and improvement options: docs/stack-and-costs.md#keyframes-and-ocr-limits-and-improvements.
git clone https://github.com/dariodaddamio/NORA-open.git
cd NORA-open
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
Copy-Item .env.example .env(On macOS/Linux, use source .venv/bin/activate instead of Activate.ps1.)
- Open the Discord Developer Portal → New Application → name it → open Bot → Add Bot → under Token, Reset Token and copy it (this value is
DISCORD_TOKENin.env). Never commit it. - In Bot, enable Message Content Intent (needed for
/saveallchannel scans). - Open OAuth2 → URL Generator: scopes
botandapplications.commands. Choose bot permissions (at minimum: View Channels, Send Messages, Read Message History). Open the generated URL, pick your server, invite the bot.
Screenshots, re-invite, and permission detail: docs/setup.md.
Create or choose a folder (e.g. C:\Users\you\Documents\MyVault). Put its absolute path in .env as OBSIDIAN_VAULT_PATH. The bot will create Instagram Notes/ and related folders there on first success.
Option A — OpenRouter (cloud, includes free models)
- Sign up at openrouter.ai, then open Keys and create an API key.
- In
.env, setOPENROUTER_API_KEY=to that key (no quotes needed unless your editor adds them). - Leave
OPENROUTER_MODEL=openrouter/freeto start (free-tier availability changes over time; you can swap the id for any model listed on OpenRouter). Billing and limits are on their site.
Option B — Ollama (local, no OpenRouter)
- Install Ollama and pull a model, e.g.
ollama pull llama3.1. - In
.env, leaveOPENROUTER_API_KEYempty (or delete the value after the=). - Set
OLLAMA_MODELto match what you pulled (e.g.llama3.1; the pipeline normalizes tollama3.1:latestwhen needed). Keep Ollama running while you use the bot.
More on cost vs privacy: docs/stack-and-costs.md. All env vars: docs/configuration.md.
.\.venv\Scripts\python bot.pyWait until the process stays running with no traceback. Slash commands can take ~30–60s after startup to appear in Discord.
In your server, run /save and paste an Instagram reel URL, or /saveall in a channel to scan history. If something fails, start with docs/troubleshooting.md.
| Doc | What it covers |
|---|---|
| docs/setup.md | Prerequisites, install, Discord portal detail, run, multi-device |
| docs/how-it-works.md | High-level flow diagrams; link into the pipeline |
| docs/architecture.md | Pipeline stages, gates, LLM stages, idempotency, temp |
| docs/configuration.md | Environment variables, discrete modes (TITLE_STYLE, pipeline, OCR), tuning notes |
| docs/vault-output.md | Vault folders, note sections, frontmatter, taxonomy |
| docs/stack-and-costs.md | Local vs cloud LLM, cost tiers, OCR limits vs real vision, extension points |
| docs/open-private-workspace.md | NORA-open vs private workspace, mirror excludes, staying safe |
| docs/extending.md | Where to hook code and main files |
| docs/troubleshooting.md | Common failures and quality tuning |
Index: docs/README.md
Issues and ideas: NORA-open issues — bug reports and feature suggestions welcome there.
License: MIT · Contributing: CONTRIBUTING.md · Code of conduct: CODE_OF_CONDUCT.md