Skip to content

ItsJustJar/JartoniteBot

Repository files navigation

Jartonite

Production-ready Discord bot for the JARTON Studios middleman marketplace.

  • Stack: TypeScript, discord.js v14, Prisma, MariaDB
  • Deployment: VPS + systemd (no Docker)
  • Cross-server privacy model: clients and freelancers communicate through a strict reply-only bridge between two guilds

Implemented Features

  • Slash-command architecture with modular folders (src/features, src/commands, src/utils)
  • Honey/orange themed embeds with centralized style (EMBED_COLOR, optional LOGO_URL)
  • /ticket
    • Opens guided Order flow (TOS -> department -> service -> modal -> ticket creation)
    • Staff can post panel embed with post_panel=true
  • Ticket panel buttons
    • Order
    • Support (modal + staff shadow ping)
  • Cross-Discord bridge (Option 1, implemented)
    • One bot in both guilds
    • Linked channels (ticket_links)
    • Reply-only forwarding on both sides
    • Invalid non-reply messages are deleted (if permitted) and user is DM'd with instructions
    • Message chain tracked in message_bridge
  • Quote lifecycle
    • /submit quote from freelancer-side linked channels
    • Client-side accept/deny buttons
    • On accept: state updated, channels renamed from quote-* to ticket-*, freelancer access tightened
  • /bugreport modal -> bug report channel
  • /profile + /portfolio persistence (view/set)
  • /balance + /wallet wallet readout
  • Stubbed command scaffolding for all requested commands with TODO marker and permission placeholders
  • Audit logging for ticket/quote/job state changes (DB + service-records channel)
  • Startup lockdown enforcement for panel/listing channels

Cross-Discord Chat Options

Option 1 (Recommended, Implemented)

  • One bot application token added to both guilds.
  • Each order creates:
    • Client guild channel (client + staff)
    • Freelancer guild channel (relevant freelancer roles + staff)
  • Messages are mirrored only via reply-to-bot-forwarded-embed rules.

Option 2 (Supported by architecture, not implemented)

  • Two bot apps/tokens, shared DB queue or internal API.
  • Better permission isolation, more operational complexity.

Option 3 (Not feasible for privacy requirement)

  • Single guild with hidden live chat is not truly possible in Discord text channels if both parties can see the channel.
  • For strict separation, two guilds + bridge is required.

Project Structure

src/
  commands/
    definitions.ts
    handler.ts
  config/
    env.ts
    services.ts
  db/
    prisma.ts
  features/
    bridge/service.ts
    jobs/quotes.ts
    tickets/service.ts
  types/context.ts
  utils/
    audit.ts
    content.ts
    embed.ts
    permissions.ts
  index.ts
  register-commands.ts
prisma/
  schema.prisma
config/
  services.json
systemd/
  jartonite.service
.env.example
README.md

Requirements

  • Node.js 20+
  • MariaDB 10.6+
  • systemd-based Linux VPS
  • Discord bot with permissions:
    • Manage Channels
    • Manage Roles (if you expand role workflows)
    • Manage Messages
    • Send Messages
    • Embed Links
    • Attach Files
    • Read Message History
    • Add Reactions
  • Privileged intents (Developer Portal -> Bot):
    • Message Content Intent (required for cross-discord reply bridge)
    • Server Members Intent (optional for this build; disabled by default)

Setup (VPS)

  1. Clone project.
  2. Install dependencies:
npm i
  1. Create MariaDB database and grants.

If maria is unavailable on Ubuntu 22.04, use mariadb:

mariadb

Session context captured from your VPS:

  • Host: ip-23-137-105-200
  • MariaDB monitor server version: 10.6.23-MariaDB-0ubuntu0.22.04.1

Commands used on your VPS:

CREATE DATABASE IF NOT EXISTS jartonite
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON jartonite.* TO 'mcuser'@'localhost';
FLUSH PRIVILEGES;
SHOW DATABASES;
USE jartonite;

Because your grant uses mcuser@localhost, .env is configured with:

DATABASE_URL=mysql://mcuser:[email protected]:3306/jartonite

Replace CHANGE_ME with the real password for mcuser (or adjust auth/user as needed).

  1. Configure environment:
cp .env.example .env
  1. Edit .env and set all required IDs/tokens.
  2. Edit config/services.json for your department/service map and freelancer role mapping.
  3. Generate Prisma client + run migrations:
npm run prisma:generate
npm run prisma:migrate
  1. Register slash commands (for configured guild IDs):
npm run register:commands
  1. Build and run:
npm run build
npm run start

systemd Deployment

  1. Copy template:
sudo cp systemd/jartonite.service /etc/systemd/system/jartonite.service
  1. Edit service file User, Group, WorkingDirectory, and EnvironmentFile.
  2. Enable/start service:
sudo systemctl daemon-reload
sudo systemctl enable jartonite
sudo systemctl restart jartonite
sudo systemctl status jartonite
  1. View logs:
journalctl -u jartonite -f

Slash Command Notes

  • Use /ticket post_panel:true as staff to post the panel in channel 1478952132546924655.
  • Running /ticket without post_panel starts the same order flow as panel button.

Environment Variables

See .env.example. Core required variables:

  • DISCORD_TOKEN, DISCORD_CLIENT_ID
  • DATABASE_URL
  • CLIENT_GUILD_ID
  • CLIENT_ORDER_CATEGORY_ID, CLIENT_SUPPORT_CATEGORY_ID
  • TICKET_PANEL_CHANNEL_ID
  • SERVICE_RECORDS_CHANNEL_ID
  • BUG_REPORTS_CHANNEL_ID
  • REVIEWS_CHANNEL_ID
  • JOB_LISTINGS_CHANNEL_ID
  • STAFF_PING_ROLE_ID
  • STAFF_ROLE_IDS

Freelancer bridge variables (required for Option 1 full operation):

  • FREELANCER_GUILD_ID
  • FREELANCER_ORDER_CATEGORY_ID
  • FREELANCER_STAFF_ROLE_IDS (optional override)
  • FREELANCER_ROLE_FALLBACK_IDS (optional)
  • ENABLE_MESSAGE_CONTENT_INTENT (set true for bridge)
  • ENABLE_GUILD_MEMBERS_INTENT (optional, default false)
  • EMBED_ICON_URL (optional; use your GIF/icon URL for embed header icon)

If freelancer bridge variables are missing, bot logs a clear warning and continues with client-side ticket creation only.

Troubleshooting:

  • Unknown interaction (10062):
    • Usually means multiple running instances are using the same bot token.
    • Stop duplicate processes so only one bot instance is active.
  • Can't reach database server at 127.0.0.1:3306:
    • Database is unreachable from the bot process.
    • Check MariaDB service status and verify DATABASE_URL.

Command Coverage

Fully implemented now:

  • /ticket
  • /bugreport
  • /profile
  • /portfolio
  • /balance
  • /wallet
  • /submit quote

Stubbed with TODO scaffolding:

  • /affiliate, /busy, /unbusy, /calculate, /denyticket, /undeny, /earnings, /report, /setother, /setpaypal, /settimezone, /setwise, /withdraw, /withdrawals, /claimroles, /toggleother, /apply, /embed, /reviews

Operational Notes

  • message_bridge enforces reply-only forwarding.
  • All ticket and quote lifecycle transitions are written to audit_logs and service-records channel.
  • config/services.json supports missing department/service images (null) and fallback role behavior.
  • TOS_URL falls back to a placeholder if unset.

About

Discord bot for JARTON Studios — middleman marketplace with cross-server ticket/quote bridge

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors