Skip to content

Repository files navigation

JobBot

Suchergebnisse

JobBot ist ein experimentelles Projekt, das mit Unterstützung von Codex entstanden ist und für die Jobsuche in Deutschland verwendet werden kann. Die Anwendung bietet eine WPF-Oberfläche, durchsucht konfigurierbare Stellenquellen und speichert gefundene Jobs lokal in einer SQLite-Datenbank.

Der Bot ist als vorsichtiger Job-Aggregator gebaut, nicht als aggressiver Scraper:

  • modulare Provider-Schnittstelle für Stellenquellen
  • Provider für Arbeitsagentur und Remotive
  • vorbereitete API-Provider für Adzuna und Jooble
  • konfigurierbare Suchbegriffe, Standorte und Remote-Regeln
  • Scoring mit stärker gewichteten Titel-Treffern und Keyword-Auswertung
  • SQLite-Datenbank für Duplikaterkennung, Historie und Angeschaut-Status
  • HTML- und CSV-Ergebnisdateien
  • WPF-Viewer zum Anzeigen, Suchen, Öffnen und Markieren von Stellen
  • optionaler Dauerlauf oder Windows-Aufgabenplanung
  • xUnit-Testprojekt

Voraussetzungen

  • Windows
  • .NET 8 Runtime oder SDK

Installation und Releases

Release-Builds werden über GitHub Actions auf Windows gebaut. Der Workflow erzeugt ein MSIX-Paket aus JobBot.Package und stellt es als Build-Artefakt bereit.

Öffentliche Release-Pakete sollen über SignPath Foundation signiert werden, sobald das Projekt dafür freigegeben ist. Bis dahin können MSIX-Pakete für Tests manuell über SignPath signiert werden. Selbstsignierte Testzertifikate sind nur für lokale Tests gedacht und müssen auf Zielsystemen vorher als vertrauenswürdig installiert werden.

Ein unsigned MSIX oder ein MSIX mit selbstsigniertem Testzertifikat ist nicht für eine öffentliche Weitergabe an Endnutzer vorgesehen.

Start

Einmaliger Lauf:

dotnet run --project JobBot.csproj -- --once

Standardmäßig läuft der Bot einmalig, weil schedule.enabled in appsettings.json auf false steht.

Beim ersten Start wird die Vorlage appsettings.json aus dem Projektordner nach %LOCALAPPDATA%\Richter JobBot\appsettings.json kopiert. Danach arbeitet der Bot standardmäßig mit dieser aktiven Benutzer-Konfiguration.

Viewer

Der Viewer liegt im Projekt JobBotViewer.

Start aus dem Projektordner:

dotnet run --project .\JobBotViewer\JobBotViewer.csproj

Im Viewer kannst du:

  • gespeicherte Ergebnisse aus der SQLite-Datenbank neu laden
  • eine Suche starten
  • Links öffnen
  • Stellen als Angeschaut markieren
  • Stellen wieder auf Neu setzen
  • Sucheinstellungen bearbeiten; Änderungen werden beim Verlassen des Tabs automatisch gespeichert
  • im Tab Einstellungen zwischen Light und Dark wechseln

Die Aktionsbuttons in der oberen Leiste sind nur im Tab Ergebnisse aktiv.

Neu bedeutet: Der Eintrag ist noch nicht als angeschaut markiert. Der Status bleibt Neu, bis du ihn selbst auf Angeschaut setzt.

Der Viewer ist nach MVVM aufgebaut:

  • MainWindow.xaml: Oberfläche
  • ViewModels/MainWindowViewModel.cs: Viewer-Logik
  • ViewModels/JobRowViewModel.cs: Tabellenzeilen
  • Infrastructure/RelayCommand.cs: Button-Commands
  • App.xaml.cs: zentrale Fehlerbehandlung für Viewer-Fehler

