No description
Find a file
DJP dd57239408 Add multi-select batch top-up on Low Balance screen
Checkboxes on each row + Select All in the header. When users are
selected, a "Top Up Selected" button appears in the filter bar.
Opens a modal with preset amounts to top up all selected users at
once. Each individual top-up is logged to history.

New endpoint: POST /api/balances/batch/add

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:03:46 -04:00
public Add multi-select batch top-up on Low Balance screen 2026-04-13 11:03:46 -04:00
routes Add multi-select batch top-up on Low Balance screen 2026-04-13 11:03:46 -04:00
services Add email notifications with one-click approve/reject from email 2026-03-27 09:50:44 -04:00
.dockerignore Initial commit - LibreChat Balance Manager 2026-03-17 22:51:25 -04:00
.env.example Add email notifications with one-click approve/reject from email 2026-03-27 09:50:44 -04:00
.gitignore Add credit request system with public form and admin dashboard 2026-03-20 14:43:42 -04:00
docker-compose.yml Add credit request system with public form and admin dashboard 2026-03-20 14:43:42 -04:00
Dockerfile Initial commit - LibreChat Balance Manager 2026-03-17 22:51:25 -04:00
LibreChat-Balance-Commands.md Add credit request system with public form and admin dashboard 2026-03-20 14:43:42 -04:00
package-lock.json Add email notifications with one-click approve/reject from email 2026-03-27 09:50:44 -04:00
package.json Add email notifications with one-click approve/reject from email 2026-03-27 09:50:44 -04:00
README.md Update README with email notifications, history, and full setup guide 2026-03-27 10:42:26 -04:00
server.js Add email notifications with one-click approve/reject from email 2026-03-27 09:50:44 -04:00

LibreChat Balance Manager

Admin dashboard for managing LibreChat user token balances. View, search, top up, and bulk-manage user credits.

Features

  • Dashboard — overview stats (total users, average balance, zero-balance users)
  • All Balances — paginated table sorted by credits, with per-user Top Up / Set actions
  • Find User — search by name or email (type "dave" to find daveporter@...) with instant results
  • Low Balance — filter users below 1M/2M/3M/4M/5M token thresholds
  • Credit Requests — users submit requests via a public form; admins approve/reject from the dashboard
  • Email Notifications — automatic email to admins when a request is submitted, with one-click approve buttons
  • Email Approval — approve (5M/10M/20M/custom) or reject directly from the email without logging in
  • History — full audit trail of all balance changes, searchable by user email
  • Bulk Operations — add tokens to all users or set everyone to a specific amount
  • Preset Amounts — quick buttons for common token amounts
  • CSV Export — download balance data from the All Balances view
  • API Key Auth — simple key-based authentication for the admin dashboard

Install on Dev Server

1. Clone the repo

cd /opt
git clone https://x-token-auth:YOUR_TOKEN@bitbucket.org/zlalani/librechat-balances.git Balance-Manager

Or with SSH:

GIT_SSH_COMMAND="ssh -i ~/.ssh/djp1971" git clone git@bitbucket.org:zlalani/librechat-balances.git Balance-Manager

2. Create the .env file

cd /opt/Balance-Manager
cp .env.example .env
nano .env

Set your values:

MONGO_URI=mongodb://mongodb:27017/LibreChat
PORT=3002
API_KEY=your-secure-key-here

# Webhook security
WEBHOOK_SECRET=your-random-secret-here
WEBHOOK_BASE_URL=https://chat-dev.oliver.solutions/balance-manager
WEBHOOK_TTL_HOURS=72

# SMTP (Mailgun or any SMTP server)
SMTP_HOST=smtp.mailgun.org
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
SMTP_FROM=noreply@yourdomain.com

# Notification recipients (comma-separated for multiple)
NOTIFY_TO=admin@yourdomain.com,another@yourdomain.com
Variable Description
MONGO_URI LibreChat MongoDB connection (uses Docker network name mongodb)
API_KEY Secret key for the admin dashboard — entered in browser on first load
WEBHOOK_SECRET Random string for signing email approve/reject links. Generate with openssl rand -hex 32
WEBHOOK_BASE_URL Public URL of the app (e.g. https://chat-dev.oliver.solutions/balance-manager)
WEBHOOK_TTL_HOURS How long email approve links stay valid (default 72 hours)
SMTP_HOST SMTP server hostname
SMTP_PORT SMTP port (587 for TLS)
SMTP_USER SMTP username
SMTP_PASS SMTP password
SMTP_FROM Sender email address
NOTIFY_TO Comma-separated list of admin emails to receive request notifications

3. Build and start

cd /opt/Balance-Manager
docker compose up -d --build

4. Verify it's running

docker logs librechat-balance-manager

You should see:

Connected to MongoDB
Balance Manager running on http://localhost:3002

Add this to your NGINX config (/opt/LibreChat/client/nginx.conf) inside the server block, before the location / block:

location /balance-manager/ {
    proxy_pass http://balance-manager:3002/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Then restart NGINX:

docker restart LibreChat-NGINX

Access at: https://chat-dev.oliver.solutions/balance-manager/

The balance-manager container must be on the same Docker network as NGINX. This is already configured in docker-compose.yml via the librechat_default external network.

How It Works

Credit Request Flow

  1. User visits /balance-manager/request and submits their email + OMG job number
  2. An email is sent to all NOTIFY_TO recipients with approve buttons (5M, 10M, 20M, Custom, Reject)
  3. Admin clicks a button in the email — a confirmation page opens in the browser
  4. Admin clicks "Confirm" on the page — the request is approved and tokens are added
  5. Alternatively, admins can approve/reject from the dashboard under the "Requests" tab

Email Security

  • Each button link is signed with HMAC-SHA256 using WEBHOOK_SECRET
  • Links are scoped to a specific request ID + amount and expire after WEBHOOK_TTL_HOURS
  • Clicking a link shows a confirmation page first (GET) — the actual approval only happens on form submit (POST)
  • This prevents email security scanners (Microsoft Defender Safe Links, etc.) from auto-approving requests
  • Links cannot be reused — once a request is processed, subsequent clicks show "Already Processed"

History / Audit Trail

All balance changes are logged to data/history.json:

  • Manual top-ups and balance sets from the admin dashboard
  • Request approvals (from email or dashboard)
  • Bulk operations

Search by email in the "History" tab to see all changes for a user with totals.

Updating

cd /opt/Balance-Manager
git pull https://x-token-auth:YOUR_TOKEN@bitbucket.org/zlalani/librechat-balances.git main
docker compose up -d --build

Troubleshooting

Container won't connect to MongoDB:

docker network inspect librechat_default | grep balance

If not listed, make sure docker-compose.yml has:

networks:
  librechat_default:
    external: true

Port conflict:

Change the port in both .env (PORT=3003) and docker-compose.yml (127.0.0.1:3003:3003).

Reset API key in browser:

localStorage.removeItem('bm_api_key')

Then refresh the page.

Emails not sending:

Check the container logs for SMTP errors:

docker logs librechat-balance-manager

Common issues:

  • Missing or incorrect SMTP credentials in .env
  • Mailgun sandbox domains require recipients to be added as authorized
  • SMTP_FROM must match a verified domain in Mailgun

Email approve links not working:

  • Check WEBHOOK_BASE_URL matches your public URL exactly
  • Ensure NGINX is proxying /balance-manager/ traffic correctly
  • Links expire after WEBHOOK_TTL_HOURS — check if the link has expired