{"id":13622297,"url":"https://github.com/nullabork/talkbot","last_synced_at":"2026-07-04T04:12:15.190Z","repository":{"id":53019502,"uuid":"127360873","full_name":"nullabork/talkbot","owner":"nullabork","description":"Text-to-speech and translation bot for Discord","archived":false,"fork":false,"pushed_at":"2026-04-05T06:58:26.000Z","size":14030,"stargazers_count":31,"open_issues_count":8,"forks_count":23,"subscribers_count":6,"default_branch":"v2","last_synced_at":"2026-04-05T08:24:31.211Z","etag":null,"topics":["bot","discord","discord-bot","language-translation","text-to-speech","tts","voice-channel"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/nullabork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"patreon":"talkbot"}},"created_at":"2018-03-30T00:23:18.000Z","updated_at":"2026-04-05T06:58:16.000Z","dependencies_parsed_at":"2024-06-12T04:37:33.252Z","dependency_job_id":"bacdb15b-6f84-4697-8d70-94bd94df04c2","html_url":"https://github.com/nullabork/talkbot","commit_stats":null,"previous_names":[],"tags_count":90,"template":false,"template_full_name":null,"purl":"pkg:github/nullabork/talkbot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullabork%2Ftalkbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullabork%2Ftalkbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullabork%2Ftalkbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullabork%2Ftalkbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nullabork","download_url":"https://codeload.github.com/nullabork/talkbot/tar.gz/refs/heads/v2","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nullabork%2Ftalkbot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35109331,"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-04T02:00:05.987Z","response_time":113,"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":["bot","discord","discord-bot","language-translation","text-to-speech","tts","voice-channel"],"created_at":"2024-08-01T21:01:17.317Z","updated_at":"2026-07-04T04:12:15.183Z","avatar_url":"https://github.com/nullabork.png","language":"TypeScript","funding_links":["https://patreon.com/talkbot"],"categories":["JavaScript","TypeScript"],"sub_categories":[],"readme":"# TalkBot - Discord Text-to-Speech Bot\n\nTalkBot reads Discord text channel messages aloud in voice channels. Type a message and the bot speaks it. Supports multiple voice providers, per-user voice customization, and works on any server.\n\n\u003e **This is v2** — a major rewrite of TalkBot. The codebase has been migrated to TypeScript, all secrets moved to `.env`, and Docker startup has changed. A new [local TTS provider (Kokoro)](#kokoro-local--no-cloud-api-key-needed) has been added — no cloud API keys needed, runs on your machine. If you were running v1 and want to upgrade, see [Migrating to v2](#migrating-to-v2). If you need the old version, switch to the `master` branch on GitHub (click **Branch: v2** at the top of the repo and select `master`).\n\n---\n\n## Table of Contents\n\n- [What You Need](#what-you-need)\n- [Download](#download)\n- [Quick Start (Docker)](#quick-start-docker)\n- [Migrating to v2](#migrating-to-v2)\n- [Quick Start (No Docker)](#quick-start-no-docker)\n- [Discord Setup](#discord-setup)\n- [TTS Providers](#tts-providers)\n- [Commands](#commands)\n- [Environment Variables Reference](#environment-variables-reference)\n- [Setup on Coolify](#setup-on-coolify)\n- [Local Development](#local-development)\n- [Project Structure](#project-structure)\n- [Troubleshooting](#troubleshooting)\n- [Acknowledgements](#acknowledgements)\n\n---\n\n## What You Need\n\n1. **A Discord bot token** — free from the [Discord Developer Portal](https://discord.com/developers/applications) (see [Discord Setup](#discord-setup))\n2. **API credentials for a TTS (text-to-speech) service** — at least one. Amazon Polly is the easiest to start with (see [TTS Providers](#tts-providers)). Or skip the cloud APIs entirely and run a [local TTS model (Kokoro)](https://github.com/remsky/Kokoro-FastAPI) if you have spare CPU/GPU resources\n3. **A place to run the bot** — your own computer, a VPS, or a hosting service like [Coolify](#setup-on-coolify)\n\n---\n\n## Download\n\n**Option A — Download as ZIP (no git required):**\n\n1. Click the green **Code** button at the top of this page\n2. Click **Download ZIP**\n3. Extract the ZIP to a folder on your computer\n\n**Option B — Clone with git:**\n```bash\ngit clone https://github.com/nullabork/talkbot.git\ncd talkbot\n```\n\n---\n\n## Quick Start (Docker)\n\n[Docker](https://www.docker.com/get-started/) packages the bot and everything it needs into a container so you don't have to install Node.js or manage dependencies. If you don't have Docker, see [Quick Start (No Docker)](#quick-start-no-docker) instead.\n\n1. **Install Docker** if you don't have it: [docker.com/get-started](https://www.docker.com/get-started/)\n\n2. **Open a terminal** in the talkbot folder.\n\n3. **Create your settings file:**\n   - Copy the file `.env.example` and rename the copy to `.env`\n   - Open `.env` in a text editor (Notepad, VS Code, etc.)\n   - Paste your Discord bot token after `DISCORD_TOKEN=`\n   - Paste your TTS provider credentials (see [TTS Providers](#tts-providers)), or skip cloud APIs and use the [local Kokoro model](#kokoro-local--no-cloud-api-key-needed) instead\n\n4. **Start the bot:**\n   ```bash\n   # Mac / Linux:\n   ./docker-start.sh\n\n   # Windows:\n   docker-start.cmd\n   ```\n   The start script reads your `.env` and launches the right containers automatically (including Kokoro TTS if enabled). If Kokoro hasn't been downloaded yet, it will prompt you first.\n\n5. **Check it's working:**\n   ```bash\n   ./docker-start.sh logs        # Mac / Linux\n   docker-start.cmd logs         # Windows\n   ```\n   You should see `Loaded the \u003cProvider\u003e TTS API credentials OK.` and then the bot logging into Discord. Press Ctrl+C to stop watching logs (the bot keeps running).\n\n**To stop the bot:**\n- Mac / Linux: `./docker-start.sh down`\n- Windows: `docker-start.cmd down`\n\n**To restart after changes:**\n- Mac / Linux: `./docker-start.sh restart`\n- Windows: `docker-start.cmd restart`\n\n---\n\n## Migrating to v2\n\nIf you had TalkBot running before, here's what changed and how to upgrade.\n\n### What's different\n\n- **All secrets and settings are now in `.env`** — `config/auth.json` and the TTS settings from `config/config.json` are gone. Everything is in one file.\n- **Docker startup changed** — instead of `docker compose up -d`, use the start scripts (`docker-start.sh` or `docker-start.cmd`). They read your `.env` and launch the right containers automatically.\n- **TTS providers are enabled in `.env`** — set `TTS_AMAZON_ENABLED=true` (or whichever provider you use) instead of editing `config.json`.\n- **New local TTS option** — Kokoro runs a TTS model on your machine, no cloud API keys needed.\n\n### Step by step\n\n1. **Pull the latest code:**\n   ```bash\n   git pull\n   git checkout v2\n   ```\n   Or re-download the ZIP from GitHub (make sure the branch says `v2`).\n\n2. **Create your `.env` file** — copy `.env.example` to `.env`, then move your credentials across:\n\n   | Old location (`auth.json` / `config.json`) | New location (`.env`) |\n   |---|---|\n   | `bot_token` | `DISCORD_TOKEN` |\n   | `client_id` | `CLIENT_ID` |\n   | `dev_ids` (array) | `DEV_IDS` (comma-separated) |\n   | `command_char` | `COMMAND_CHAR` |\n   | Amazon `accessKeyId` | `AWS_ACCESS_KEY_ID` |\n   | Amazon `secretAccessKey` | `AWS_SECRET_ACCESS_KEY` |\n   | Azure `subscriptionKey` | `AZURE_SUBSCRIPTION_KEY` |\n   | Watson `apikey` | `WATSON_API_KEY` |\n   | Watson `serviceUrl` | `WATSON_SERVICE_URL` |\n   | `tts.amazon.enabled: true` | `TTS_AMAZON_ENABLED=true` |\n\n3. **Start the bot:**\n   ```bash\n   # Mac / Linux:\n   ./docker-start.sh\n\n   # Windows:\n   docker-start.cmd\n   ```\n\n4. **Delete `auth.json`** — it's no longer used.\n\nYour `.server` files (per-guild state in `config/`) are unchanged and will continue to work. Voice settings, permissions, and sound effects are all preserved.\n\n---\n\n## Quick Start (No Docker)\n\nIf you'd rather run the bot directly on your computer without Docker.\n\n1. **Install Node.js 22 or newer** from [nodejs.org](https://nodejs.org/) — download the LTS version.\n\n2. **Open a terminal** in the talkbot folder.\n\n3. **Install dependencies:**\n   ```bash\n   npm install\n   ```\n\n4. **Create your settings file:**\n   - Copy `.env.example` and rename the copy to `.env`\n   - Open `.env` in a text editor and add your Discord bot token and TTS credentials\n\n5. **Build and start:**\n   ```bash\n   npm run build\n   npm start\n   ```\n\nThe bot will start and connect to Discord. To stop it, press Ctrl+C.\n\n---\n\n## Discord Setup\n\n1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and create a new application.\n2. Under **Bot**, create a bot and copy the token → paste into `DISCORD_TOKEN` in `.env`.\n3. Under **Bot \u003e Privileged Gateway Intents**, enable:\n   - **Message Content Intent** (required — the bot reads message text for TTS)\n   - **Server Members Intent** (optional, for member lookups)\n4. Under **OAuth2 \u003e URL Generator**, select:\n   - Scopes: `bot`\n   - Permissions: Send Messages, Connect, Speak, Manage Messages\n5. Use the generated URL to invite the bot to your server.\n\n---\n\n## TTS Providers\n\nYou need at least one provider enabled. Set the API credentials and `TTS_\u003cPROVIDER\u003e_ENABLED=true` in `.env`.\n\n### Amazon Polly (recommended starter)\n\n1. Create an [IAM user](https://docs.aws.amazon.com/polly/latest/dg/get-started-what-is.html) with `polly:SynthesizeSpeech` and `polly:DescribeVoices` permissions.\n2. Add to `.env`:\n   ```\n   AWS_ACCESS_KEY_ID=your_key\n   AWS_SECRET_ACCESS_KEY=your_secret\n   AWS_REGION=us-east-1\n   TTS_AMAZON_ENABLED=true\n   ```\n\n### Google Cloud TTS\n\n1. Create a [service account](https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries) and download the JSON key file.\n2. Place the key file in `config/google-auth.json`.\n3. Add to `.env`:\n   ```\n   GOOGLE_APPLICATION_CREDENTIALS=./config/google-auth.json\n   TTS_GOOGLE_ENABLED=true\n   ```\n\n### Azure Cognitive Services\n\n1. Create a [Speech resource](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/) in the Azure portal.\n2. Add to `.env`:\n   ```\n   AZURE_SUBSCRIPTION_KEY=your_key\n   AZURE_ENDPOINT=https://eastus.tts.speech.microsoft.com/\n   TTS_AZURE_ENABLED=true\n   ```\n\n### IBM Watson\n\n1. Create a [Text to Speech](https://cloud.ibm.com/catalog/services/text-to-speech) service instance.\n2. Add to `.env`:\n   ```\n   WATSON_API_KEY=your_key\n   WATSON_SERVICE_URL=https://api.au-syd.text-to-speech.watson.cloud.ibm.com/instances/your-guid\n   TTS_WATSON_ENABLED=true\n   ```\n\n### Tencent Cloud\n\n1. Create API credentials in the [Tencent Cloud console](https://cloud.tencent.com/product/tts).\n2. Add to `.env`:\n   ```\n   TENCENT_ACCESS_KEY_ID=your_key\n   TENCENT_SECRET_ACCESS_KEY=your_secret\n   TTS_TENCENT_ENABLED=true\n   ```\n\n### Alibaba Cloud (currently disabled)\n\nThe Alibaba provider is non-functional due to missing audio processing dependencies. It is hardcoded to `enabled: false`.\n\n### Kokoro (local — no cloud API key needed)\n\nRuns a local TTS model via [Kokoro-FastAPI](https://github.com/remsky/Kokoro-FastAPI). No API keys required — the model runs on your machine. The first startup downloads the model image (~4GB) and may take 5-20 minutes depending on your internet speed. Only CPU mode has been tested so far — GPU mode should work with NVIDIA hardware but is experimental.\n\n1. Add to `.env`:\n   ```\n   TTS_KOKORO_ENABLED=true\n   KOKORO_DEVICE=cpu\n   ```\n   Set `KOKORO_DEVICE=gpu` if you have an NVIDIA GPU with [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) installed.\n\n2. Start everything:\n   ```bash\n   ./docker-start.sh          # Mac / Linux\n   docker-start.cmd           # Windows\n   ```\n   The start script reads your `.env` and automatically launches the Kokoro container alongside the bot. On first run it will prompt to confirm the ~4GB model download.\n\n---\n\n## Commands\n\nTalkBot uses prefix commands (default `!`). Type `!help` in any text channel the bot can see.\n\n### Getting Started\n1. Join a voice channel\n2. Type `!follow` — the bot joins your channel\n3. Type any message — the bot reads it aloud\n4. Type `!unfollow` when done\n\n### Control\n| Command | Description |\n|---------|-------------|\n| `!follow` | Bot joins your voice channel |\n| `!unfollow` | Bot leaves voice channel |\n| `!tts \u003cmessage\u003e` | Force the bot to speak a message |\n| `!stop` | Stop current playback |\n| `!mute [@user]` | Mute yourself or someone else |\n| `!unmute [@user]` | Unmute yourself or someone else |\n| `!sidle` | Take over as bot master |\n| `!transfer @user` | Transfer master to someone else |\n\n### Personalization\n| Command | Description |\n|---------|-------------|\n| `!myvoice \u003cvoice\u003e` | Set your TTS voice (`provider/voice` or just `voice`) |\n| `!mypitch \u003c-20..20\u003e` | Set voice pitch |\n| `!myspeed \u003c0.25..4\u003e` | Set voice speed |\n| `!tolang \u003clang\u003e` | Translate your text (e.g. `en`, `fr`, `de`) |\n| `!defaults` | Reset all your voice settings |\n| `!mytitle \u003ctitle\u003e` | Set your display title |\n| `!puberty on\\|off` | Toggle random pitch/speed per message |\n| `!announceme on\\|off` | Toggle join/leave voice announcements |\n| `!myprefix set \u003ctext\u003e` | Prepend text before your messages |\n| `!mysuffix set \u003ctext\u003e` | Append text after your messages |\n\n### Info\n| Command | Description |\n|---------|-------------|\n| `!help` | Show all commands |\n| `!help \u003cgroup\u003e` | Show commands for a group (control, personalization, info, server) |\n| `!ping` | Check if the bot is alive |\n| `!who` | Show master and permitted users |\n| `!voices` | Browse voices — pick provider, language, see voice list |\n| `!voices set` | Set your voice via interactive dropdowns |\n| `!voices samples` | Open the online voice sample database |\n| `!details [@user]` | Show voice settings |\n| `!stats` | Show server TTS usage statistics |\n| `!invite` | Get the bot invite link |\n\n### Server Administration\n| Command | Description |\n|---------|-------------|\n| `!permit @user` | Allow a user to speak through the bot |\n| `!unpermit @user` | Remove speak permission |\n| `!adminrole @role` | Set which role can manage the bot |\n| `!commandchar \u003cchar\u003e` | Change the command prefix (default `!`) |\n| `!restrict [#channel]` | Restrict bot to specific text channels |\n| `!keep \u003ccount\u003e` | Auto-delete old messages (keep last N) |\n| `!sfx set \u003cword\u003e \u003curl\u003e` | Add a sound effect triggered by a word/emoji |\n| `!sfx list` | List all sound effects |\n| `!sfx del \u003cword\u003e` | Remove a sound effect |\n| `!textrule add \u003cfind\u003e -\u003e \u003creplace\u003e` | Add a text replacement rule |\n| `!textrule list` | List all text rules |\n| `!bind add \u003cid\u003e` | Auto-follow when users join a channel/role |\n| `!twitch permit \u003cchannel\u003e \u003cwho\u003e` | Connect Twitch chat to voice |\n\n---\n\n## Environment Variables Reference\n\nAll configuration is done through `.env`. Copy `.env.example` to get started.\n\n### Required\n| Variable | Description |\n|----------|-------------|\n| `DISCORD_TOKEN` | Bot token from Discord Developer Portal |\n\n### Optional — Discord\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `CLIENT_ID` | | Application ID (needed for slash command registration) |\n| `DEV_IDS` | | Comma-separated Discord user IDs for bot developers |\n| `SUPPORT_SERVER_ID` | | Your support Discord server ID |\n\n### Optional — Bot Behavior\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `COMMAND_CHAR` | `!` | Prefix character for commands |\n| `DEFAULT_TITLE` | `master` | Default title for the bot master |\n| `NEGLECT_TIMEOUT` | `3600000` | Ms before bot leaves inactive voice (default 1 hour) |\n| `NEGLECT_TIMEOUT_MESSAGES` | `Talkbot inactivity timeout` | Comma-separated messages spoken before timeout |\n| `PESTER_THRESHOLD` | `10000000` | Character count before self-hosting nag |\n| `TWITCH_AUDIO_QUEUE_LIMIT` | `10` | Max queued Twitch messages |\n| `ADVERTISE_STREAMER` | | Streamer name to advertise |\n| `TAGLINE` | | Bot tagline |\n\n### Optional — Logging\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `LOG_OUTPUT` | `true` | Enable info logging |\n| `LOG_ERRORS` | `true` | Enable error logging |\n| `NODE_ENV` | `development` | Set to `production` for deployed instances |\n| `LOG_LEVEL` | `info` | Logging verbosity |\n\n### TTS Provider Credentials\n| Variable | Provider | Description |\n|----------|----------|-------------|\n| `GOOGLE_APPLICATION_CREDENTIALS` | Google | Path to service account JSON |\n| `AWS_ACCESS_KEY_ID` | Amazon Polly | IAM access key |\n| `AWS_SECRET_ACCESS_KEY` | Amazon Polly | IAM secret key |\n| `AWS_REGION` | Amazon Polly | AWS region (default `us-east-1`) |\n| `AZURE_SUBSCRIPTION_KEY` | Azure | Speech resource subscription key |\n| `AZURE_ENDPOINT` | Azure | Speech endpoint URL |\n| `WATSON_API_KEY` | Watson | IAM API key |\n| `WATSON_SERVICE_URL` | Watson | Service instance URL |\n| `TENCENT_ACCESS_KEY_ID` | Tencent | API access key |\n| `TENCENT_SECRET_ACCESS_KEY` | Tencent | API secret key |\n| `ALIBABA_APP_KEY` | Alibaba | Application key |\n| `ALIBABA_TOKEN` | Alibaba | Access token |\n| `ALIBABA_ENDPOINT` | Alibaba | TTS endpoint URL |\n| `KOKORO_BASE_URL` | Kokoro | Server URL (default `http://kokoro-tts:8880`) |\n| `KOKORO_DEFAULT_VOICE` | Kokoro | Default voice (default `af_heart`) |\n| `KOKORO_DEVICE` | Kokoro | `cpu` or `gpu` (picks Docker image) |\n\n### TTS Provider Settings\nEach provider has `ENABLED`, `ENFORCE_LIMIT`, and `LIMIT` settings. Format: `TTS_\u003cPROVIDER\u003e_\u003cSETTING\u003e`.\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `TTS_GOOGLE_ENABLED` | `false` | Enable Google Cloud TTS |\n| `TTS_GOOGLE_ENFORCE_LIMIT` | `false` | Block requests after limit hit |\n| `TTS_GOOGLE_LIMIT` | `5000000` | Character limit |\n| `TTS_AMAZON_ENABLED` | `true` | Enable Amazon Polly |\n| `TTS_AMAZON_ENFORCE_LIMIT` | `false` | Block requests after limit hit |\n| `TTS_AMAZON_LIMIT` | `5000000` | Character limit |\n| `TTS_AZURE_ENABLED` | `false` | Enable Azure Cognitive Services |\n| `TTS_AZURE_ENFORCE_LIMIT` | `false` | Block requests after limit hit |\n| `TTS_AZURE_LIMIT` | `5000000` | Character limit |\n| `TTS_WATSON_ENABLED` | `false` | Enable IBM Watson |\n| `TTS_WATSON_ENFORCE_LIMIT` | `false` | Block requests after limit hit |\n| `TTS_WATSON_LIMIT` | `5000000` | Character limit |\n| `TTS_TENCENT_ENABLED` | `false` | Enable Tencent Cloud |\n| `TTS_TENCENT_ENFORCE_LIMIT` | `true` | Block requests after limit hit |\n| `TTS_TENCENT_LIMIT` | `1000000` | Character limit |\n| `TTS_ALIBABA_ENABLED` | `false` | Enable Alibaba Cloud |\n| `TTS_ALIBABA_ENFORCE_LIMIT` | `true` | Block requests after limit hit |\n| `TTS_ALIBABA_LIMIT` | `1000000` | Character limit |\n| `TTS_KOKORO_ENABLED` | `false` | Enable Kokoro local TTS |\n| `TTS_KOKORO_ENFORCE_LIMIT` | `false` | Block requests after limit hit |\n| `TTS_KOKORO_LIMIT` | `5000000` | Character limit |\n\n---\n\n## Setup on Coolify\n\n[Coolify](https://coolify.io/) is a self-hosted PaaS that can deploy Docker apps.\n\n1. **Create a new resource** in Coolify and connect your GitHub repo (or use the public URL).\n\n2. **Set build pack** to Docker Compose.\n\n3. **Add environment variables** in Coolify's UI — add all the variables from your `.env` file. At minimum:\n   - `DISCORD_TOKEN`\n   - Your TTS provider credentials (e.g. `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`)\n   - `TTS_\u003cPROVIDER\u003e_ENABLED=true` for the provider(s) you want\n\n4. **Persistent storage** — create a volume mount for the config directory so `.server` files (per-guild state) persist across deployments:\n   ```\n   /data/talkbot/config → /app/config\n   ```\n\n5. **Deploy** — Coolify will build the Docker image and start the container.\n\n6. **Check logs** in Coolify's UI to verify the bot connected and loaded TTS providers.\n\n**Tips:**\n- Coolify passes env vars to the container automatically — you don't need a `.env` file inside the container.\n- For Google TTS, upload `google-auth.json` to your persistent volume and set `GOOGLE_APPLICATION_CREDENTIALS=/app/config/google-auth.json`.\n- The bot stores per-server state in `config/*.server` files — make sure the volume is persistent so these survive redeployments.\n\n---\n\n## Local Development\n\n### Prerequisites\n- Node.js 22+\n- npm\n\n### Setup\n```bash\ngit clone https://github.com/nullabork/talkbot.git\ncd talkbot\nnpm install\ncp .env.example .env\n# Edit .env with your credentials\n```\n\n### Commands\n| Command | Description |\n|---------|-------------|\n| `npm run build` | Compile TypeScript to `dist/` |\n| `npm start` | Run the compiled bot |\n| `npm run dev` | Watch mode with auto-restart |\n| `npm test` | Run tests (Vitest) |\n| `npm run lint` | Type-check (`tsc --noEmit`) |\n\n### How it works\n1. `npm run build` compiles TypeScript from `src/` to `dist/` using `tsc`, then rewrites path aliases with `tsc-alias`, then copies `src/lang.json` to `dist/`.\n2. `npm start` runs `node dist/src/index.js` which loads `.env`, validates env vars with Zod, initializes TTS providers, connects to Discord, and listens for messages.\n3. When a user types in a text channel, the bot checks if it's a command (`!follow`, etc.) or regular text. Regular text is sent to the TTS provider and played in the voice channel.\n\n---\n\n## Project Structure\n\n```\nsrc/\n  index.ts              — Bot entry point (event handlers, startup)\n  env.ts                — Zod-validated environment variables\n  config-loader.ts      — Loads config/config.json\n  paths.ts              — Resolved filesystem paths\n  commands/\n    index.ts            — Command registry and dispatch\n    modules/            — Individual command handlers (37 commands)\n  helpers/\n    bot-stuff.ts        — Discord client setup\n    common.ts           — Logging and string utilities\n    ffmpeg.ts           — MP3 → Opus conversion (WASM)\n    ssml-dictionary.ts  — Discord markdown → SSML mappings\n  models/\n    Server.ts           — Per-guild state, voice connection, TTS pipeline\n    World.ts            — All servers, presence, lifecycle\n    Command.ts          — Base command class\n    BotCommand.ts       — Legacy command data class\n    MessageDetails.ts   — Command context wrapper\n    MessageSSML.ts      — SSML message builder\n  services/\n    TextToSpeechService.ts  — Abstract TTS base class + provider registry\n    tts/                    — Provider implementations (Google, Amazon, Azure, Watson, Tencent, Alibaba)\n  types/                — TypeScript interfaces\nconfig/\n  config.json           — Server overrides (per-guild settings)\n  config.example.json   — Template\n  default.textrules.json — Default text replacement rules\n  lang.json             — i18n string overrides\n  *.server              — Per-guild state files (auto-generated)\n```\n\n---\n\n## Troubleshooting\n\n### Bot doesn't respond to commands\n- Make sure `DISCORD_TOKEN` is set in `.env`.\n- Check that **Message Content Intent** is enabled in the Discord Developer Portal.\n- Verify the bot has Send Messages permission in the channel.\n\n### Bot joins voice but doesn't speak\n- Check that at least one TTS provider is enabled (`TTS_\u003cPROVIDER\u003e_ENABLED=true`) and has valid credentials in `.env`.\n- Check logs for TTS API errors.\n- Make sure the bot has **Connect** and **Speak** permissions in the voice channel.\n\n### Docker build fails\n- Ensure `patches/` directory exists (needed by `patch-package`).\n- Check that `config/default.textrules.json` and `config/lang.json` exist.\n\n### Google TTS not working\n- `GOOGLE_APPLICATION_CREDENTIALS` must point to a valid service account JSON file.\n- In Docker, the config volume mount (`./config:/app/config`) must contain `google-auth.json`.\n\n### Bot is slow to speak\n- First message after startup is slower (WASM ffmpeg cold load for Amazon Polly).\n- Subsequent messages are faster.\n- Google Cloud TTS is generally the fastest provider.\n\n### Upgrading from v1\n- See [Migrating to v2](#migrating-to-v2) for the full walkthrough.\n\n---\n\n## Acknowledgements\n\n- WootoSmash\n- FaxWang\n- GreenLionVoltronPilot\n- Kingk22\n- Kelinmiriel\n\n## License\n\nSee [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullabork%2Ftalkbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnullabork%2Ftalkbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullabork%2Ftalkbot/lists"}