4.4 KiB
4.4 KiB
School Paperless Intake Workflow
Workflows:
n8n-workflows/18-school-paperless-intake.jsonn8n-workflows/19-paperless-school-metadata-enrichment.json
This workflow is meant for a Telegram chat-driven upload pipeline that sends schoolwork into Paperless-NGX while recording intake metadata in shared Postgres.
What it does
- Accepts a multipart upload at
POST /webhook/school/intake/upload - Requires form fields:
class_nameassignment_namesubmission_kind
- Accepts optional fields:
semestercourse_codepaper_kindnotessource(defaults totelegram)telegram_chat_idtelegram_message_id
- Generates a deterministic
intake_idfrom date + class + assignment + file checksum - Stores/updates the intake row in Postgres first
- Uploads the file to Paperless using the deterministic intake ID in the filename
- Marks the row as
uploadedafter Paperless accepts the upload
Shared Postgres expectations
- Use the shared Postgres network/credentials pattern already used by the automation stack.
- The workflow expects an n8n Postgres credential named
Shared Postgres. - Recommended target database:
school_intake - Tracked schema:
docs/reference/SCHOOL_INTAKE_POSTGRES_SCHEMA.sql
Required environment variables
Add to automation/.env:
PAPERLESS_BASE_URL=https://paperless.paccoco.com
PAPERLESS_API_TOKEN=CHANGE_ME
LITELLM_API_KEY=CHANGE_ME
PAPERLESS_CORRESPONDENT_SCHOOL=
PAPERLESS_DOCUMENT_TYPE_SCHOOL=
PAPERLESS_TAG_SCHOOL=
PAPERLESS_TAG_ASSIGNMENTS=
PAPERLESS_TAG_TELEGRAM=
NODE_FUNCTION_ALLOW_BUILTIN=crypto
Add to the n8n service environment: block in automation/docker-compose.yaml:
PAPERLESS_BASE_URL: ${PAPERLESS_BASE_URL}
PAPERLESS_API_TOKEN: ${PAPERLESS_API_TOKEN}
PAPERLESS_CORRESPONDENT_SCHOOL: ${PAPERLESS_CORRESPONDENT_SCHOOL}
PAPERLESS_DOCUMENT_TYPE_SCHOOL: ${PAPERLESS_DOCUMENT_TYPE_SCHOOL}
PAPERLESS_TAG_SCHOOL: ${PAPERLESS_TAG_SCHOOL}
PAPERLESS_TAG_ASSIGNMENTS: ${PAPERLESS_TAG_ASSIGNMENTS}
PAPERLESS_TAG_TELEGRAM: ${PAPERLESS_TAG_TELEGRAM}
NODE_FUNCTION_ALLOW_BUILTIN: crypto
Notes:
PAPERLESS_CORRESPONDENT_SCHOOLandPAPERLESS_DOCUMENT_TYPE_SCHOOLshould be numeric IDs if you want those fields auto-assigned.- Leave optional Paperless IDs blank if you prefer Paperless rules to classify later.
NODE_FUNCTION_ALLOW_BUILTIN=cryptois required because the Code node hashes the uploaded file.N8N_BLOCK_ENV_ACCESS_IN_NODEmust remainfalse.
Paperless metadata behavior
The upload uses:
- filename:
<intake_id>.<ext> - title:
<class_name> — <assignment_name> — <submission_kind>
Workflow 18 deliberately keeps the Paperless upload minimal and safe:
- multipart
document - deterministic title
The deterministic filename/title preserve the intake_id for later correlation.
Workflow 19 handles the follow-up metadata pass after Paperless finishes processing:
- fetch Paperless document by webhook document id
- resolve
intake_idfrom the stored filename - look up the intake record in shared Postgres
- re-apply deterministic title
- merge generic school tags plus optional class/submission-kind mappings
- optionally set document type / correspondent from JSON env mappings
Testing
Use the example curl request in:
n8n-workflows/fixtures/school-paperless-intake-webhook.curl.example.txt
Minimum test checklist:
- Import the workflow into n8n.
- Attach the
Shared Postgrescredential. - Confirm the target DB/table exists.
- Send the sample multipart request.
- Verify a row appears in
school_paperless_intakewithstatus=uploaded. - Verify the uploaded Paperless document title and stored filename both include the deterministic intake ID.
- Trigger workflow 19 with the Paperless document id and verify the row moves to
status=enriched. - Re-submit the same file and metadata to confirm the same
intake_idis reused and the Postgres row is upserted.
Known assumptions / caveats
- The workflow is repo-only and was not live-tested against the running n8n/Paperless stack.
- The Postgres node uses SQL expressions inline rather than parameter binding because exported n8n node JSON can differ by version.
- If your n8n build blocks
require('crypto'), addNODE_FUNCTION_ALLOW_BUILTIN=cryptoto the container env. - If Paperless needs tags as repeated
tags[]fields instead of a comma-separatedtagsfield, adjust the HTTP Request node after import.