Ticket-System-Automation mit Python: REST-APIs, Libraries und praktische Patterns

2026-05-20

Überblick über Python-Clients und REST-API-Integrationen für Zammad, OTOBO und Znuny – von offiziellen Libraries bis zu eigenen Automatisierungs-Skripten.

Ticket-System-Automation mit Python: REST-APIs, Libraries und praktische Patterns

Python ist die Lingua Franca der Systemautomation – und bei Open-Source-Ticket-Systemen wie Zammad, OTOBO und Znuny (OTRS-Fork) bietet sich eine breite Palette an Integrationsoptionen. Dieser Artikel ordnet die verfügbaren Python-Clients, offiziellen APIs und bewährte Patterns für wiederkehrende Automatisierungsaufgaben ein.


Die drei Wege zur Python-Integration

AnsatzWann sinnvollKomplexität
Offizielle Python-Client-LibrarySchneller Einstieg, dokumentierte EndpointsNiedrig
Direct REST-API mit requestsVolle Kontrolle, Custom-Endpoints, DebuggingMittel
Wrapper/ETL-Frameworks (z. B. open-ticket-ai)Multi-System-Automation, Pipelines, RAGHoch

Zammad: Zammad-Py und die REST-API

Zammad-Py (Community-Client)

Die Library zammad_py bietet eine objektorientierte Schicht über die Zammad REST-API:

from zammad_py import ZammadAPI

client = ZammadAPI(
    url="https://helpdesk.example.com/api/v1",
    http_token="your_api_token"
)

# Tickets abrufen
for ticket in client.ticket.all():
    print(f"{ticket['number']}: {ticket['title']}")

# Ticket erstellen
ticket = client.ticket.create({
    "title": "Server-Alert: CPU-Load",
    "group": "IT-Operations",
    "customer": "monitoring@example.com",
    "article": {
        "subject": "Alert",
        "body": "CPU usage exceeded 90% on server-01",
        "type": "note",
        "internal": False
    }
})

Vorteile: Typische CRUD-Operationen abstrahiert, Fehlerhandling integriert, aktive Community.

Limitationen: Nicht alle API-Features (z. B. Core Workflows, Object-Manager-Changes) sind gemappt.

Direct REST-API mit requests

Für fortgeschrittene Szenarien (Webhooks, Tags, Time Accounting) empfiehlt sich direkter API-Zugriff:

import requests

headers = {
    "Authorization": "Bearer your_token",
    "Content-Type": "application/json"
}

# Suche mit Query
response = requests.get(
    "https://helpdesk.example.com/api/v1/tickets/search",
    headers=headers,
    params={"query": "state:new AND priority:3", "limit": 50}
)

# Bulk-Update mehrerer Tickets
tickets = response.json()["assets"]["Ticket"]
for ticket_id in tickets:
    requests.put(
        f"https://helpdesk.example.com/api/v1/tickets/{ticket_id}",
        headers=headers,
        json={"state": "open", "owner": "admin@example.com"}
    )

Ressourcen:


OTOBO & Znuny: Die OPM-Schnittstelle und GenericInterface

OTOBO und Znuny (als OTRS-Forks) nutzen eine ähnliche Architektur: Das GenericInterface bietet REST/SOAP-Webservices, die per Python ansprechbar sind.

Pattern: Session-basierte Authentifizierung

import requests

# 1. SessionToken erhalten
session_resp = requests.post(
    "https://otobo.example.com/otobo/rpc.pl",
    json={
        "UserLogin": "api_user",
        "Password": "api_pass"
    }
)
session_token = session_resp.json()["SessionID"]

# 2. Ticket erstellen
ticket_create = requests.post(
    "https://otobo.example.com/otobo/nph-genericinterface.pl/Webservice/TicketConnectorREST/Ticket",
    headers={"Authorization": f"Token {session_token}"},
    json={
        "Ticket": {
            "Title": "API-Generated Alert",
            "Queue": "IT-Support",
            "State": "new",
            "Priority": "3 normal",
            "CustomerUser": "monitoring"
        },
        "Article": {
            "Subject": "Automated Alert",
            "Body": "Alert details...",
            "ContentType": "text/plain; charset=utf8"
        }
    }
)

Python-Wrapper für OTOBO/Znuny

