{"id":50831377,"url":"https://github.com/ammarlakis/paperless-wsd-bridge","last_synced_at":"2026-06-13T23:30:42.552Z","repository":{"id":360058790,"uuid":"1248501740","full_name":"ammarlakis/paperless-wsd-bridge","owner":"ammarlakis","description":"Paperless-ngx WSD Bridge","archived":false,"fork":false,"pushed_at":"2026-05-24T20:06:04.000Z","size":70,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-24T21:16:01.079Z","etag":null,"topics":["helm","kubernetes","paperless"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ammarlakis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T18:14:18.000Z","updated_at":"2026-05-24T20:06:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ammarlakis/paperless-wsd-bridge","commit_stats":null,"previous_names":["ammarlakis/paperless-wsd-bridge"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ammarlakis/paperless-wsd-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammarlakis%2Fpaperless-wsd-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammarlakis%2Fpaperless-wsd-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammarlakis%2Fpaperless-wsd-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammarlakis%2Fpaperless-wsd-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ammarlakis","download_url":"https://codeload.github.com/ammarlakis/paperless-wsd-bridge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ammarlakis%2Fpaperless-wsd-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34304627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["helm","kubernetes","paperless"],"created_at":"2026-06-13T23:30:41.869Z","updated_at":"2026-06-13T23:30:42.546Z","avatar_url":"https://github.com/ammarlakis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# paperless-wsd-bridge\n\nLocal WSD push-scan receiver for [Paperless-ngx](https://docs.paperless-ngx.com/).\n\nThis service registers scan profiles with a WSD-capable scanner, receives\npanel-initiated scan events, retrieves scanned images, builds PDFs, and uploads\nthem to Paperless through the REST API.\n\n## Project Status\n\nThis is an early, hardware-dependent project. It is tested with an Epson\nET-4850 and may need profile or SOAP-template adjustments for other scanners.\nOpen an issue with scanner model, profile, logs, and the failing WSD operation\nif another device behaves differently.\n\n## Features\n\n- WSD panel scanning into Paperless-ngx.\n- ConfigMap or directory-driven scan profiles.\n- ADF multi-page scans with `ImagesToTransfer=0`.\n- Auto source mode with ADF first and platen fallback.\n- Manual duplex workflow:\n  - `Paperless Duplex Fronts` stages the first pass.\n  - `Paperless Duplex Backs` scans the second pass, reverses backs, interleaves\n    pages, and uploads one PDF.\n- Durable spool directories for ready, failed, in-progress, uploaded, debug, and\n  duplex staging files.\n\n## Requirements\n\n- A WSD-capable scanner reachable from the bridge.\n- A callback URL that the scanner can reach on TCP port `6666`.\n- A Paperless-ngx API URL and API token.\n- Python 3.12 for local runs, or Docker/Kubernetes for containerized runs.\n\n## Configuration\n\nThe container reads scan profiles from `WSD_PROFILES_DIR`, which defaults to\n`/app/profiles`. Each profile is a YAML file. A minimal profile looks like this:\n\n```yaml\nid: paperless\nname: Paperless\ncolor: RGB24\nimage_format: jpeg\nformat: tiff-single-uncompressed\nquality: 85\ntarget_folder: /spool\nspool:\n  root: /spool\n  in_progress_dir: in-progress\n  ready_dir: ready\n  uploaded_dir: uploaded\n  failed_dir: failed\n  debug_dir: debug\n  keep_intermediates: false\n  debug_retrieve_payloads: false\npost_scan:\n  enabled: true\n  type: paperless_api\n  url_env: PAPERLESS_API_URL\n  token_env: PAPERLESS_API_TOKEN\n  timeout_seconds: 120\n  success_action: delete\n  failure_action: move\n  fields:\n    tags: []\nsend_email: false\nuse_pdf: true\nuse_default_ticket: false\nvalidate_scan_ticket: false\ncreate_scan_job_mode: minimal\npaper_size: A4\nresolution: 300\ninput_src: Auto\n```\n\nRequired runtime settings:\n\n| Variable | Purpose |\n| --- | --- |\n| `WSD_SCANNER_TARGET` | Scanner WSD endpoint, for example `http://scanner.example.local:80/WSD/DEVICE`. |\n| `WSD_CALLBACK_URL` | Full callback URL advertised to the scanner, for example `http://bridge.example.local:6666/wsd`. |\n| `PAPERLESS_API_URL` | Paperless base URL, without `/api/documents/post_document/`. |\n| `PAPERLESS_API_TOKEN` | Paperless API token used for upload. |\n| `WSD_PROFILES_DIR` | Directory containing profile YAML files. Defaults to `/app/profiles`. |\n\nOptional settings:\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `WSD_SCANNER_EP_REF` | unset | Known scanner endpoint reference. Leave unset unless discovery needs help. |\n| `WSD_LISTEN_HOST` | `0.0.0.0` | Callback server bind address. |\n| `WSD_LISTEN_PORT` | `6666` | Callback server bind port. |\n| `WSD_SUBSCRIPTION_TTL_SECONDS` | `900` | WSD event subscription TTL. |\n| `WSD_RENEW_INTERVAL_SECONDS` | `600` | Subscription renewal interval. |\n| `WSD_RETRY_MIN_SECONDS` | `10` | Initial reconnect delay. |\n| `WSD_RETRY_MAX_SECONDS` | `300` | Maximum reconnect delay. |\n\n## Docker\n\nBuild the image:\n\n```sh\ndocker build -t paperless-wsd-bridge .\n```\n\nRun it with profiles and spool storage mounted from the host:\n\n```sh\ndocker run --rm \\\n  -p 6666:6666 \\\n  -e WSD_SCANNER_TARGET=http://scanner.example.local:80/WSD/DEVICE \\\n  -e WSD_CALLBACK_URL=http://bridge.example.local:6666/wsd \\\n  -e PAPERLESS_API_URL=http://paperless.example.local:8000 \\\n  -e PAPERLESS_API_TOKEN=replace-me \\\n  -v \"$PWD/profiles:/app/profiles:ro\" \\\n  -v \"$PWD/spool:/spool\" \\\n  paperless-wsd-bridge\n```\n\n## Helm\n\nThe chart lives in `charts/paperless-wsd-bridge`.\n\nCreate a values file from the example:\n\n```sh\ncp charts/paperless-wsd-bridge/values.example.yaml my-values.yaml\n```\n\nSet at least:\n\n- `image.repository`\n- `scanner.target`\n- `callback.url`\n- `paperless.apiUrl`\n- `paperless.apiToken.existingSecret` or `paperless.apiToken.value`\n\nInstall:\n\n```sh\nhelm upgrade --install paperless-wsd-bridge \\\n  charts/paperless-wsd-bridge \\\n  --values my-values.yaml\n```\n\nProfiles are rendered from `profiles` values into a ConfigMap and mounted at\n`/app/profiles`.\n\n## Security Notes\n\n- Treat the Paperless API token as a secret. Prefer an existing Kubernetes\n  Secret over putting `paperless.apiToken.value` in a values file.\n- The WSD callback server is intended for a trusted local network. Do not expose\n  it to the public internet.\n- If `debug_retrieve_payloads` is enabled, retrieved image payloads are written\n  to the spool debug directory and may contain document contents.\n\n## Troubleshooting\n\n- The scanner must be able to connect back to `WSD_CALLBACK_URL`; this is often\n  the first problem to check.\n- If scans register but do not start, try setting `scanner.endpointReference`\n  from the scanner's WSD metadata.\n- If an ADF scan produces no pages in `Auto` mode, the bridge retries once with\n  `Platen`.\n- Failed uploads are moved to the failed spool when `failure_action: move` is\n  configured. Ready artifacts are retried on service start when profile metadata\n  is available.\n\n## Development\n\nInstall dependencies:\n\n```sh\npython3 -m venv .venv\n. .venv/bin/activate\npip install -r requirements.txt\n```\n\nBasic validation:\n\n```sh\npython3 -m compileall src\nhelm lint charts/paperless-wsd-bridge\nhelm template paperless-wsd-bridge charts/paperless-wsd-bridge\n```\n\nPrepare a release commit, changelog entry, tag, and push:\n\n```sh\njust release\n```\n\nPushing the release tag triggers the `Release` GitHub Actions workflow. The\nworkflow publishes:\n\n- a standalone Linux `amd64` release artifact,\n- a multi-arch GHCR Docker image for `linux/amd64` and `linux/arm64`, tagged\n  with the release version, `major.minor`, and `latest`,\n- a packaged Helm chart attached to the GitHub release as\n  `paperless-wsd-bridge-helm-\u003cversion\u003e.tgz`,\n- a Helm repository update by dispatching `ammarlakis/helm-charts`.\n\nUseful release overrides:\n\n```sh\nRELEASE_PUSH=false just release\nRELEASE_VERSION=0.1.7 just release\n```\n\nThe release command requires a clean working tree and uses `git-cliff` to build\n`CHANGELOG.md` from conventional commits. The Helm repository dispatch requires\nthe `UPDATE_REGISTRY_APP_PRIVATE_KEY` repository secret used by the GitHub App\nthat can run workflows in `ammarlakis/helm-charts`.\n\n## License\n\nGPL-3.0. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fammarlakis%2Fpaperless-wsd-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fammarlakis%2Fpaperless-wsd-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fammarlakis%2Fpaperless-wsd-bridge/lists"}