Automated Thermal Print Service for the MySagra Ecosystem
Features β’ How It Works β’ Installation β’ Docker β’ Configuration
MyStampa is a headless print service built with Node.js and TypeScript. It is part of the MySagra ecosystem and is responsible for receiving confirmed orders from the backend via Server-Sent Events (SSE) and routing them to the correct ESC/POS thermal printers over TCP.
It also monitors the status of all configured printers (online, offline, paper out) and reports changes back to the backend in real time.
A lightweight web UI is included for configuration β managing single-ticket categories and viewing live printer status.
- SSE-based order reception β connects to the backend and listens for
confirmed-orderandreprint-orderevents - Kitchen receipts β routes order items to the correct kitchen printer based on food configuration
- Cash receipts β prints fiscal receipts with itemized totals, discounts, surcharges and payment method
- Single tickets β prints individual cut tickets for configurable item categories
- Logo support β prints a custom logo and MySagra footer on cash receipts (ESC/POS raster graphics)
- Print queue β failed jobs are queued and retried automatically every 60 seconds
- TCP probing β probes each printer via socket every 2 minutes using ESC/POS
DLE EOT 4 - Paper status detection β distinguishes between ONLINE, OFFLINE and paper-out (ERROR)
- Backend sync β PATCHes the printer status on the backend only when it changes
- Login β authenticates against the MySagra backend using user credentials
- Category config β select which item categories should print individual cut tickets
- Printer overview β live list of all printers with their current status
MySagra Backend
β
β SSE (X-API-KEY)
βΌ
MyStampa
β
ββββΊ Kitchen Printer 1 (TCP ESC/POS)
ββββΊ Kitchen Printer 2 (TCP ESC/POS)
ββββΊ Cash Register Printer (TCP ESC/POS)
- On startup MyStampa fetches the printer list from the backend using the API key.
- It connects to the SSE endpoint at
API_URL/events/printerand keeps the connection alive. - When a
confirmed-orderorreprint-orderevent arrives, it fetches food and cash register details from the backend, builds the receipts and sends them to the appropriate printers over TCP. - Every 2 minutes it probes all printers and PATCHes any status changes to the backend.
Authentication is split into two independent layers:
- Automated service β
X-API-KEYheader on all backend API calls - Web UI β standard credential login against
API_URL/auth/login; the returned session token is stored in a cookie for the duration of the session
- Node.js 20.x or higher
- Access to a MySagra backend instance
- ESC/POS thermal printers reachable over TCP
-
Clone the repository
git clone https://github.com/MySagra/mystampa.git cd mystampa -
Install dependencies
npm install
-
Configure environment variables
cp .env.example .env
Edit
.envwith your values (see Configuration). -
Start in development mode
npm run dev
-
Open the web UI
Navigate to http://localhost:3032
MyStampa is designed to run as a Docker container alongside the rest of the MySagra stack.
-
Create your
.envfilecp .env.example .env
Fill in
API_URLandAPI_KEY. -
Start the container
docker-compose up -d
-
Access the web UI
The application will be available at http://localhost:3032
The Dockerfile uses a multi-stage build:
- deps β installs npm packages
- builder β compiles TypeScript
- runner β minimal production image running
node dist/index.js
The container joins the mysagra-network external Docker network to reach the backend.
The named volume mystampa_config is used to persist the configuration (single-ticket categories) across container restarts and image updates. It is created automatically by Docker on first run β no manual setup required.
Every fiscal receipt prints a logo at the top. By default the MySagra logo (baked into the Docker image) is used. You can replace it with your own without rebuilding the image.
The service looks for the logo in this order:
assets/logo.png(or.jpg/.jpeg) β your custom logo, provided at runtimedefault-assets/logo.pngβ the MySagra fallback, always present inside the image
Place your logo file in the assets/ folder at the project root:
assets/
βββ logo.png β your custom logo (PNG, JPG or JPEG)
Restart the service and the new logo will appear on the next receipt.
The docker-compose.yml already mounts ./assets as a volume:
volumes:
- ./assets:/app/assetsSimply drop your logo.png into the ./assets/ folder on the host β no rebuild required:
cp /path/to/your/logo.png ./assets/logo.png
docker-compose restart mystampaIf ./assets/logo.png is absent, the container automatically falls back to the MySagra default logo stored in default-assets/ inside the image.
Tips for best results:
- Use a square or landscape image, ideally 300β600 px wide
- Black-and-white or high-contrast images print best on thermal paper
- Supported formats:
logo.png,logo.jpg,logo.jpeg
All configuration is done via environment variables. Copy .env.example to .env and fill in the values.
| Variable | Description | Example |
|---|---|---|
API_URL |
Base URL of the MySagra backend | http://mysagra-backend:4300 |
API_KEY |
API key for the automated print service (X-API-KEY) |
ms_pt_xxxxxxxxxxxxx |
How to get the API key: the API key is generated and displayed after your first login to the MySagra admin panel. Once obtained, copy it into the
API_KEYfield in your.envfile and restart the service.
The API key is used exclusively by the automated service (SSE connection, printer fetching, status patching, food/cash-register lookups). The web UI authenticates separately using user credentials.
mystampa/
βββ src/
β βββ index.ts # Entry point β Express server, SSE client, printer polling
β βββ models.ts # Domain models and API interfaces
β βββ routes/
β β βββ print.ts # Print order handler (kitchen + cash receipts)
β βββ utils/
β β βββ axiosInstance.ts # Axios with retry interceptor
β β βββ printer.ts # ESC/POS receipt builder and TCP send
β β βββ printQueue.ts # Failed-job queue with periodic retry
β β βββ image.ts # Logo rasterization for ESC/POS
β βββ views/
β βββ login.ejs # Web UI login page
β βββ config.ejs # Web UI configuration page
βββ public/ # Static files (favicon, banner, login-bg, logo.svg)
βββ assets/ # Print assets (logo.png, mysagralogo.png)
βββ Dockerfile
βββ docker-compose.yml
βββ .env.example
| Command | Description |
|---|---|
npm run dev |
Start with ts-node and hot reload |
npm run build |
Compile TypeScript to dist/ |
npm start |
Build and run the production server |
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
- You can use, modify, and distribute this software
- You must disclose source code of any modifications
- You must license derivative works under AGPL-3.0
- Network use counts as distribution (must provide source)
See the LICENSE file for full details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
