feat(n8n): add school paperless intake pipeline
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
| 14 | Paperless Inbox Reminder | Scheduled (Monday 9 AM) | Queries Paperless for untagged documents; sends Gotify reminder with oldest items listed, or a ✅ clear if inbox is empty |
|
||||
| 15 | n8n Self-Health Monitor | Scheduled (every 15 min) | Checks n8n execution history for failures in the past hour; deduplicates via Postgres; pushes Gotify alert with workflow name and error summary |
|
||||
| 16 | NFS Mount Watchdog | Scheduled (every 5 min) | Probes NFS mount points on PD; if missing: runs mount script, re-probes, restarts affected containers (Plex, Audiobookshelf, Immich); notifies via Gotify on heal or escalation |
|
||||
| 18 | Telegram School Intake → Postgres → Paperless | `POST /webhook/school/intake/upload` | Accepts multipart schoolwork uploads plus class/assignment metadata, writes an intake record to shared Postgres, then uploads into Paperless with deterministic `intake_id` in the filename/title |
|
||||
| 19 | Paperless School Intake Metadata Enrichment | `POST /webhook/school/intake/paperless-enrich` | Handles Paperless post-consumption webhooks, looks up the intake record by deterministic filename, then applies deterministic title/tags and optional document-type/correspondent mapping |
|
||||
|
||||
## How to Import
|
||||
|
||||
@@ -67,9 +69,16 @@ Two steps required — both the `.env` file AND the `docker-compose.yaml` `envir
|
||||
|
||||
| Variable | Used by | How to get |
|
||||
|----------|---------|------------|
|
||||
| `PAPERLESS_API_TOKEN` | 04, 08 | Paperless → Settings → API token |
|
||||
| `PAPERLESS_API_TOKEN` | 04, 08, 18, 19 | Paperless → Settings → API token |
|
||||
| `PAPERLESS_TAG_TRANSCRIPTION` | 04 | Tag ID from Paperless API |
|
||||
| `PAPERLESS_TAG_LECTURE_NOTES` | 08 | Tag ID from Paperless API |
|
||||
| `PAPERLESS_TAG_SCHOOL` | 19 | Generic school tag ID from Paperless API |
|
||||
| `PAPERLESS_TAG_ASSIGNMENTS` | 19 | Generic assignments tag ID from Paperless API |
|
||||
| `PAPERLESS_TAG_TELEGRAM` | 19 | Tag ID for Telegram-submitted items |
|
||||
| `PAPERLESS_TAG_CLASS_MAP_JSON` | 19 | JSON object mapping class name → Paperless tag ID |
|
||||
| `PAPERLESS_TAG_SUBMISSION_KIND_MAP_JSON` | 19 | JSON object mapping submission kind → Paperless tag ID |
|
||||
| `PAPERLESS_DOCUMENT_TYPE_PAPER_KIND_MAP_JSON` | 19 | JSON object mapping paper kind → Paperless document type ID |
|
||||
| `PAPERLESS_CORRESPONDENT_CLASS_MAP_JSON` | 19 | JSON object mapping class name → Paperless correspondent ID |
|
||||
| `N8N_API_KEY` | 15 | n8n → Settings → API → Create API Key |
|
||||
| `LITELLM_API_KEY` | 01, 04, 08 | LiteLLM virtual key (already in .env) |
|
||||
|
||||
@@ -81,6 +90,13 @@ Two steps required — both the `.env` file AND the `docker-compose.yaml` `envir
|
||||
PAPERLESS_API_TOKEN: ${PAPERLESS_API_TOKEN}
|
||||
PAPERLESS_TAG_TRANSCRIPTION: ${PAPERLESS_TAG_TRANSCRIPTION}
|
||||
PAPERLESS_TAG_LECTURE_NOTES: ${PAPERLESS_TAG_LECTURE_NOTES}
|
||||
PAPERLESS_TAG_SCHOOL: ${PAPERLESS_TAG_SCHOOL}
|
||||
PAPERLESS_TAG_ASSIGNMENTS: ${PAPERLESS_TAG_ASSIGNMENTS}
|
||||
PAPERLESS_TAG_TELEGRAM: ${PAPERLESS_TAG_TELEGRAM}
|
||||
PAPERLESS_TAG_CLASS_MAP_JSON: ${PAPERLESS_TAG_CLASS_MAP_JSON}
|
||||
PAPERLESS_TAG_SUBMISSION_KIND_MAP_JSON: ${PAPERLESS_TAG_SUBMISSION_KIND_MAP_JSON}
|
||||
PAPERLESS_DOCUMENT_TYPE_PAPER_KIND_MAP_JSON: ${PAPERLESS_DOCUMENT_TYPE_PAPER_KIND_MAP_JSON}
|
||||
PAPERLESS_CORRESPONDENT_CLASS_MAP_JSON: ${PAPERLESS_CORRESPONDENT_CLASS_MAP_JSON}
|
||||
N8N_API_KEY: ${N8N_API_KEY}
|
||||
```
|
||||
|
||||
@@ -136,10 +152,11 @@ In Paperless-NGX, set up post-consumption webhooks to POST to:
|
||||
```
|
||||
https://n8n.paccoco.com/webhook/paperless/new-document
|
||||
https://n8n.paccoco.com/webhook/paperless/rag-ingest
|
||||
https://n8n.paccoco.com/webhook/school/intake/paperless-enrich
|
||||
```
|
||||
with body: `{"document_id": <id>}`
|
||||
|
||||
You can trigger both from the same Paperless event — workflow 03 classifies/tags the document, workflow 05 ingests it into RAG.
|
||||
You can trigger all three from the same Paperless event. Workflow 03 handles AI summary/tagging, workflow 05 handles RAG ingest, and workflow 19 re-applies deterministic school metadata for intake-managed documents.
|
||||
|
||||
### Grafana Webhook (already configured)
|
||||
|
||||
@@ -156,6 +173,19 @@ Works with Gitea, Forgejo, GitHub, and GitLab webhook payloads.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Upload schoolwork from Telegram intake:
|
||||
```bash
|
||||
curl -X POST https://n8n.paccoco.com/webhook/school/intake/upload \
|
||||
-F "document=@essay-draft.pdf" \
|
||||
-F "class_name=English 101" \
|
||||
-F "assignment_name=Essay Draft 1" \
|
||||
-F "submission_kind=homework" \
|
||||
-F "semester=Fall 2026" \
|
||||
-F "course_code=ENG101" \
|
||||
-F "paper_kind=essay"
|
||||
```
|
||||
|
||||
|
||||
### Ingest a document into RAG:
|
||||
```bash
|
||||
curl -X POST https://n8n.paccoco.com/webhook/rag/ingest \
|
||||
@@ -259,6 +289,20 @@ curl -X POST https://n8n.paccoco.com/webhook/git/push \
|
||||
}'
|
||||
```
|
||||
|
||||
## Workflow 18 — Telegram School Intake → Postgres → Paperless
|
||||
|
||||
Import `18-school-paperless-intake.json` for a chat-driven schoolwork intake flow. Supporting notes live at `docs/operations/SCHOOL_PAPERLESS_INTAKE.md` and the tracked schema lives at `docs/reference/SCHOOL_INTAKE_POSTGRES_SCHEMA.sql`.
|
||||
|
||||
Highlights:
|
||||
- multipart upload endpoint: `POST /webhook/school/intake/upload`
|
||||
- required fields: `class_name`, `assignment_name`, `submission_kind`
|
||||
- optional fields: `semester`, `course_code`, `paper_kind`, `notes`, `telegram_chat_id`, `telegram_message_id`
|
||||
- writes intake metadata to shared Postgres before upload
|
||||
- sends deterministic `intake_id` in the Paperless filename and title correlation data
|
||||
|
||||
Testing fixture:
|
||||
- `fixtures/school-paperless-intake-webhook.curl.example.txt`
|
||||
|
||||
## Customizing RSS Feeds (Workflow 06)
|
||||
|
||||
Edit the "Define RSS Feeds" Code node to add/remove feeds. Default feeds:
|
||||
|
||||
Reference in New Issue
Block a user