Files
broccolini-bot/.env.example
indifferentketchup 840b6bfcf8 simplify: prune dead code, dedup gmail send, drop neutered log stubs
- Remove no-op log stubs (logGmail, logAutomation, logSecurity, logSystem)
  and ~17 callsites; dead counters in tickets.js and gmail-poll.js go too
- Dedup three near-identical Gmail send paths into sendThreadedEmail helper
- Drop dead Mongoose fields: broccoliniTicketId, lastSyncedBroccoliniArticleId,
  renameCount, renameWindowStart, reminderSent, staffChannelId,
  unclaimedRemindersSent, lastMessageAuthorIsStaff
- Drop dead config fields and their .env.example entries
- Inline api/botClient.js (3-line wrapper, 2 callers)
- Trim unused exports across utils.js, tickets.js, configSchema.js, debugLog.js
- Fix handlers/messages.js to use isStaff() — old partial check ignored
  ADDITIONAL_STAFF_ROLES, so those members were treated as customers
- Drop unused deps p-queue + dotenv-expand; move mongodb to devDependencies

Net: -583 LOC source + -57 LOC lockfile. All 23 modules load clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:37:14 +00:00

140 lines
8.0 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# Broccolini Bot Example environment (no secrets)
# Copy to .env and fill in real values. See README for full docs.
# =============================================================================
# Test env: set ENV_FILE=.env.test to load .env.test instead (see docs/setup/ENV_AND_SECURITY.md).
# --- Discord: Core ---
DISCORD_TOKEN= # Bot token from Discord Developer Portal
DISCORD_APPLICATION_ID= # Application (client) ID
DISCORD_GUILD_ID= # Server (guild) ID where the bot runs
# --- Discord: Channel & category IDs ---
# Ticket creation: set one or both; /panel and /email-routing choose behavior
DISCORD_TICKET_CATEGORY_ID= # Category for Discord-originated ticket channels
TICKET_CATEGORY_ID= # Category for email-originated ticket channels
# Category display name (primary must match the category name in Discord; overflow folders are created as "{name} (Overflow 1)", etc.)
TICKET_CATEGORY_NAME=Open Tickets
# Escalation categories (tier 2 and tier 3)
DISCORD_ESCALATED_CATEGORY_ID= # Fallback escalation category (Discord)
EMAIL_ESCALATED_CATEGORY_ID= # Fallback escalation category (email); legacy alias: ESCALATED_CATEGORY_ID
DISCORD_ESCALATED2_CHANNEL_ID= # Tier 2 escalation category/channel (Discord)
DISCORD_ESCALATED3_CHANNEL_ID= # Tier 3 escalation category/channel (Discord)
EMAIL_ESCALATED2_CHANNEL_ID= # Tier 2 escalation category ID (email tickets; env name says CHANNEL for legacy reasons)
EMAIL_ESCALATED3_CHANNEL_ID= # Tier 3 escalation category ID (email tickets; same naming note as tier 2)
# Logging, transcripts, and utility
ROLE_ID_TO_PING= # Role ID to ping on new tickets (config also accepts ROLE_TO_PING_ID as alias)
TRANSCRIPT_CHANNEL_ID= # Channel for ticket transcripts on close
LOGGING_CHANNEL_ID= # Channel for lifecycle log messages
DEBUGGING_CHANNEL_ID= # Channel for error logs (escalate, poll, etc.); optional
# --- Discord: Ticket copy & buttons ---
# ESCALATION_MESSAGE: use {support_name} for SUPPORT_NAME
ESCALATION_MESSAGE= # e.g. Your ticket has been escalated.\n\nA senior {support_name} will be here to assist as soon as possible.
BUTTON_LABEL_CLOSE=Close Ticket
BUTTON_LABEL_CLAIM=Claim
BUTTON_LABEL_UNCLAIM=Unclaim
BUTTON_EMOJI_CLOSE=🔒
BUTTON_EMOJI_CLAIM=📌
BUTTON_EMOJI_UNCLAIM=🔓
# --- Google / Gmail ---
GOOGLE_CLIENT_ID= # OAuth2 Client ID from Google Cloud Console
GOOGLE_CLIENT_SECRET= # OAuth2 Client Secret
REFRESH_TOKEN= # OAuth2 refresh token for the support inbox
MY_EMAIL= # Support inbox email address
# --- Server ---
DISCORD_ONLY_PORT=5000 # Port for healthcheck / Discord-only server
# HEALTHCHECK_HOST= # Optional; bind address for health server (default: all interfaces; use 127.0.0.1 for local-only)
# --- Database ---
MONGODB_URI= # MongoDB connection string (e.g. mongodb://broccoli_bot:CHANGE_ME@localhost:27017/broccoli_db?authSource=broccoli_db)
# MONGODB_DATABASE= # Optional; DB name usually in MONGODB_URI path (not read by app currently)
# --- Branding & copy ---
SUPPORT_NAME=Support
LOGO_URL= # URL of logo shown in embeds (optional)
EMAIL_SIGNATURE= # HTML signature for outgoing emails (use \n for line breaks)
TICKET_CLOSE_SUBJECT_PREFIX=[Resolved]
# Email tickets only (closure email body):
TICKET_CLOSE_MESSAGE= # Body of closure email to customer
TICKET_CLOSE_SIGNATURE= # Signature on closure email
# Discord ticket closure (in-channel before transcript, transcript post, and auto-close):
DISCORD_CLOSE_MESSAGE= # Message in ticket channel before transcript (e.g. ... If you still need assistance, please open a new ticket.)
DISCORD_TRANSCRIPT_MESSAGE= # When posting transcript / DM to user. Use {channel_name}, {email}, {date_opened}, {date_closed}
DISCORD_AUTO_CLOSE_MESSAGE= # Message in ticket when auto-closed (e.g. ... If you still need assistance, please open a new ticket.)
# --- Ticket limits & permissions ---
GLOBAL_TICKET_LIMIT=5 # Max concurrent open tickets globally
RATE_LIMIT_TICKETS_PER_USER=0 # Max tickets per user per window (0 = disabled)
RATE_LIMIT_WINDOW_MINUTES=60 # Window in minutes for per-user rate limit
BLACKLISTED_ROLES= # Comma-separated role IDs that cannot open tickets
ADDITIONAL_STAFF_ROLES= # Comma-separated role IDs with staff permissions
# --- Auto-close ---
AUTO_CLOSE_ENABLED=false
AUTO_CLOSE_AFTER_HOURS=72
# --- Reminders ---
REMINDER_ENABLED=false
REMINDER_AFTER_HOURS=24
# REMINDER_MESSAGE: use {ping} (claimer mention or role ping), {hours}
REMINDER_MESSAGE= # e.g. Hey {ping}! This ticket has been inactive for {hours} hours. Please provide an update or close the ticket.
TICKET_WELCOME_MESSAGE= # Message in welcome embed when ticket channel is created
# TICKET_CLAIMED_MESSAGE / TICKET_UNCLAIMED_MESSAGE: use {staff_mention}, {staff_name}
TICKET_CLAIMED_MESSAGE= # e.g. Ticket claimed by {staff_mention} 🚀
TICKET_UNCLAIMED_MESSAGE= # e.g. Ticket unclaimed by {staff_mention} ☀️
# --- Priority (low, normal, medium, high; default: normal) ---
PRIORITY_ENABLED=false
DEFAULT_PRIORITY=normal
PRIORITY_HIGH_EMOJI=🔴
PRIORITY_MEDIUM_EMOJI=🟡
PRIORITY_LOW_EMOJI=🟢
# --- Claiming ---
AUTO_UNCLAIM_ENABLED=false
AUTO_UNCLAIM_AFTER_HOURS=24
ALLOW_CLAIM_OVERWRITE=false
ADMIN_ID= # Discord user ID of the bot admin (for Gmail OAuth failure DMs)
FORCE_CLOSE_TIMER_SECONDS=60 # Seconds to wait before force-closing a ticket (default 60)
GMAIL_POLL_INTERVAL_SECONDS=30 # Gmail poll interval in seconds (default 30)
GMAIL_LOG_CHANNEL_ID= # Channel for Gmail poll activity logs
AUTOMATION_LOG_CHANNEL_ID= # Channel for auto-close/auto-unclaim/reminder logs
RENAME_LOG_CHANNEL_ID= # Channel for channel rename queue logs
SECURITY_LOG_CHANNEL_ID= # Channel for security/audit logs
SYSTEM_LOG_CHANNEL_ID= # Channel for bot lifecycle logs (startup, shutdown, DB events)
# --- Staff threads ---
STAFF_THREAD_ENABLED=false # Create a private staff thread on each ticket channel
STAFF_THREAD_NAME=Staff Discussion # Name of the private thread
STAFF_THREAD_AUTO_ADD_ROLE=false # Auto-add all members of STAFF_THREAD_ROLE_ID to thread on creation
STAFF_THREAD_ROLE_ID= # Role whose members are added to the thread (defaults to ROLE_ID_TO_PING)
# --- Message pinning ---
PIN_INITIAL_MESSAGE_ENABLED=false # Auto-pin the welcome message on ticket creation
PIN_ESCALATION_MESSAGE_ENABLED=false # Auto-pin escalation messages
PIN_SUPPRESS_SYSTEM_MESSAGE=false # Delete the "X pinned a message" system message after pinning
TRANSCRIPT_DM_TO_CREATOR=false # DM the transcript file to the ticket creator on close (Discord-origin tickets only)
# --- Settings site & internal API ---
SETTINGS_PORT=12752 # Port for the settings web UI
SETTINGS_ADMIN_PASSWORD= # Password to access the settings UI
SETTINGS_ADMIN_PASSWORD_2= # Optional second password with identical access (leave blank to disable)
SETTINGS_DOMAIN=tickets.indifferentketchup.com # Domain for the settings site (update when domain changes)
INTERNAL_API_PORT=12753 # Internal port for bot<->settings IPC (not exposed externally)
INTERNAL_API_SECRET= # Shared secret between bot and settings site (generate a random string)
# --- Game list (comma-separated; used for detection and tags) ---
GAME_LIST=Project Zomboid, Minecraft, ...
# --- Embed colors (hex with 0x prefix) ---
EMBED_COLOR_OPEN=0x00FF00
EMBED_COLOR_CLAIMED=0xFFFF00
EMBED_COLOR_ESCALATED=0xFF6600
EMBED_COLOR_INFO=0x1e2124