Skip to content
Work
MEDIUMAutomation / hardware integration service01/2025–present

Scanner service

Node.jsExpressnode-windowsNAPS2.ConsoleCanon DR-C230Batch scriptingscanimageImageMagickWindows Service
github.com/itd24/scanner-service

Overview

This project turns a cheap second hand document scanner into a small network service. The scanner sits at home. A Node.js service drives it and listens for a request.

When I press a scan button in my dashboard, my home API calls the service. The service scans into a folder named after the person I picked. Paperless watches that folder, so the finished scan ends up in my archive without more steps.

Most of the work went into the small problems. NAPS2 has to be stopped between scans, and it behaves differently when a service starts it. Both cases are in the README, with the fixes.

Problem

I have a cheap second hand document scanner at home. I wanted to start a scan with one button press from my dashboard, and I wanted the finished file to land in my document archive without any more work.

Approach

  • I wrote a small Node.js service that drives the scanner and offers a tiny HTTP API.
  • I made the scan category part of the request, so the chosen person becomes the folder the scan is saved in.
  • I used the scan folder as the link to the archive. Paperless reads that folder, so a finished scan is picked up on its own.
  • I installed the service as a Windows service, so it runs without a window open.
  • I wrote a small test script, so I can run one operation from the command line without starting the server.
  • I wrote down the two NAPS2 problems I ran into, together with the fixes.

Architecture and design decisions

  • An Express server listens on port 4356. It has two routes: POST /trigger/:operation and GET /alive.
  • My NestJS home API calls the service when I press a scan button in the dashboard or on the Dashy start page.
  • The scanfile operation runs a batch script with the category from the request body. The category, such as a person's name, becomes the subfolder under the scan directory.
  • The killprocess operation runs a second batch script that stops processes by name. It exists because NAPS2 has to be stopped cleanly between scans.
  • The service is registered through node-windows under the name Home Setup Windows Service, with install and uninstall scripts.
  • There is also a standalone batch script for scanning without the service, and a Linux version that uses scanimage and ImageMagick.
  • The scan directory comes from a setting. If it is not set, it falls back to C:\SCANS or ~/Documents/Scans.

Reliability and performance

  • The service runs unattended as a Windows service and not as a script in a window.
  • The killprocess operation clears a stuck scanner process, so the next scan can start.
  • NAPS2.Console is usually not on the PATH, and the README says so, with the fix.
  • When a service starts NAPS2, it loads no profile. I ship an example profile named after the scanner, so the scan works in service mode.
  • A GET /alive route lets other tools check that the service is running.

Outcomes

  • A physical scanner works as a service that I can start from anywhere on my network.
  • One button press in the dashboard produces a sorted PDF in my archive.
  • The two NAPS2 failure cases are documented with fixes.
  • The same interface also exists for Linux.

Known gaps

  • I have no numbers for scan time or how many pages it handles.
  • I have not described any login for the API, so I do not claim the service is safe outside a trusted network.
  • The Linux version is a variant. I do not say how much I use it.
  • It works with one scanner model, the Canon DR-C230. I have not tested others.
  • I do not say which licence the repository uses.

Get in touch

Hiring for architecture, technical leadership or applied AI engineering?

I answer questions about any of the case studies in detail, including the parts the source material does not cover.