# Broccolini Bot A Node.js Discord bot that bridges **Gmail ↔ Discord** for support ticketing, with **MongoDB** for state. Built for Indifferent Broccoli (game-server hosting). - Inbound email → Discord ticket channel. - Staff messages in that channel → Gmail reply (threaded). - Discord-originated tickets (panel / context menu) live entirely in Discord. For an architectural overview, see [HOWITWORKS.md](HOWITWORKS.md). For agent/contributor conventions, see [CLAUDE.md](CLAUDE.md). --- ## Quick start ```bash git clone cd broccolini-bot npm install cp .env.example .env # fill DISCORD_TOKEN, DISCORD_APPLICATION_ID, DISCORD_GUILD_ID, TICKET_CATEGORY_ID, # ROLE_ID_TO_PING, MONGODB_URI, GOOGLE_CLIENT_ID/SECRET, REFRESH_TOKEN, MY_EMAIL npm start ``` Need a Gmail refresh token? `node get-refresh-token.js` (redirect URI `http://localhost:3000/oauth2callback`). Probe Mongo with `npm run test-mongodb`. Restart the bot after any `.env` change. Restart also re-registers slash commands. ## Deploy (Docker) ```bash docker compose up --build -d docker logs broccolini --tail 50 -f ``` Host port `8892` → container `5000` (`DISCORD_ONLY_PORT`). ## Configuration All config is environment variables loaded by `config.js` into `CONFIG`. The full list — with descriptions and defaults — lives in [`.env.example`](.env.example). Highlights: | Variable | Notes | |----------|-------| | `DISCORD_TOKEN` / `DISCORD_BOT_TOKEN` | Bot token. First non-empty after trim wins. | | `DISCORD_APPLICATION_ID`, `DISCORD_GUILD_ID` | Required for slash command registration. | | `TICKET_CATEGORY_ID` | Default category for email tickets. Validated at startup. | | `DISCORD_TICKET_CATEGORY_ID` | Category for Discord panel/context tickets (falls back to `TICKET_CATEGORY_ID`). | | `ROLE_ID_TO_PING` | Support role pinged on new tickets. | | `MONGODB_URI` | Mongo connection string. | | `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` / `REFRESH_TOKEN` / `MY_EMAIL` | Gmail OAuth + canonical inbox address. | | `RENAMER_BOT` | Optional secondary token used for channel renames. | | `INTERNAL_API_SECRET` / `INTERNAL_API_PORT` | Enable the internal config API used by the settings UI. | ## Slash commands | Command | Purpose | |---------|---------| | `/escalate`, `/deescalate` | Move ticket between tier 2/3 categories. | | `/add`, `/remove` | Add/remove user from current ticket channel. | | `/transfer` | Hand the claim to another staff member. | | `/move` | Reparent the channel to another category. | | `/force-close`, `/cancel-close`, `/closetimer` | Force-close flow with cancellable countdown. | | `/topic` | Set channel topic. | | `/response` | Saved reply templates (`send`, `create`, `edit`, `delete`, `list`). | | `/panel` | Post an "Open ticket" panel button (thread / category / both). | | `/notifydm` | Toggle DM alerts when a customer replies in your claimed ticket. | | `/signature` | Personal email signature (valediction, display name, tagline). | | `/staffthread` | Toggle / configure staff-only threads on tickets. | | `/pinmessages` | Auto-pin welcome / escalation messages. | | `/gmailpoll` | Set the Gmail poll interval at runtime. | | `/help` | In-bot summary. | Plus context menus: **Create Ticket From Message**, **View User Tickets**. ## Settings UI (optional) `settings-site/` is a separate Express app that talks to the bot's internal config API over the `broccoli-net` Docker network using `INTERNAL_API_SECRET`. It is **not** part of this bot's process. See [`settings-site/CLAUDE.md`](settings-site/CLAUDE.md). ## Troubleshooting | Symptom | Check | |---------|-------| | Slash commands missing | Correct `DISCORD_APPLICATION_ID` + `DISCORD_GUILD_ID`; restart; Discord can take a minute to sync. | | Gmail not ingesting | `REFRESH_TOKEN` valid? Auth failure halts polling — re-auth and restart. | | Mongo errors at startup | `MONGODB_URI` reachable? `npm run test-mongodb` to confirm. | | Channel rename "too quickly" | Discord limit is 2 renames/10 min per channel — the queue serializes; wait it out. | | Modal/button no response | Bot online + intents enabled; check `DEBUGGING_CHANNEL_ID` / container logs. | ## License ISC