Die Ergebnis-Tabelle zeigt Remote nur noch als Hinweis, zum Beispiel Hybrid, Homeoffice möglich, Mobiles Arbeiten, Remote möglich oder Full Remote. Eine Remote-Prozent-Spalte gibt es nicht mehr, weil die Datenquellen dafür zu selten verlässliche Prozentwerte liefern.

Täglicher Betrieb

Variante A: Windows-Aufgabenplanung

Empfohlen für den Anfang. Nach dem Veröffentlichen kann die EXE per Aufgabenplanung gestartet werden:

dotnet publish JobBot.csproj -c Release --no-self-contained
.\bin\Release\net8.0\JobBot.exe "%LOCALAPPDATA%\Richter JobBot\appsettings.json" --once

Das mitgelieferte Script richtet eine tägliche Aufgabe ein:

powershell -ExecutionPolicy Bypass -File .\install-scheduled-task.ps1

Ohne expliziten Namen legt das Script die Aufgabe mit Uhrzeit im Namen an, zum Beispiel JobBot Daily 08-00. Eine andere Uhrzeit oder ein eigener Name sind möglich:

powershell -ExecutionPolicy Bypass -File .\install-scheduled-task.ps1 -RunAt "07:30"
powershell -ExecutionPolicy Bypass -File .\install-scheduled-task.ps1 -TaskName "JobBot Daily Arbeitstag" -RunAt "07:30"

Variante B: Dauerlauf

Setze in der aktiven %LOCALAPPDATA%\Richter JobBot\appsettings.json:

"schedule": {
  "enabled": true,
  "runAtLocalTime": "08:00"
}

Dann wartet der Bot im Prozess bis zur nächsten geplanten Uhrzeit und läuft danach täglich.

Speicherorte

Standardmäßig werden Laufzeitdaten nicht im Projektordner gespeichert:

  • aktive Konfiguration: %LOCALAPPDATA%\Richter JobBot\appsettings.json
  • SQLite-Datenbank: %LOCALAPPDATA%\Richter JobBot\jobbot.sqlite
  • Ergebnisdateien: %LOCALAPPDATA%\Richter JobBot\results

Im Projektordner entstehen beim Entwickeln/Bauen weiterhin technische Ordner wie bin, obj, .vs.

Datenschutz

JobBot überträgt Suchbegriffe, Orte und technische Abfrageparameter an die jeweils aktivierten Stellenquellen. Dazu gehören in der Standardkonfiguration insbesondere die Jobsuche der Bundesagentur für Arbeit; weitere Quellen wie Remotive, Adzuna oder Jooble werden nur genutzt, wenn sie in der Konfiguration aktiviert sind.

Gefundene Stellen werden lokal in einer SQLite-Datenbank gespeichert. Gespeichert werden unter anderem Provider, Job-ID, Titel, Firma, Ort, URL, Funddatum, Match-Score, erkannte Remote-/Homeoffice-Hinweise, Keyword-Begründungen und der lokale Angeschaut-Status.

JobBot betreibt keinen eigenen Serverdienst und lädt die lokale SQLite-Datenbank nicht an den Projektentwickler hoch. Bei aktivierten externen API-Providern gelten zusätzlich die Datenschutzbedingungen der jeweiligen Anbieter.

Konfiguration

