Merge branch 'v20260203-06-autotask-ticketnotes-child-endpoint' into main

This commit is contained in:
Ivo Oskamp 2026-02-06 13:23:31 +01:00
commit e5123952b2
4 changed files with 64 additions and 29 deletions

View File

@ -1 +1 @@
v20260203-04-autotask-resolve-user-note v20260203-06-autotask-ticketnotes-child-endpoint

View File

@ -522,38 +522,67 @@ class AutotaskClient:
def create_ticket_note(self, note_payload: Dict[str, Any]) -> Dict[str, Any]: def create_ticket_note(self, note_payload: Dict[str, Any]) -> Dict[str, Any]:
"""Create a TicketNote via POST /TicketNotes. """Create a TicketNote for a Ticket.
Note: Tenant support varies. Callers should handle AutotaskError(status_code=404) Autotask TicketNotes are a child collection of Tickets. In some tenants, creating notes via the
and implement a fallback if needed. root entity endpoint (POST /TicketNotes) is not supported, while creating via the parent ticket
""" child URL may work (POST /Tickets/{id}/TicketNotes).
if not isinstance(note_payload, dict): Callers can keep a fallback (for example updating the Ticket description) if both routes fail.
raise AutotaskError("Invalid ticket note payload.") """
if not isinstance(note_payload, dict):
raise AutotaskError("Invalid ticket note payload.")
try:
tid = int(note_payload.get("ticketID") or note_payload.get("ticketId") or 0)
except Exception:
tid = 0
if tid <= 0:
raise AutotaskError("Invalid ticketID in ticket note payload.")
title = str(note_payload.get("title") or "Backupchecks")
description = str(
note_payload.get("description")
or note_payload.get("note")
or note_payload.get("body")
or ""
)
pub_val = note_payload.get("publish")
# REST uses an integer picklist; in practice '1' corresponds to "ALL" / all Autotask users.
if isinstance(pub_val, bool):
publish = 1 if pub_val else 1
else:
try: try:
tid = int(note_payload.get("ticketID") or note_payload.get("ticketId") or 0) publish = int(pub_val) if pub_val is not None else 1
except Exception: except Exception:
tid = 0 publish = 1
if tid <= 0:
raise AutotaskError("Invalid ticketID in ticket note payload.")
data = self._request("POST", "TicketNotes", json_body=note_payload) child_payload = {
if isinstance(data, dict): "title": title,
if "item" in data and isinstance(data.get("item"), dict): "description": description,
return data["item"] "publish": publish,
if "items" in data and isinstance(data.get("items"), list) and data.get("items"): }
first = data.get("items")[0]
if isinstance(first, dict):
return first
if "id" in data:
return data
items = self._as_items_list(data) # Preferred: parent-child URL
if items: data = self._request("POST", f"Tickets/{tid}/TicketNotes", json_body=child_payload)
return items[0]
raise AutotaskError("Autotask did not return a created ticket note object.") if isinstance(data, dict):
if "item" in data and isinstance(data.get("item"), dict):
return data["item"]
if "items" in data and isinstance(data.get("items"), list) and data.get("items"):
first = data.get("items")[0]
if isinstance(first, dict):
return first
if "id" in data:
return data
items = self._as_items_list(data)
if items:
return items[0]
raise AutotaskError("Autotask did not return a created ticket note object.")
def get_ticket_note(self, note_id: int) -> Dict[str, Any]: def get_ticket_note(self, note_id: int) -> Dict[str, Any]:
"""Retrieve a TicketNote by ID via GET /TicketNotes/{id}.""" """Retrieve a TicketNote by ID via GET /TicketNotes/{id}."""
@ -773,4 +802,4 @@ class AutotaskClient:
# Respect limit if tenant returns more. # Respect limit if tenant returns more.
if limit and isinstance(limit, int) and limit > 0: if limit and isinstance(limit, int) and limit > 0:
return items[: int(limit)] return items[: int(limit)]
return items return items

View File

@ -1869,8 +1869,8 @@ def api_run_checks_autotask_resolve_note():
note_payload = { note_payload = {
"ticketID": ticket_id, "ticketID": ticket_id,
"title": "Backupchecks", "title": "Backupchecks",
"note": body, "description": body,
"publish": True, "publish": 1,
} }
created = client.create_ticket_note(note_payload) created = client.create_ticket_note(note_payload)
@ -2237,4 +2237,4 @@ def api_run_checks_mark_success_override():
except Exception: except Exception:
pass pass
return jsonify({"status": "ok", "message": "Override created."}) return jsonify({"status": "ok", "message": "Override created."})

View File

@ -487,6 +487,12 @@ Changes:
- Updated backend validation to only return success when the TicketNote is successfully created. - Updated backend validation to only return success when the TicketNote is successfully created.
- Aligned frontend success messaging with actual TicketNote creation in Autotask. - Aligned frontend success messaging with actual TicketNote creation in Autotask.
## v20260203-06-autotask-ticketnotes-child-endpoint
- Updated the Resolve action to create ticket notes using the Autotask child endpoint POST /Tickets/{TicketID}/Notes.
- Removed usage of the unsupported POST /TicketNotes endpoint.
- Ensured the created note is user-visible in Autotask and clearly marks the ticket as resolved by Backupchecks.
*** ***
## v0.1.21 ## v0.1.21