First upload

This commit is contained in:
samkintop
2026-02-17 21:49:58 -06:00
parent 29a13768f7
commit 6821424663
46 changed files with 3179 additions and 14 deletions

126
docs/setup/1PASSWORD.md Normal file
View File

@@ -0,0 +1,126 @@
# 1Password integration (API keys & tokens)
Use 1Password as the single source of truth for Broccolini Bot secrets. Your `.env` file then holds only **Secret References** (`op://...`), so you never store plaintext tokens on disk.
---
## Setup checklist (extension + CLI)
| Step | What to do |
|------|------------|
| **1. Extension** | In Cursor: **Extensions** (Ctrl+Shift+X) → search **1Password****Install**. *(On WSL/Linux the extension may refuse to install; use the CLI path below instead.)* |
| **2. Choose account** | After installing: Command Palette (Ctrl+Shift+P) → **1Password: Choose account** → sign in and pick a vault. |
| **3. CLI** | Install 1Password CLI: `sudo apt install op` (WSL/Linux) or [install from 1Password](https://developer.1password.com/docs/cli/get-started/). Then run **`eval $(op signin)`** once per terminal (or add to your shell profile). |
| **4. Store secrets** | In 1Password: create an item (e.g. **Broccolini Bot**) and add custom fields for each secret (e.g. `DISCORD_TOKEN`, `MONGODB_URI`, `REFRESH_TOKEN`). Use **Copy reference** on each field. |
| **5. .env with refs** | In `broccolini-bot/.env`: put `KEY=op://Vault/ItemName/FIELD` for each secret (no plaintext). Use **1Password: Get from 1Password** in the editor to insert refs, or paste from step 4. |
| **6. Run bot** | From `broccolini-bot/`: **`npm run start:1p`** (or `op run --env-file=.env -- npm run start`). |
If the extension is not available on your OS, use **steps 36 only** (CLI + Secret References in `.env` + `op run`).
---
## Extensions and Cursor integration
| What | Where | Purpose |
|------|--------|--------|
| **1Password for VS Code** | [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=1Password.1password) | Works in Cursor. Save/retrieve secrets, Secret References, detect secrets, preview `op://` refs. [Docs](https://developer.1password.com/docs/vscode/). |
| **1Password Cursor Hooks** | [1Password Marketplace](https://marketplace.1password.com/integration/cursor-hooks) | Validates that **1Password Environments**mounted `.env` files are present and valid before Cursor Agent runs shell commands. [Cursor Hooks docs](https://developer.1password.com/docs/cursor-hooks), [validate hook guide](https://developer.1password.com/docs/environments/cursor-hook-validate). |
- **VS Code extension:** Install in Cursor via Extensions (search “1Password”). Use **1Password: Get from 1Password** / **Save in 1Password** and Secret References in `.env` and code.
- **Cursor Hooks:** Uses **1Password Environments** with *locally mounted* `.env` files (Mac/Linux; requires 1Password app + `sqlite3`). Clone [1Password/cursor-hooks](https://github.com/1Password/cursor-hooks), add the hook to `.cursor/hooks`, and optionally `.1password/environments.toml` to declare which `.env` paths to validate. Then Cursor Agent only runs commands when those env files are mounted.
---
## 1. Install
- **1Password for VS Code / Cursor**
Install the [1Password extension](https://marketplace.visualstudio.com/items?itemName=1Password.1password) in Cursor. You can then use Secret References in files and autofill from your vault.
- **1Password CLI (`op`)**
Required for running the bot with secrets from 1Password. Full install and sign-in: **[Get started with 1Password CLI](https://developer.1password.com/docs/cli/get-started/)**.
- **Install:** Linux (WSL): `sudo apt install op`; Mac: Homebrew or [manual](https://developer.1password.com/docs/cli/get-started/); Windows: winget or manual.
- **Desktop app:** In 1Password app → **Settings****Developer** → turn on **Integrate with 1Password CLI** (Mac: optional Touch ID; Windows: turn on Windows Hello first; Linux: **Settings****Security****Unlock using system authentication**, then Developer → Integrate).
- **Sign in:** Run `eval $(op signin)` (or any `op` command); youll be prompted to authenticate.
---
## 2. Store secrets in 1Password
Create an item that will hold Broccolini Bot env vars, e.g. **“Broccolini Bot”** or **“Broccolini Bot Production”**.
- **Type:** API Credential or Secure Note.
- **Fields:** Add one custom field per secret. Field names must match the env var names (e.g. `DISCORD_TOKEN`, `MONGODB_URI`, `REFRESH_TOKEN`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, etc.).
Use the same names as in `.env.example` for the sensitive values.
You can use a second item (e.g. **“Broccolini Bot Test”**) with test-only values and point `.env.test` at it (see below).
---
## 3. Use Secret References in `.env`
In `.env` (and optionally `.env.test`), **do not** put real tokens. Use 1Password Secret References instead:
```bash
# Example: vault "Personal", item "Broccolini Bot", field "password" or custom field name
DISCORD_TOKEN=op://Personal/Broccolini Bot/DISCORD_TOKEN
MONGODB_URI=op://Personal/Broccolini Bot/MONGODB_URI
REFRESH_TOKEN=op://Personal/Broccolini Bot/REFRESH_TOKEN
GOOGLE_CLIENT_ID=op://Personal/Broccolini Bot/GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET=op://Personal/Broccolini Bot/GOOGLE_CLIENT_SECRET
# ... same for other secrets
```
- Replace **Personal** with your vault name.
- Replace **Broccolini Bot** with your item title (spaces are fine).
- The last part is the **field name** inside that item (e.g. `DISCORD_TOKEN`).
Non-secret values (IDs, ports, feature flags) can stay as plain text in `.env` if you prefer.
To get a reference from the 1Password app: open the item → click a field → “Copy reference”.
---
## 4. Run the bot with 1Password
From the **broccolini-bot** directory:
```bash
op run --env-file=.env -- npm run start
```
For the test env:
```bash
op run --env-file=.env.test -- npm run start:test
```
`op run` reads `.env` (or `.env.test`), resolves every `op://...` value with 1Password, and runs the command with the resolved environment. The bots `config.js` still reads from `process.env` as usual; no code changes are required.
---
## 5. npm scripts (already in package.json)
In `broccolini-bot/`:
- `npm run start:1p` — production env from 1Password (resolves `op://` from `.env`)
- `npm run start:test:1p` — test env from 1Password (resolves `op://` from `.env.test`)
---
## 6. Security notes
- **Do not commit `.env` or `.env.test`.** They are gitignored. Even with Secret References, keep them out of the repo.
- **Rotate secrets** in 1Password when needed; no need to edit local files if you only use references.
- The 1Password Cursor extension can fill Secret References in the editor; the CLI is what actually resolves them when you run the bot.
---
## Quick reference
| Task | Command / step |
|------|----------------|
| **CLI get started** | [Get started with 1Password CLI](https://developer.1password.com/docs/cli/get-started/) (install, desktop integration, sign in) |
| Sign in to CLI | `eval $(op signin)` — required so the session is loaded into your shell; plain `op signin` only prints the commands. |
| Run bot (production) | `op run --env-file=.env -- npm run start` |
| Run bot (test) | `op run --env-file=.env.test -- npm run start:test` |
| Copy a secret reference | 1Password app → item → field → “Copy reference” |

View File

@@ -0,0 +1,73 @@
# Environment, Test Env, and Security
## Test environment (prevent data loss)
**.env is production/live.** Changes to `.env` can affect real tickets, Discord, Gmail, and MongoDB. To try config changes safely:
1. **Copy the test template:**
`cp .env.test.example .env.test`
2. **Edit `.env.test`** with test-only values (e.g. test guild, test MongoDB database name, test API URL). Use a separate test DB in `MONGODB_URI` to avoid touching production data.
3. **Run the bot with the test env:**
`npm run start:test`
Or: `ENV_FILE=.env.test node broccolini-discord.js`
4. **Other scripts with test env:**
- `npm run test-mongodb:test` — test MongoDB connection using `.env.test`
5. **After confirming behavior**, migrate only the desired variables from `.env.test` into `.env` (manually). Do not overwrite `.env` blindly.
**Rule:** New or risky env changes are done in `.env.test` first; only after confirmation are they applied to `.env`.
---
## Agent / AI rules
- **Changes to `.env` by an agent (e.g. Cursor) must require explicit user confirmation.** Do not modify `.env` automatically. Prefer proposing changes to `.env.test` or listing the exact edits for the user to apply to `.env`.
- **Do not commit `.env` or `.env.test`.** Only `.env.example` and `.env.test.example` are committed (no secrets).
---
## Security checklist
- **Secrets:** All secrets live in `.env` (or `.env.test` for test). Never commit them. `.gitignore` excludes `.env` and `.env.*` except `.env.example` and `.env.test.example`.
- **Code:** No `eval()` or `new Function()` of user input. No hardcoded tokens, passwords, or API keys in source.
- **Config:** Credentials are read from `process.env` via `config.js`; config is loaded once at startup from the file specified by `ENV_FILE` or default `.env`.
- **MongoDB:** Use a dedicated user and database; restrict network access (Atlas IP allowlist or VPC). For test, use a separate DB or cluster.
- **Discord / Google:** Use tokens with minimal required scopes; rotate if compromised.
- **HTML in emails:** `LOGO_URL`, `EMAIL_SIGNATURE`, and closure messages are escaped in outbound HTML to prevent injection.
- **Healthcheck:** Optional `HEALTHCHECK_HOST=127.0.0.1` in `.env` binds the healthcheck server to localhost only; omit to listen on all interfaces.
- **Dependencies:** Run `npm audit` periodically and fix or accept risk for reported vulnerabilities.
---
## Cleanup and redundancy
- **Single source of truth for env keys:** `.env.example` and `.env.test.example` list all supported variables. Defaults for optional vars live in `config.js`; do not duplicate default values in both `.env.example` and `config.js` for the same value (`.env.example` documents, `config.js` implements).
- **No duplicate env files:** Use `.env` for live, `.env.test` for test; do not commit `.env.local`, `.env.production`, etc. unless documented and gitignored as needed.
- **Parent repo (IB-Discord-Bot):** Broccolini Bot does not reference sibling paths (e.g. `../ngrok`) in code. Run order and ports are documented in `~/IB-Discord-Bot/README.md`.
---
## Connection to IB-Discord-Bot stack
Broccolini Bot is a subproject of **IB-Discord-Bot**. It does not import or require files outside `broccolini-bot/`. Integration is via:
- **Ports:** Broccolini Bot healthcheck uses `DISCORD_ONLY_PORT` (default 5000). Use a different port in `.env.test` (e.g. 5001) if running bot and test bot on the same machine.
See parent **~/IB-Discord-Bot/README.md** for run order, ports, and troubleshooting.
---
## Quick reference
| File / command | Purpose |
|-----------------------|--------|
| `.env` | Live config (never commit). |
| `.env.test` | Test config (never commit). |
| `.env.example` | Template for `.env` (committed). |
| `.env.test.example` | Template for `.env.test` (committed). |
| `ENV_FILE=.env.test` | Load `.env.test` instead of `.env`. |
| `npm run start:test` | Run bot with `.env.test`. |
| `npm run test-mongodb:test` | Test MongoDB using `.env.test`. |

152
docs/setup/MONGODB_SETUP.md Normal file
View File

@@ -0,0 +1,152 @@
# MongoDB Setup for Broccolini Bot
## Overview
Broccolini Bot uses **MongoDB only** for persistent storage (tickets, transcripts, counters, tags, close requests). Run all commands from the repo root; create `.env` there (copy from `.env.example`) and set `MONGODB_URI`. For test runs, use `.env.test` (copy from `.env.test.example`) and `npm run test-mongodb:test`; see [ENV_AND_SECURITY.md](./ENV_AND_SECURITY.md).
## Files
1. **`db-connection.js`** - MongoDB connection module with reconnection logic
2. **`models.js`** - Mongoose schemas including:
- `Ticket` - Stores ticket information
- `TicketCounter` - Tracks ticket numbers per sender
- `Transcript` - Stores transcript message references
3. **`scripts/test-mongodb.js`** - Connection test script (run via `npm run test-mongodb`; use `npm run test-mongodb:test` with `.env.test`)
## Configuration
### 1. Environment Variable
Add to your `.env` file:
```env
MONGODB_URI=mongodb://localhost:27018/broccolini_bot
```
**Note:** Uses port `27018` to match your existing setup (as defined in docker-compose.yml).
### 2. Install Dependencies
```bash
npm install
```
This will install `mongoose@^6.12.0`.
## Usage in Your Code
### Basic Connection
```javascript
const { connectMongoDB, closeMongoDB, mongoose } = require('./db-connection');
// In your Discord client.once('ready', ...) event:
await connectMongoDB(process.env.MONGODB_URI);
console.log('Connected to MongoDB');
// Get models:
const Ticket = mongoose.model('Ticket');
const TicketCounter = mongoose.model('TicketCounter');
const Transcript = mongoose.model('Transcript');
```
## Schema Reference
### Ticket Schema
```javascript
{
gmail_thread_id: String (required, unique, indexed),
discord_thread_id: String,
broccolini_ticket_id: Number,
sender_email: String (required),
subject: String,
created_at: Date (default: now),
status: String (enum: ['open', 'closed'], default: 'open'),
claimed_by: String (Discord user ID),
escalated: Boolean (default: false),
ticket_number: Number,
rename_count: Number (default: 0),
rename_window_start: Date
}
```
### TicketCounter Schema
```javascript
{
sender_local: String (required, unique),
counter: Number (default: 1)
}
```
### Transcript Schema
```javascript
{
gmail_thread_id: String (required),
transcript_message_id: String,
created_at: Date (default: now)
}
```
## Testing the Connection
From the repo root, run:
```bash
npm run test-mongodb
```
Expected output:
```
Pinged your deployment. You successfully connected to MongoDB!
```
## Graceful Shutdown
Add this to your main file for clean shutdown:
```javascript
process.on('SIGTERM', async () => {
console.log('SIGTERM received, closing connections...');
await closeMongoDB();
await client.destroy(); // Discord client
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('SIGINT received, closing connections...');
await closeMongoDB();
await client.destroy();
process.exit(0);
});
```
## Connection Features
- **Auto-reconnection**: If MongoDB connection drops, Mongoose will automatically attempt to reconnect
- **Connection events**: Logs when connected, disconnected, and reconnected
- **Error handling**: Graceful error messages with stack traces
- **Timeouts**: Configured with reasonable defaults (5s server selection, 45s socket timeout)
## Next Steps
1. Review the schemas in `models.js`
2. Test the connection with `npm run test-mongodb`
3. Start the bot with `npm start` (uses MongoDB throughout)
4. Monitor MongoDB connection in production logs
## Troubleshooting
### Connection refused
- Check MongoDB is running: `docker ps` or `systemctl status mongodb`
- Verify port 27018 is correct in `.env`
- Check MongoDB logs for errors
### Authentication failed
- If MongoDB requires auth, update URI: `mongodb://username:password@localhost:27018/broccolini_bot`
### Schema validation errors
- Check required fields are provided when creating documents
- Ensure `status` is either 'open' or 'closed' (enum validation)

View File

@@ -0,0 +1,154 @@
# Project Structure
Overview of the **Broccolini Bot** project layout and the role of each file and directory. Single-level repo: all paths are relative to the repo root.
---
## Root
| File / Dir | Purpose |
|------------|--------|
| `broccolini-discord.js` | **Entry point.** Main Discord bot process. |
| `config.js` | Configuration loading (env, defaults). |
| `db-connection.js` | MongoDB connection setup. |
| `models.js` | Mongoose models (e.g. guild settings, tickets). |
| `utils.js` | Shared utilities. |
| `gmail-poll.js` | Gmail polling / inbox sync logic. |
| `game-options.json` | Game-related options (e.g. for slash commands). |
| `package.json` | Dependencies and npm scripts. |
| `.env.example` | Example environment variables (copy to `.env`). |
| `.env.test.example` | Test env template (copy to `.env.test`; run with `npm run start:test`). See [ENV_AND_SECURITY.md](./ENV_AND_SECURITY.md). |
| `.gitignore` | Git ignore rules (`.env` and `.env.test` never committed). |
---
## Directories
### `commands/`
Slash-command registration and definitions.
| File | Purpose |
|------|--------|
| `register.js` | Registers Discord slash commands (e.g. `/ticket`, `/setup`). |
---
### `handlers/`
Event and interaction handlers for the Discord bot.
| File | Purpose |
|------|--------|
| `accountinfo.js` | Account / user info commands or logic. |
| `analytics.js` | Analytics or stats handling. |
| `buttons.js` | Discord button interaction handlers. |
| `commands.js` | Slash command execution routing. |
| `messages.js` | Message events (e.g. DMs, channel messages). |
| `setup.js` | Setup / configuration flow (e.g. guild setup). |
---
### `services/`
Core business logic and external integrations.
| File | Purpose |
|------|--------|
| `debugLog.js` | Debug / structured logging. |
| `gmail.js` | Gmail API integration (read/send, labels). |
| `guildSettings.js` | Guild-specific settings (DB + cache). |
| `tickets.js` | Ticket lifecycle (create, update, auto-close, reminders). |
---
### `utils/`
Helper modules used across the app.
| File | Purpose |
|------|--------|
| `ticketComponents.js` | Discord components (buttons, selects) for ticket flows. |
---
### `scripts/`
One-off or maintenance scripts.
| File | Purpose |
|------|--------|
| `backup-env.js` | Copies `.env` to `.env.backup` (run via `node scripts/backup-env.js`). |
| `test-mongodb.js` | Tests MongoDB connection (run via `npm run test-mongodb`). |
---
### `docs/`
Documentation and reference files (all paths below relative to repo root).
| File | Purpose |
|------|--------|
| `ENV_AND_SECURITY.md` | Test env workflow, security checklist, agent rules. |
| `QUICKSTART.md` | Quick start / setup guide. |
| `FEATURES_SUMMARY.md` | Feature overview. |
| `IMPLEMENTATION_SUMMARY.md` | Implementation notes. |
| `PHASE_FEATURES.md` | Phased feature list. |
| `MONGODB_SETUP.md` | MongoDB setup instructions. |
| `NEW_FEATURES.md` | New features changelog. |
| `UPGRADE_COMPLETE.md` | Upgrade completion notes. |
| `DISCORD_API_VALIDATION.md` | Discord API validation details. |
| `DISCORD_API_IMPROVEMENTS.md` | Discord API improvements. |
| `PROPOSAL.md` | Roadmap and possible next steps (API, routing, bOSScord). |
| `PROJECT_STRUCTURE.md` | This file. |
---
## Tree View
```
broccolini-bot/
├── broccolini-discord.js # Entry point
├── config.js
├── db-connection.js
├── models.js
├── utils.js
├── gmail-poll.js
├── game-options.json
├── package.json
├── .env.example
├── .gitignore
├── commands/
│ └── register.js
├── handlers/
│ ├── accountinfo.js
│ ├── analytics.js
│ ├── buttons.js
│ ├── commands.js
│ ├── messages.js
│ └── setup.js
├── services/
│ ├── debugLog.js
│ ├── gmail.js
│ ├── guildSettings.js
│ └── tickets.js
├── utils/
│ └── ticketComponents.js
├── scripts/
│ ├── backup-env.js
│ └── test-mongodb.js
├── docs/ # All .md docs except README.md
│ ├── ENV_AND_SECURITY.md
│ ├── QUICKSTART.md
│ ├── MONGODB_SETUP.md
│ └── ... (see table above)
└── README.md
```
---
## Run
- **Start bot:** `npm start` → runs `node broccolini-discord.js`
- **Backup .env:** `node scripts/backup-env.js` → copies `.env` to `.env.backup`
- **Test MongoDB:** `npm run test-mongodb` → runs `node scripts/test-mongodb.js`

199
docs/setup/QUICKSTART.md Normal file
View File

@@ -0,0 +1,199 @@
# Broccolini Bot Quick Start Guide
Get started with Broccolini Bot in 5 minutes! Run all commands from the repo root. Ensure `.env` exists in the repo root (copy from `.env.example`).
**Test env:** To try changes safely, use `.env.test` (copy from `.env.test.example`) and run `npm run start:test`. See [ENV_AND_SECURITY.md](./ENV_AND_SECURITY.md). **Agents:** do not modify `.env` without explicit user confirmation; prefer changing `.env.test` first.
## 1. Restart Your Bot
```bash
npm start
```
The bot will automatically:
- Use MongoDB collections (Tag, CloseRequest, etc.) as needed
- Register all new slash commands
- Start background jobs (auto-close, auto-unclaim, reminders)
## 2. Create Your First Saved Response
```
/response create name:welcome content:Welcome to support, {ticket.user}! We'll help you with {ticket.subject}.
```
Then use it:
```
/response send name:welcome
```
Use `/tag` in a ticket channel to set the ticket category (dropdown: Server Down, Billing, Mod Help, etc.). The bot posts: *Your ticket has been categorized as [Emoji][Tag][Emoji].*
## 3. Set Up a Ticket Panel
```
/panel #support-tickets type:both title:Need Help? description:Click below to open a ticket!
```
Use `type` to choose **thread**, **category**, or **both**. Users click the button → Fill out modal → Ticket created automatically!
## 4. Try the New Commands
### User Management
```
/add @user # Add someone to current ticket
/remove @user # Remove someone from ticket
```
### Ticket Actions
```
/transfer @staff # Transfer to another staff member
/move #category # Move to different category
/priority [level] # Set priority: posts upgraded/downgraded/normal message; email sent when set to high
/topic Important! # Set channel topic
/escalate [reason] [tier] # Escalate to tier 2 or 3 (or use Escalate button)
/deescalate # De-escalate one step
/force-close # Close without confirmation
```
### Close Confirmation
Click "Close Ticket" button → Get confirmation prompt → Confirm or cancel
## 5. Configure New Options
Edit your `.env`:
```env
# Enable auto-unclaim after 24 hours of inactivity
AUTO_UNCLAIM_ENABLED=true
AUTO_UNCLAIM_AFTER_HOURS=24
# Allow staff to claim already-claimed tickets
ALLOW_CLAIM_OVERWRITE=true
# Use threads instead of channels (future)
USE_THREADS=false
```
**Restart the bot** after changing `.env`; slash commands may need re-registration (restart the bot).
## 6. Use Variables in Tags
Create smart tags with dynamic content:
```
/response create name:closing content:Thanks {ticket.user}! Ticket #{ticket.number} is now closed. Contact us anytime at {server.name}!
```
Available variables:
- `{ticket.user}`, `{ticket.email}`, `{ticket.number}`, `{ticket.subject}`
- `{staff.name}`, `{staff.mention}`
- `{server.name}`, `{date}`, `{time}`
## 7. Priority Management
Set priorities for better organization:
```
/priority low # 🟢 Low priority
/priority normal # 🟡 Normal (default)
/priority medium # 🟠 Medium priority
/priority high # 🔴 High priority (sends email to ticket sender)
```
The bot posts: *Your ticket has been upgraded/downgraded to [Emoji][Level][Emoji].* or *Your ticket priority has returned to Normal.*
## 8. Test the Panel System
1. Create panel in a channel: `/panel #support`
2. As a user, click "Open Ticket" button
3. Fill out the modal form
4. Submit → Ticket channel created automatically!
## 9. View All Commands
```
/help
```
Shows organized list of all commands with descriptions.
## 10. Check Your Setup
Verify everything is working:
✅ All slash commands appear in Discord
✅ Can create saved responses with `/response create`; use `/tag` for ticket category
✅ Panel shows "Open Ticket" button (and optional type: thread / category / both)
✅ Clicking button shows modal form
✅ Close button shows confirmation
✅ Priority command updates ticket
`/help` command shows all features
---
## Common Issues
### Commands not showing?
- Wait up to 1 hour for Discord to sync
- Verify `DISCORD_APPLICATION_ID` in `.env`
- Restart bot
### Modal not appearing?
- Check user permissions
- Ensure bot has proper guild permissions
- Try in different channel
### Saved responses not working?
- Use `/response list` to see all tags
- Check for typos in tag name
- Autocomplete shows valid tags
---
## Next Steps
1. **Create More Tags**: Add responses for common questions
2. **Set Up Panels**: Put panels in help channels
3. **Train Staff**: Show team the new commands
4. **Enable Auto-Features**: Turn on auto-unclaim if desired
5. **Customize Messages**: Edit `.env` variables for your brand
6. **Monitor Performance**: Check logs for errors
---
## Key Features Summary
**Variables** - Dynamic message templates
🏷️ **Tags** - Saved responses system
👥 **User Management** - Add/remove users from tickets
🎫 **Panel System** - User-friendly ticket creation
📋 **Modal Forms** - Interactive ticket submission
**Priority Levels** - Organize by importance
🔄 **Transfer** - Move tickets between staff
📌 **Enhanced Claiming** - Auto-unclaim, overwrite options
**Close Confirmation** - Prevent accidental closes
📚 **Help Command** - Built-in documentation
---
## Pro Tips
💡 Use variables in welcome messages for personalization
💡 Create tags for FAQs to save time
💡 Set high priority for urgent tickets
💡 Use `/topic` to document ticket status
💡 Enable auto-unclaim to prevent stale claims
💡 Put panels in pinned messages
💡 Use `/transfer` with reasons for context
---
## Getting Help
- Read [PHASE_FEATURES.md](./PHASE_FEATURES.md) for detailed documentation
- Check logs for error messages
- Test features in a test channel first
- Use `/help` in Discord for command reference
---
**Ready to go! Enjoy your enhanced ticket system! 🚀**