Skip to content

jordankzf/print-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Print Agent

Remote printing over WebSocket. Send print jobs from a server to a thermal printer (e.g. FC-588) at a remote office. The recipient double-clicks an exe, picks their printer, and it connects automatically. No port forwarding, no accounts, no configuration on the remote end.

Architecture

Your Server (Linux VPS)              Remote Windows PC
┌──────────────────┐                 ┌───────────────────────┐
│  Print Server     │◄──WebSocket────│  PrintAgent.exe       │
│  (Bun/TypeScript) │    (outbound)  │  (Go, ~6MB)           │
│                   │                │                       │
│  POST /api/print  │───job data────►│  → Windows Spooler    │
│  GET  /api/status │                │  → Thermal printer    │
└──────────────────┘                 └───────────────────────┘

The agent makes an outbound WebSocket connection to your server — no port forwarding or special config needed on the remote end.

Setup: Server

1. Deploy the print server

cd server
bun install
bun run start

2. Environment variables

export PRINT_SERVER_PORT=9100           # default: 9100
export PRINT_API_SECRET=your-secret-here  # for REST API auth

3. Expose to the internet

The agent connects outbound to your server via WebSocket. You need to make the print server reachable on a domain.

Option A: Cloudflare Tunnel (recommended)

No reverse proxy needed — cloudflared connects directly to Cloudflare's edge.

  1. Install cloudflared and authenticate:

    cloudflared tunnel login
    cloudflared tunnel create print-server
  2. Add the hostname to your tunnel config (~/.cloudflared/config.yml):

    tunnel: <your-tunnel-id>
    credentials-file: /home/you/.cloudflared/<your-tunnel-id>.json
    
    ingress:
      - hostname: print.yourdomain.com
        service: http://localhost:9100
      - service: http_status:404
  3. Route DNS to the tunnel:

    cloudflared tunnel route dns <your-tunnel-id> print.yourdomain.com
  4. Run the tunnel (or set up as a systemd service):

    cloudflared tunnel run <tunnel-name>

Agent connects to wss://print.yourdomain.com/ws — goes through port 443, works through any firewall. Cloudflare handles SSL and WebSocket proxying automatically.

Cloudflare has a 100-second WebSocket idle timeout. The agent pings every 30 seconds, so the connection stays alive automatically.

Option B: Cloudflare + reverse proxy

  1. Add a DNS A record: print.yourdomain.com → your VPS IP, Proxied (orange cloud on)
  2. Add a reverse proxy on your VPS to forward to the print server:

Caddy (add to Caddyfile):

print.yourdomain.com {
    reverse_proxy localhost:9100
}

Nginx:

server {
    listen 443 ssl;
    server_name print.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/print.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/print.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:9100;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
    }
}

Agent connects to wss://print.yourdomain.com/ws.

Option C: Direct (no Cloudflare)

Open the port and connect directly (unencrypted):

ufw allow 9100

Agent connects to ws://your-vps-ip:9100/ws. Works but could be blocked by corporate firewalls that restrict non-standard ports.

4. Keep it running (PM2)

pm2 start "bun run start" --name print-server --cwd /path/to/server
pm2 save

Setup: Remote PC (Agent)

1. Install

Download PrintAgentSetup.exe from Releases and send it to the recipient.

2. Run the installer

Click through — all defaults are fine. The agent launches after install.

3. First launch

  1. Lists all installed printers — pick the target printer by number
  2. Asks for server URL — enter your WebSocket URL (e.g. wss://print.yourdomain.com/ws)
  3. Config saved — won't ask again

That's it. Starts automatically on boot, lives in the system tray.

What the recipient sees

  • Green "CONNECTED - READY" = working, waiting for jobs
  • Red "DISCONNECTED" = can't reach server, retrying automatically
  • Scrolling log with timestamps — if something goes wrong, they can photograph the screen and send it to you

Troubleshooting

  • "No printers found" → Make sure the printer is plugged in and turned on, restart the exe
  • "DISCONNECTED" won't go away → Check internet connection. The exe retries automatically.
  • Need to change printer or server → Delete config.json next to the exe (in Program Files) and restart

Sending Print Jobs (API)

From any service on your server:

# Plain text (auto-wrapped in ESC/POS init + cut commands)
curl -X POST http://localhost:9100/api/print \
  -H "Authorization: Bearer your-secret-here" \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello from the server!\nThis prints on the remote printer."}'

# Raw ESC/POS (base64 encoded)
curl -X POST http://localhost:9100/api/print \
  -H "Authorization: Bearer your-secret-here" \
  -H "Content-Type: application/json" \
  -d '{"raw_data": "G0AbaEhlbGxvIFdvcmxkCg=="}'

# Check agent status
curl http://localhost:9100/api/status \
  -H "Authorization: Bearer your-secret-here"

# List recent jobs
curl http://localhost:9100/api/jobs \
  -H "Authorization: Bearer your-secret-here"

Features

  • Zero-config remote end — outbound WebSocket, no port forwarding needed
  • Auto-reconnect — exponential backoff, survives network drops
  • System tray — minimize to tray, auto-start on boot
  • Verbose logging — large monospace text, photographable for remote debugging
  • ESC/POS support — send raw thermal printer commands or plain text
  • Job queue — jobs queue on the server if the agent is offline, sent when it reconnects
  • Installer — Inno Setup, auto-start, clean uninstall

Building from source

# Agent (Windows)
cd agent
go mod download
go build -ldflags="-H windowsgui -s -w" -o ../PrintAgent.exe .

# Installer (requires Inno Setup 6)
iscc installer.iss

# Server
cd server
bun run start

Requires Go 1.21+ on Windows (uses Win32 APIs for printing and GUI).

About

Remote printing over WebSocket. Send print jobs from a server to a thermal printer at a remote office. Zero-config Windows agent with system tray, auto-reconnect, and installer.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors