Zum Hauptinhalt springen
Paperless Guide: Secretary Bot

Paperless Guide: Secretary Bot

·790 Wörter·4 min
Tobias Schulz
Autor
Tobias Schulz
고생 끝에 낙이 온다 · immer, weiter
Inhaltsverzeichnis
Paperless Guide - Dieser Artikel ist Teil einer Serie.
Teil 7: Dieser Artikel

Es ist eine Weile her, seit ich zuletzt über mein papierloses Büro geschrieben habe. Denn mein System läuft und tut genau das, was es soll - seit nunmehr vielen Jahren. In der Zwischenzeit gab es jedoch zahlreiche Neuerungen bei Paperless-ngx, wie zum Beispiel die Arbeitsabläufe (Workflows) mit Webhooks und Nested Tags. Gerade Webhooks sind für mich enorm interessant, weil sie bei neuen, geänderten und gelöschten Dokumenten auslösen können.

Integration anderer Dienste
#

Mit Webhooks ist es endlich möglich, Paperless-ngx mit anderen Diensten zu verbinden. Gerade weil sie auch bei einem Update von Dokumenten auslösen können, lösten sie direkt meine Pre- und Post-Consume-Skripte ab. Diese setzte ich ein, um sehr einfach gestrickte Validierungen laufen zu lassen.

Diese neue Situation nahm ich mir zum Anlass, um meinen Paperless Secretary neu aufzubauen. Bislang handelte es sich hierbei um ein einfaches Python Skript, in dem ich Dokumenten-Filter und Aktionen definiert hatte. In den letzten Wochen ist ein kleiner Webservice entstanden, der als Docker Container bereitgestellt wird und - wer hätte es geahnt - auf HTTP-Anfragen wartet. Wie eben jene von den neuen Paperless-ngx Webhooks 😁.

Secretary v2
#

Der neue Paperless Secretary besteht aus zwei Bausteinen: dem Webservice, der die Anfragen entgegen nimmt. Und der Rules Engine, die konfigurierte Regelwerke aus Konfigurationsdateien liest, validiert und ausführt.

Verfügbarkeit
#

Source Code und Dokumentation stehen zum aktuellen Zeitpunkt nicht öffentlich zur Verfügung, da das Projekt noch sehr frisch ist und ich auf absehbare Zeit keinen Support leisten kann. Dennoch möchte ich die Gelegenheit nutzen und dir zeigen, wie man solche Webhooks einsetzen könnte.

Ich werde in den nächsten Monaten an genau dieser Stelle das Container Image veröffentlichen. Und zwar dann, wenn ich die Dokumentation auf Vordermann gebracht habe.

Regelwerke
#

Der Secretary hält ein Verzeichnis aus YAML Dateien, in denen komplexe Regeln vorgegeben werden können. Verwendest du Home Assistant ? Dann ist dir das Konzept sicher geläufig, denn ich habe mich beim Design der Regel-Notationen stark von Home Assistant Automationen inspirieren lassen. Denn eine Sache haben die Schöpfer vollkommen richtig gemacht: du kannst auf einen Blick herauslesen, was die Automation machen soll. Und genau das wollte ich für Regeln auch.

Eine Secretary Regel besteht immer aus ihrer Bezeichnung, Bedingungen (when) und Aktionen (exec). Bedingungen und Aktionen können beliebig viele Filter bzw. Aktionen ausführen. Und das macht es sehr dynamisch und spannend 😎.

Genug Theorie, sehen wir uns so eine Regel doch einfach mal an.

Regel-Kopf und Bedingungen:

- id: kontoauszug_bank_titel_check
  description: >
    Ziel: Titel => YYYY/MM
  when:
    - correspondent: "N26"
    - document_type: "Kontoauszug"
    - not:
        - title:
            regex: '^20\d{2}/(0[1-9]|1[0-2])$'
        - tags:
            contains: "Problem"

Gesucht werden mit dieser Regel Dokumente, deren Korrespondent N26 und Dokument-Typ Kontoauszug ist, die aber weder den Tag Problem noch einen Titel im Format YYYY/MM besitzen.

Aktionen anwenden:

  exec:
    - regex:
        field: content
        pattern: '\d{2}\.(\d{2})\.(\d{4}) bis \d{2}\.\1\.\2'
        result: "{{ m2 }}/{{ m1 }}"
        output: result_one
    - regex:
        field: content
        pattern: 'Depotauszug per \d{2}\.(\d{2})\.(\d{4})'
        result: "{{ m2 }}/{{ m1 }}"
        output: result_two
    - variable:
        match_result: >
          {%- if result_one is defined -%}
            {{ result_one }}
          {%- elif result_two is defined -%}
            {{ result_two }}
          {%- endif -%}
    - if:
        when:
          - template: "{{ match_result != '' }}"
        then:
          - set:
              title: "{{ match_result }}"
        else:
          - tag_add: "{{ tag('Problem') }}"
          - note: "Der korrekte Titel konnte nicht ermittelt werden."
    - save

Die Aktionen sind - mit Ausnahme der regulären Ausdrücke - eigentlich sofort verständlich. Machen wir dennoch einen kurzen Deep Dive:

  1. Der Inhalt des Dokuments wird nach einem Textmuster abgesucht, welches diese Form hat: 00.00.0000 bis 00.00.0000. Das Ergebnis wird zu 0000/00 transformiert und in result_one gespeichert.
  2. Erneut wird ein Textmuster mit dieser Form gesucht: Depotauszug per 00.00.0000. Das Ergebnis wird zu 0000/00 transformiert und in result_two gespeichert.
  3. In der Variable match_result wird der Fund eines Textmusters gespeichert.
  4. Wenn es einen Fund gab, wird der Titel des Dokuments gesetzt.
  5. Falls es keinen Fund gab, wird der Tag Problem gesetzt und eine Notiz am Dokument hinterlassen.
  6. Die Änderungen werden in Paperless-ngx gespeichert.

Für den Tag Problem habe ich mich entschieden, da ich etwas manuell nacharbeiten muss. Welche Tags ich wofür verwende, kannst du hier nachlesen.

Fazit
#

Warum ich so viel Aufwand betreibe? Die Antwort liegt auf der Hand: ich bin ein fauler Mensch und werde intrinsisch angetrieben, Abläufe zu optimieren und automatisieren. Ich müsste viele Dokumente per Hand selbst bearbeiten, damit sie zu meinen Ablagevorstellungen passen - also lasse ich das machen. So einfach ist das 😁.

Mittlerweile habe ich ein recht großes Regelwerk gebaut und bin unendlich zufrieden damit. Schade, dass in Paperless-ngx selbst keinerlei Möglichkeiten zur Verfügung stehen, Regelwerke einzubauen. Aber was nicht ist, kann ja schließlich noch werden.

Welche Use-Cases würdest du automatisiert gern in deinem papierlosen Büro umsetzen? Lass es mich wissen!


Das Titel-/Hintergrundbild stammt von Dhruvansh Soni auf Unsplash.

Paperless Guide - Dieser Artikel ist Teil einer Serie.
Teil 7: Dieser Artikel

Verwandte Artikel