{"id":51762764,"url":"https://github.com/sinamsv/nebula","last_synced_at":"2026-07-19T16:00:19.943Z","repository":{"id":339408715,"uuid":"1161795858","full_name":"sinamsv/Nebula","owner":"sinamsv","description":"an AI agent platform 🤖","archived":false,"fork":false,"pushed_at":"2026-07-19T14:55:24.000Z","size":408,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-19T16:00:18.338Z","etag":null,"topics":["admin-bot","ai","ai-admin","ai-agent","ai-agents","automation","bot","discord","discord-bot","discord-bot-ai","discord-py","python","telegram","telegrambot"],"latest_commit_sha":null,"homepage":"https://sinamsv.ir/projects/nebula","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sinamsv.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-19T14:27:17.000Z","updated_at":"2026-07-19T14:54:12.000Z","dependencies_parsed_at":"2026-02-19T18:03:01.457Z","dependency_job_id":null,"html_url":"https://github.com/sinamsv/Nebula","commit_stats":null,"previous_names":["sinamsv/nebulabot","sinamsv/nebula"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/sinamsv/Nebula","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinamsv%2FNebula","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinamsv%2FNebula/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinamsv%2FNebula/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinamsv%2FNebula/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sinamsv","download_url":"https://codeload.github.com/sinamsv/Nebula/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sinamsv%2FNebula/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35657585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-19T02:00:06.923Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin-bot","ai","ai-admin","ai-agent","ai-agents","automation","bot","discord","discord-bot","discord-bot-ai","discord-py","python","telegram","telegrambot"],"created_at":"2026-07-19T16:00:18.658Z","updated_at":"2026-07-19T16:00:19.752Z","avatar_url":"https://github.com/sinamsv.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nebula - AI-Powered Multi-Platform Assistant\n\n![Python Version](https://img.shields.io/badge/python-3.9+-blue)\n![Discord.py](https://img.shields.io/badge/discord.py-2.3+-blue)\n![python-telegram-bot](https://img.shields.io/badge/python--telegram--bot-21+-blue)\n![FastAPI](https://img.shields.io/badge/FastAPI-web%20panel-teal)\n[![Documentation](https://img.shields.io/badge/Docs-Documentation-blue)](./DOCUMENTATION.md)\n[![Migration](https://img.shields.io/badge/Guide-Migration-orange)](./MIGRATION_GUIDE.md)\n[![License](https://img.shields.io/badge/License-MIT-green)](./LICENSE.txt)\n\nNebula is an AI-powered assistant reachable from **Discord, Telegram, and a web panel**, sharing one account, one conversation memory, and one coin balance across whichever platform(s) you talk to it from. Ask it things, have it search the web, upload images for it to actually see (web), and — for admins on Discord — moderate your server, all through natural conversation.\n\n## ✨ Features\n\n### 🤖 AI-Powered Conversations\n- Natural language processing, model configurable via `AI_MODEL` across six providers (OpenAI, Anthropic, Google, xAI, OpenRouter, Groq)\n- Context-aware responses that remember previous conversations — **across platforms**, not just within one (Discord/Telegram) — or scoped to an individual chat (web's multi-chat mode)\n- Addresses users by their display name for personal engagement\n- Handles replies to messages intelligently, on Discord and Telegram\n- **Real image understanding on web**: attach an image to a web chat message and Nebula actually sees it, not just a placeholder note\n\n### 🌍 Multi-Platform, One Account\n- **Discord**: mention the bot in a server channel, or just DM it directly — no mention needed in DMs.\n- **Telegram**: message it directly in a private chat, or `@mention` it in a group.\n- **Web**: sign up or log in at the web panel, then chat directly — no mention needed, ever.\n- **One Nebula account, everywhere**: sign up once, then link additional platforms with `/sync` (Discord or web) instead of creating a separate account per platform.\n- Admin status, memory, and coin balance are all properties of your **Nebula account**, not any single platform.\n\n### 💬 Multiple Chats (Web Only)\n- Unlike Discord/Telegram (one continuous conversation per account), the web panel lets you keep multiple independently-named chats going at once.\n- Each web chat has its **own** 200,000-token memory capacity — separate from your shared Discord/Telegram history, and separate from your other web chats.\n- Create, rename, and delete chats freely; nothing you do in one chat affects another.\n\n### 🔗 Cross-Platform Account Linking (`/sync` + `/verify`)\nAlready have a Nebula account and want to use another platform too?\n1. On Discord (`/sync platform:telegram username:\u003cyour Nebula username\u003e`) or on the web panel's Platforms page — you'll get a one-time code.\n2. On Telegram: message the bot `/start` if you haven't already, then send `/verify username:\u003cyour Nebula username\u003e code:\u003cthe code\u003e`.\n3. Done — your memory and coin balance now carry over.\n\nCodes expire after 10 minutes and can only be used once. Linking is deliberately one-directional: Discord and the web panel can each *issue* a code; only Telegram *consumes* one via `/verify` today.\n\n### 👤 Accounts \u0026 Approval\n- Sign up on Discord (`/signup`), Telegram (`/signup username:\u003cn\u003e password:\u003cp\u003e`), or the web panel (a signup form) — pending admin approval by default.\n- Log in on any platform to link an existing account to a new platform identity directly.\n- **Sign in with Google** (web only): finds-or-creates a Nebula account from your Google account's email — entirely optional, not required for anything else to work.\n- The very first admin account is created via a one-time `ADMIN_BOOTSTRAP_KEY`, usable from Discord, Telegram, or the web signup form (whichever you use first); every admin after that is promoted with `/add_admin` (Discord) or approved/promoted from the web admin panel.\n\n### 💾 Memory Management\n- SQLite-backed conversation history, scoped to your Nebula account (Discord/Telegram) or to an individual web chat.\n- 200,000 token capacity per scope; new messages are refused with a clear message once full, rather than being silently dropped or auto-wiped.\n- `/memory_stats` and `/memory_reset` (Discord/Telegram) — available to any approved user, and apply to their own memory only. On web, deleting a chat (`DELETE /api/v1/chat/{id}`) is the equivalent \"start fresh\" action for that chat.\n\n### 🌝 Nebula Coin System (Rate Limiting)\n- **Starting Balance**: every account starts with **10 coins**, shared globally (not per-guild, per-chat, or per-platform).\n- **Consumption**: 1 coin per AI message, 2 coins per web search.\n- **Automatic Reset**: back to 10 (non-stacking) every 8 hours.\n- `/coin` (Discord/Telegram) or `GET /api/v1/users/me/coins` (web) to check your balance; `/add_coin` (Discord/Telegram, admin-only) or `POST /api/v1/users/{id}/coins` (web, admin-only) to grant or set someone's balance.\n\n### 🔍 Web Search Integration\n- Google Custom Search or Tavily (an AI-native search API) — pick one via `SEARCH_PROVIDER`\n- Available to all approved users, costs 2 Nebula Coins\n- Web users can toggle search off for an individual message (`{\"tools\": {\"search\": false}}`); Discord/Telegram always offer it\n- If the selected provider is misconfigured, search is disabled entirely (no silent fallback to the other provider) and admins are notified\n\n### 🛡️ Admin Tools\n- **Discord Only**: Kick, ban, and channel creation via natural-language AI request — inherently Discord Guild operations with no Telegram or web equivalent.\n- **User Activity Check** (Discord): cross-platform account activity and memory usage for any linked user.\n- **Admin Logs**: `/admin_logs` (Discord) — every admin action, across every platform, in one log.\n- **Account Approval**: available from Discord (`/approve_user`, `/pending_users`, `/add_admin`) **and** from the web admin panel (`GET /api/v1/admin/users/pending`, `POST /api/v1/admin/users/{id}/review`) — admin status is Nebula-level, so promoting/approving someone from either surface applies everywhere they're linked.\n\n### 🔐 Google OAuth (Infrastructure)\n- Web users can connect a Google account. Tokens are stored **encrypted** (not hashed — they need to be recoverable), via `cryptography`'s Fernet.\n- This is groundwork for future Google Sheets/Calendar tools — nothing uses these tokens yet, and connecting Google is entirely optional.\n\n## 📋 Prerequisites\n\n- Python 3.9 or higher\n- A Discord Bot Token, a Telegram Bot Token, a configured web adapter, or any combination (at least one is required)\n- An API key for at least one supported AI provider (OpenAI, Anthropic, Google, xAI, OpenRouter, or Groq)\n- Google Custom Search or Tavily API key (optional, for search functionality)\n- Google OAuth credentials (optional, only if you want to enable the web panel's \"Connect Google\" flow)\n\n## 🚀 Installation\n\n### 1. Clone or Download the Repository\n\n```bash\ngit clone https://github.com/sinamsv/Nebula\ncd Nebula\n```\n\n### 2. Install Dependencies\n\n```bash\npip install -r requirements.txt\n```\n\n### 3. Configure Environment Variables\n\n1. Copy `.env.sample` to `.env`:\n```bash\ncp .env.sample .env\n```\n\n2. Edit `.env` and fill in your credentials. At minimum, you need `AI_PROVIDER`, `AI_API_KEY`, `AI_MODEL`, `ADMIN_BOOTSTRAP_KEY`. Note that the **web panel is mandatory** and always active, while Discord and Telegram remain optional:\n\n```env\nDISCORD_TOKEN=your_discord_bot_token_here\nTELEGRAM_BOT_TOKEN=your_telegram_bot_token_here\nAI_PROVIDER=google\nAI_API_KEY=your_api_key_here\nAI_MODEL=gemini-2.0-flash-001\nADMIN_BOOTSTRAP_KEY=  # generate per the instructions in .env.sample\n```\n\n### 4. Get Your API Keys\n\n#### Discord Bot Token:\n1. Go to [Discord Developer Portal](https://discord.com/developers/applications)\n2. Create a new application → \"Bot\" section → \"Reset Token\" and copy it\n3. Enable these Privileged Gateway Intents: Server Members Intent, Message Content Intent\n\n#### Telegram Bot Token:\n1. Open a chat with [@BotFather](https://t.me/BotFather) on Telegram\n2. Send `/newbot` and follow the prompts (choose a name and a username ending in `bot`)\n3. BotFather gives you a token that looks like `123456789:AAExampleTokenTextGoesHere` — copy it into `TELEGRAM_BOT_TOKEN`\n\n#### Web Panel (Mandatory):\n1. The web adapter is a core system feature and is always active.\n2. Generate `JWT_SECRET`: `python3 -c \"import secrets; print(secrets.token_urlsafe(64))\"`\n3. Generate `OAUTH_TOKEN_ENCRYPTION_KEY`: `python3 -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"`\n4. (Optional) Fill in `GOOGLE_OAUTH_CLIENT_ID`/`SECRET`/`REDIRECT_URI` if you want to enable Google Sign-In/Connect — see [Google Cloud Console](https://console.cloud.google.com/apis/credentials).\n5. The API serves on `BACKEND_PORT` (default `8000`). Pair it with the Next.js frontend, pointed at this API's base URL.\n\nYou don't need all three adapters — set whichever platform(s) you actually want to run. Nebula starts every adapter it's configured for and skips the rest.\n\n#### AI Provider Key:\nNebula supports six AI providers, selected via `AI_PROVIDER`. Set `AI_API_KEY` to that provider's key, and `AI_MODEL` to a model string that provider recognizes:\n\n| `AI_PROVIDER` | Where to get a key | Example `AI_MODEL` |\n|---|---|---|\n| `openai` | [platform.openai.com](https://platform.openai.com/) | `gpt-5.2` |\n| `anthropic` | [console.anthropic.com](https://console.anthropic.com/) | `claude-sonnet-4-6` |\n| `google` | [Google AI Studio](https://aistudio.google.com/) | `gemini-3.1-pro-preview` |\n| `xai` | [console.x.ai](https://console.x.ai/) | `grok-4.3` |\n| `openrouter` | [openrouter.ai](https://openrouter.ai/) | `anthropic/claude-sonnet-4` |\n| `groq` | [console.groq.com](https://console.groq.com/) | `llama-3.3-70b-versatile` |\n\n`openai`, `anthropic`, and `google` talk to their official APIs directly. `xai`, `openrouter`, and `groq` are accessed as OpenAI-compatible endpoints — their base URLs are already configured for you in `ai/config.json`, no extra setup needed.\n\nIf you were using Nebula before this provider system existed, your old `OPENAI_API_KEY`/`OPENAI_BASE_URL` setup (e.g. pointed at Gemini) still works unchanged — see `.env.sample`'s deprecated section — but new setups should use `AI_PROVIDER` + `AI_API_KEY` instead.\n\n#### Google Custom Search / Tavily (Optional):\n- Google: [API Key](https://console.cloud.google.com/apis/credentials) + [Search Engine ID](https://programmablesearchengine.google.com/)\n- Tavily: get a key at [app.tavily.com](https://app.tavily.com/)\n\n### 5. Customize System Prompt (Optional)\n\nEdit `system.txt` to customize Nebula's personality and behavior — shared across every platform, including web.\n\n### 6. Run Nebula\n\n```bash\npython main.py\n```\n\nThis starts the entire multi-platform ecosystem (Discord, Telegram, Web API, and the Next.js Web UI frontend) concurrently under a single, unified Python process.\n\nOn startup, `main.py` automatically orchestrates:\n- Checking for missing or outdated Node.js dependencies in `web_frontend/` and running `npm install` automatically if needed.\n- Checking for the production build (`.next/`) and running `npm run build` automatically if it is missing.\n- Executing the frontend using `npm run start` (or `npm run dev` in local development if `NODE_ENV=development` is set).\n\nAll Next.js logs are forwarded and clearly prefixed directly to your Python console logs for easy debugging.\n\n## 🎯 Usage\n\n### Talking to Nebula\n\n**Discord:**\n```\n@Nebula what's the weather like?\n```\nOr just DM the bot directly — no mention needed there.\n\n**Telegram:**\n```\n[in a private chat with the bot] what's the weather like?\n```\nOr, in a group, `@mention` it the same way you would on Discord.\n\n**Web:**\nLog in at the web panel, open (or create) a chat, and just type — no mention needed, ever. Attach an image if you want Nebula to actually look at it.\n\n*Note: each response costs 1 Nebula Coin, shared across whichever platform(s) you use.*\n\n### Web API Quick Reference\n\n```bash\n# Sign up\ncurl -X POST http://localhost:8000/api/v1/auth/signup \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"username\": \"sina\", \"password\": \"a-strong-password\"}'\n\n# Create a chat (using the access_token from signup/login)\ncurl -X POST http://localhost:8000/api/v1/chat \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" -H \"Content-Type: application/json\" \\\n  -d '{\"title\": \"General\"}'\n\n# Send a message\ncurl -X POST http://localhost:8000/api/v1/chat/\u003cchat_id\u003e/messages \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" -H \"Content-Type: application/json\" \\\n  -d '{\"input\": \"hello Nebula!\", \"tools\": {\"search\": true}}'\n```\n\nSee DOCUMENTATION.md's \"Web Panel\" section for the full API surface.\n\n### Commands\n\n#### Discord (Slash Commands)\n| Command | Who | Description |\n|---|---|---|\n| `/signup` | Anyone | Create a Nebula account, linked to this Discord identity |\n| `/login` | Anyone | Link this Discord identity to an existing Nebula account |\n| `/sync` | Approved users | Generate a code to link another platform to this account |\n| `/coin` | Approved users | Show your Nebula Coin balance |\n| `/memory_stats` / `/memory_reset` | Approved users | View or clear your own memory |\n| `/add_coin` | Admin | Add to or set a user's coin balance |\n| `/approve_user` / `/pending_users` / `/add_admin` | Admin | Account approval and admin management |\n| `/admin_logs` | Admin | View recent admin action logs |\n\n#### Telegram\n| Command | Who | Description |\n|---|---|---|\n| `/start` | Anyone | Get started / see available commands |\n| `/signup username:\u003cn\u003e password:\u003cp\u003e` | Anyone | Create a Nebula account, linked to this Telegram identity |\n| `/login username:\u003cn\u003e password:\u003cp\u003e` | Anyone | Link this Telegram identity to an existing Nebula account |\n| `/verify username:\u003cn\u003e code:\u003cc\u003e` | Anyone | Complete a `/sync` started on Discord or the web panel |\n| `/coin` | Approved users | Show your Nebula Coin balance |\n| `/memory_stats` / `/memory_reset` | Approved users | View or clear your own memory |\n| `/add_coin username:\u003cn\u003e amount:\u003ca\u003e mode:\u003cadd\\|set\u003e` | Admin | Add to or set a user's coin balance |\n\n#### Web (HTTP API, see DOCUMENTATION.md for the full list)\n| Endpoint | Who | Description |\n|---|---|---|\n| `POST /api/v1/auth/signup`, `/login` | Anyone | Create/access a Nebula account from the browser |\n| `GET /api/v1/auth/google`, `/google/callback` | Anyone | Sign in / connect with Google |\n| `GET`/`POST /api/v1/chat` | Approved | List / create chats |\n| `POST /api/v1/chat/{id}/messages(/image)` | Approved | Chat with Nebula, optionally with an image |\n| `POST /api/v1/sync/{platform}` | Approved | Generate a code to link Discord or Telegram |\n| `GET /api/v1/users/me/coins` | Approved | Your own coin balance |\n| `GET /api/v1/admin/users/pending`, `POST /api/v1/admin/users/{id}/review` | Admin | Review pending signups |\n\nAdmin moderation commands (kick, ban, create channel) remain Discord-only today.\n\n### AI-Powered Admin Tools (Discord, Administrators Only)\n\n```\n@Nebula kick @username for spamming\n@Nebula ban @username for violating rules\n@Nebula create a text channel called \"general-chat\" in the \"Community\" category\n@Nebula check activity for @username\n```\n\n## 🏗️ Project Structure\n\n```\nnebula/\n├── main.py                    # Launcher: builds shared core instances, runs every configured adapter\n├── system.txt                 # AI system prompt (shared across every platform)\n├── requirements.txt\n├── .env.sample\n├── core/                      # Platform-agnostic business logic\n│   ├── database.py            #   SQLite layer: nebula_users, platform_identities, memory, coins, sync codes, admin log, chats, oauth_connections\n│   ├── auth.py                #   Signup/login/approval + cross-platform account sync\n│   ├── memory.py              #   Per-account (or per-web-chat) conversation memory, 200k token cap\n│   ├── coins.py                #   Nebula Coin balance/spend/reset logic\n│   └── crypto.py              #   Fernet encryption for OAuth tokens at rest\n├── ai/\n│   ├── handler.py             # Platform-agnostic conversation turn handling (model calls, tool dispatch, multimodal)\n│   ├── config.json            # Per-provider base_url/temperature/thinking_level settings\n│   └── providers/              # One file per AI SDK, normalized behind a shared interface (multimodal-capable)\n│       ├── base.py             #   BaseProvider, NormalizedResponse, NormalizedToolCall, ImageAttachment\n│       ├── openai_sdk.py       #   OpenAI + xAI + OpenRouter + Groq\n│       ├── anthropic_sdk.py    #   Anthropic\n│       └── google_sdk.py       #   Google Gemini\n├── tools/                     # AI-callable tools\n│   ├── search.py               #   Platform-agnostic (Google / Tavily)\n│   └── moderation.py           #   Discord-only (kick/ban/create_channel need a discord.Guild)\n├── discord_bot/                # Discord adapter\n├── telegram_bot/                # Telegram adapter\n└── web_backend/                 # Web adapter (FastAPI) -- thin, mirrors discord_bot/telegram_bot's structure\n    ├── app.py                   #   FastAPI app factory\n    ├── security.py               #   JWT issue/validate\n    ├── dependencies.py            #   Shared-instance + identity dependency injection\n    ├── schemas/                   #   Pydantic request/response models\n    └── routes/                    #   auth.py, chat.py, coins.py, sync.py, admin.py\n```\n\n## 🗄️ Database Schema\n\nSchema is organized around **Nebula accounts**, not guilds, channels, or web sessions — this is what makes cross-platform identity, memory, and coin balances work.\n\n| Table | Purpose |\n|---|---|\n| `nebula_users` | A Nebula account: username, password hash, display name, admin/approval status |\n| `platform_identities` | Links a platform-specific ID (Discord user ID, Telegram user ID, web session, Google email) to a `nebula_user_id`. One account can have many platform identities. |\n| `platform_sync_codes` | One-time codes for the `/sync` (Discord or web) → `/verify` (Telegram) account-linking flow |\n| `chats` | **(New in 1.5.0)** Web-only: one row per named chat, scoped to a `nebula_user_id` |\n| `conversation_history` | Memory. `chat_id IS NULL` = legacy account-wide history (Discord/Telegram); `chat_id = \u003cint\u003e` = scoped to one web chat |\n| `coin_balances` | Nebula Coin balance and reset timer, per `nebula_user_id`, global across platforms |\n| `oauth_connections` | **(New in 1.5.0)** Encrypted OAuth tokens (Google), per `(nebula_user_id, provider)` |\n| `admin_actions_log` | Every admin action, across every platform |\n| `bootstrap_state` | Tracks whether the one-time `ADMIN_BOOTSTRAP_KEY` has been claimed |\n| `server_settings` | Discord-specific, legacy per-guild settings |\n\n## ⚙️ Configuration\n\n### Memory Management\n- **Max Tokens**: 200,000 per scope — one shared scope per Nebula account for Discord/Telegram, one independent scope per web chat.\n- **Hard cap, not auto-reset**.\n- **Token Counting**: `tiktoken`.\n\n### AI Configuration\n- **Provider**: set via `AI_PROVIDER` + `AI_API_KEY`. See `ai/config.json` for per-provider `base_url`/`temperature`/`thinking_level` settings.\n- **Model**: set via `AI_MODEL`.\n- **Max Tokens**: 2000 per response.\n- **Multimodal images**: web-only, real forwarding to the model (not a text placeholder) — see DOCUMENTATION.md.\n- **Legacy config**: `OPENAI_API_KEY` + `OPENAI_BASE_URL` still works if set, but is deprecated.\n\n### Message Handling\n- **Discord**: 2000-character limit, auto-split.\n- **Telegram**: 4096-character limit, auto-split.\n- **Web**: no artificial split — JSON response bodies, rendered by the frontend as-is.\n\n### Web Panel\n- `BACKEND_PORT`, `FRONTEND_PORT`, `WEB_FRONTEND_URL`, `JWT_SECRET`, `OAUTH_TOKEN_ENCRYPTION_KEY` — see `.env.sample`.\n- Google OAuth (optional): `GOOGLE_OAUTH_CLIENT_ID`, `GOOGLE_OAUTH_CLIENT_SECRET`, `GOOGLE_OAUTH_REDIRECT_URI`.\n\n## 🔒 Permissions Required\n\n**Discord**: Read Messages/View Channels, Send Messages, Manage Messages, Embed Links, Read Message History, Kick Members, Ban Members, Manage Channels.\n\n**Telegram**: no special bot permissions needed for private chats. For group use, disable Privacy Mode via BotFather's `/setprivacy` if you want it to see un-mentioned messages.\n\n**Web**: none beyond normal HTTPS network access to wherever you deploy the API and frontend.\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.\n\n## 📄 License\n\nMIT License\n\n---\n\n**Enjoy using Nebula! 🌟**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinamsv%2Fnebula","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsinamsv%2Fnebula","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsinamsv%2Fnebula/lists"}