Im Vergleich zu Zammad gibt es weniger reife Python-Clients. Empfohlen wird:

  1. Eigener Thin-Client: 100-200 Zeilen Wrapper um requests für projektspezifische Endpoints
  2. Open Ticket AI: Framework mit unified Ticket-Modell für OTOBO, Znuny und Zammad

Ressourcen:


Praktische Automation-Patterns

Pattern 1: Monitoring → Ticket (Inbound)

def create_ticket_from_alert(alert_data: dict, system: str):
    """Unified interface für Zammad/OTOBO/Znuny"""
    
    if system == "zammad":
        return zammad_client.ticket.create({
            "title": alert_data["summary"],
            "group": "Monitoring",
            "article": {"body": alert_data["details"]}
        })
    elif system in ["otobo", "znuny"]:
        return otobo_session.post(
            f"/TicketConnectorREST/Ticket",
            json=map_alert_to_otobo(alert_data)
        )

Pattern 2: Ticket-Eskalation (Outbound)

def escalate_stale_tickets(system_client, hours_threshold: int = 24):
    """Findet und eskaliert Tickets ohne Agenten-Aktivität"""
    
    stale_tickets = system_client.search(
        query=f"state:open AND last_contact_agent:[* TO now-{hours_threshold}h]"
    )
    
    for ticket in stale_tickets:
        system_client.update(ticket["id"], {
            "priority": "high",
            "tags": ["auto-escalated"],
            "note": f"Automatisch eskaliert nach {hours_threshold}h Inaktivität"
        })

Pattern 3: Datenmigration (Cross-System)

# Zammad → OTOBO Migration
for ticket in zammad_client.ticket.all():
    mapped_ticket = {
        "Title": ticket["title"],
        "Queue": map_queue(ticket["group"]),
        "State": map_state(ticket["state"]),
        "CustomerUser": ticket["customer"]
    }
    otobo_client.ticket.create(mapped_ticket)

Error Handling und Resilience

Produktive Automation erfordert robustes Error Handling:

from tenacity import retry, stop_after_attempt, wait_exponential
import logging

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=4, max=10)
)
def safe_api_call(func, *args, **kwargs):
    try:
        return func(*args, **kwargs)
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 429:  # Rate Limit
            raise  # Trigger retry
        elif e.response.status_code == 401:
            logging.error("Authentication failed - check API token")
            raise
        else:
            logging.error(f"API Error: {e}")
            raise

DSGVO-Aspekte bei API-Automation

Beim automatisierten Zugriff auf Ticket-Daten beachten:

AspektEmpfehlung
API-Token-SpeicherungEnvironment-Variablen oder Secret Manager, nie im Code
LoggingKeine PII (Personenbezogene Daten) in Logs speichern
ZugriffsrechteService-Accounts mit minimalen Rechten (Least Privilege)
Rate-LimitingRespektieren, um keine Systemüberlastung zu verursachen
PseudonymisierungBei Weiterleitung an externe Systeme (z. B. KI-APIs)

Vergleich: Wann welches System?

Use CaseEmpfohlener EinstiegAnmerkung
Neues Python-Projekt, Zammadzammad_py + REST als FallbackCommunity-Client reicht für 80%
OTOBO/Znuny-IntegrationEigener requests-WrapperGenericInterface-Doku nutzen
Multi-System-AutomationOpen Ticket AI FrameworkEinheitliches Datenmodell
Prototyping/SchnelltestsJupyter Notebook + requestsDirektes API-Exploration
Produktive CronjobsPython-Skript + python-dotenv + LoggingRobustheit vor Eleganz

Fazit und nächste Schritte

Python-Automation für Ticket-Systeme ist kein „entweder-oder“ zwischen Client-Libraries und direkter REST-Nutzung. Die meisten Teams profitieren von einem Hybrid-Ansatz:

  1. Offizielle/Community-Libraries für Standardoperationen
  2. Direkte REST-Calls für Edge Cases und Debugging
  3. Eigene Abstraktionsschicht für Cross-System-Konsistenz

Wer tiefer einsteigen möchte, findet in unseren Plugin-Verzeichnissen für Zammad, OTOBO und Znuny passende Erweiterungen, die oft selbst Python-Integrationen mitbringen.


Dieser Artikel ist ein technisches Praxis-Summary. Für aktuelle API-Versionen und Breaking Changes konsultieren Sie die jeweiligen offiziellen Dokumentationen.