Die wichtigsten Bereiche in appsettings.json:

  • search.terms: Suchbegriffe wie WinForms Entwickler, WPF Entwickler, .NET Desktop Entwickler
  • search.locations: Orte oder Regionen für die Suche
  • search.remoteMode: Any, HybridOrRemote oder RemoteOnly
  • search.requireRemoteOutsideLocalLocations: wenn true, werden außerhalb lokaler Orte Remote-/Homeoffice-Hinweise verlangt
  • search.localLocationsWithoutRemoteRequirement: Orte, die auch ohne Remote-Hinweis akzeptiert werden, aktuell Berlin
  • search.maxResultsPerProviderRun: maximale Roh-Treffer pro Provider-Lauf
  • scoring.minimumMatchPercent: Mindestscore für die Ausgabe, aktuell 30
  • scoring.titleWeight: Gewicht für Keyword-Treffer im Titel, aktuell 2.2
  • scoring.descriptionWeight: Gewicht für Keyword-Treffer in der Beschreibung, aktuell 1.0
  • scoring.remoteBonus: Bonus bei Remote-/Homeoffice-Hinweis
  • providers.arbeitsagentur: Arbeitsagentur-Quelle aktivieren, Page-Limit, Wartezeit und Detailabrufe steuern
  • providers.remotive: Remotive-Quelle aktivieren und Kategorie/Limit steuern
  • providers.adzuna: Adzuna mit appId und appKey aktivieren
  • providers.jooble: Jooble mit apiKey aktivieren
  • storage.sqlitePath: Speicherort der SQLite-Datenbank
  • reporting.outputDirectory: Ordner für HTML-/CSV-Ergebnisse
  • viewer.theme: Light oder Dark für den WPF-Viewer

Relative Pfade in der aktiven Settings-Datei werden relativ zur Settings-Datei aufgelöst. Windows-Variablen wie %LOCALAPPDATA% werden ebenfalls aufgelöst.

Scoring

Das Scoring bewertet die fachliche Passung eines Jobs.

Wichtige Regeln:

  • Pflichtkeywords werden in Titel und Beschreibung gesucht.
  • Treffer im Titel zählen stärker als Treffer in der Beschreibung.
  • Starke Keywords wie winforms, windows forms, wpf, .net desktop erhöhen den Score deutlich.
  • Unterstützende Keywords wie c#, .net, sql, mvvm, visual studio erhöhen den Score moderat.
  • Negative Keywords wie java, php, praktikum, ausbildung schließen einen Job aus.
  • Remote-/Homeoffice-Hinweise geben einen Bonus, ersetzen aber keine fachliche Passung.

Die Begründungen werden in Console-, CSV-, HTML-Ausgabe und Viewer angezeigt, zum Beispiel:

  • title: wpf
  • description: windows forms
  • description support: c#
  • remote/hybrid signal
  • excluded keyword: ausbildung

Ergebnisdateien

Nach jedem Lauf entstehen standardmäßig:

  • %LOCALAPPDATA%\Richter JobBot\results\latest-results.html
  • %LOCALAPPDATA%\Richter JobBot\results\latest-results.csv
  • %LOCALAPPDATA%\Richter JobBot\results\yyyy-MM-dd-results.html
  • %LOCALAPPDATA%\Richter JobBot\results\yyyy-MM-dd-results.csv
  • %LOCALAPPDATA%\Richter JobBot\results\latest-fetched.csv
  • %LOCALAPPDATA%\Richter JobBot\results\yyyy-MM-dd-fetched.csv
  • %LOCALAPPDATA%\Richter JobBot\results\latest-provider-debug.csv
  • %LOCALAPPDATA%\Richter JobBot\results\yyyy-MM-dd-provider-debug.csv

latest-results.* enthält die finalen Treffer.

latest-fetched.csv enthält alle nicht ausgeschlossenen gefundenen Jobs inklusive Score, Provider, Link, Gründen und ob der Job in den finalen Treffern enthalten war. Diese Datei ist hilfreich, um Suchbegriffe und Scoring nachzuschärfen.

latest-provider-debug.csv zeigt pro Provider-Abfrage Suchbegriff, Ort, Seite, HTTP-Status, Anzahl der zurückgegebenen Rohjobs und einen gekürzten Response-Ausschnitt.

latest-fetched.csv wird standardmäßig nur aktualisiert, wenn der Lauf wirklich Jobs geholt hat. Dadurch überschreibt ein Netzwerkfehler oder leerer Lauf nicht die letzte brauchbare Diagnose-Datei. Die datierte yyyy-MM-dd-fetched.csv wird trotzdem für jeden Lauf geschrieben.

Quellen

Aktuell eingebaut:

  • ArbeitsagenturJobProvider: nutzt die Jobsuche-Schnittstelle der Arbeitsagentur. Kein eigener API-Key des Nutzers erforderlich.
  • RemotiveJobProvider: nutzt die öffentliche Remotive Remote-Jobs-API. Aktuell in der Standardkonfiguration deaktiviert.
  • AdzunaJobProvider: vorbereitet für die Adzuna Jobs API. Trage appId und appKey ein und setze enabled auf true.
  • JoobleJobProvider: vorbereitet für die Jooble REST API. Trage apiKey ein und setze enabled auf true.

LinkedIn und XING werden bewusst nicht direkt automatisiert, weil deren öffentliche APIs nicht für freie Jobsuche gedacht sind und automatisiertes Scraping gegen deren Regeln laufen kann.

Arbeitsagentur-Provider

Der Arbeitsagentur-Provider ist vorsichtig gekapselt:

  • Suchseiten werden sequenziell und mit konfigurierbarer Pause geladen.
  • Treffer werden nach Provider + ProviderJobId dedupliziert.
  • Detailabrufe passieren erst nach der Deduplizierung, damit derselbe Job nicht mehrfach detailliert geladen wird.
  • HTTP-Fehler bei Suchseiten werden in der Provider-Debug-Datei sichtbar.

Die Bundesagentur selbst bietet nach aktuellem Stand keine offiziell garantierte Public-API für Drittanwendungen an. Deshalb sollte der Adapter leicht austauschbar bleiben.

Datenbank

Die SQLite-Datenbank wird automatisch angelegt. Sie speichert:

  • Provider und Job-ID
  • Titel, Firma, Ort, URL
  • erstes und letztes Funddatum
  • letzten Match-Score
  • erkannten Remote-/Homeoffice-Hinweis
  • letzte Begründung/Keyword-Treffer
  • is_viewed: bleibt false, bis du die Stelle im Viewer als angeschaut markierst

Die Duplikaterkennung basiert auf Provider + ProviderJobId.

Tests

Das Testprojekt liegt in JobBot.Tests und nutzt xUnit.

Tests ausführen:

dotnet test .\JobBot.Tests\JobBot.Tests.csproj

Aktuell werden unter anderem getestet:

  • Scoring inklusive Titelgewichtung und Pflichtkeywords im Titel
  • Remote-Hinweis-Erkennung
  • Settings-Laden und Pfadauflösung
  • Schedule-Berechnung
  • SQLite-Repository
  • Arbeitsagentur-Deduplizierung vor Detailabrufen
  • Runner-Deduplizierung und Provider-Warnungen

Provider erweitern

Neue Quellen implementieren IJobProvider:

public sealed class MyJobProvider : IJobProvider
{
    public string Name => "MyProvider";
    public bool Enabled => true;

    public Task<IReadOnlyList<JobPosting>> SearchAsync(
        SearchSettings search,
        CancellationToken cancellationToken)
    {
        // API abrufen, normalisierte JobPosting-Liste zurückgeben.
    }
}

Danach den Provider in Program.cs zur Providerliste hinzufügen.

Nächste sinnvolle Ausbaustufen

  • Neu fachlich getrennt von Angeschaut speichern, falls später beide Informationen separat gebraucht werden
  • Suchplan statt Kreuzprodukt aus terms x locations
  • Provider-Debug für Detailabrufe erweitern
  • zusätzliche Provider für Firmenkarriereseiten oder weitere Job-APIs
  • E-Mail- oder Desktop-Benachrichtigung
  • Profilgewichtung nach Wunsch-Arbeitsort, Gehalt oder Seniorität

About

Experimenteller JobBot für die Jobsuche in Deutschland mit WPF-Oberfläche, konfigurierbaren Stellenquellen, Keyword- Scoring und lokaler SQLite-Speicherung.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages