feat(jira): watch_issues reports what changed on a set of tickets (1.4.0)
Given up to 50 keys and an instant, returns the issues updated since with their status, new comments (author id, plain-text body, own comments flagged) and status transitions, plus the instance's own account. JQL dates are converted to the account's time zone; malformed keys are never queried; a deleted key falls back to per-key reads instead of failing the batch. get_comments gains order, start_at and author_id, and decodes HTML entities. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -142,24 +142,46 @@ def adf(text):
|
||||
"content": [{"type": "paragraph", "content": [{"type": "text", "text": text}]}]}
|
||||
|
||||
|
||||
def _html_text(rendered):
|
||||
t = re.sub(r"(?i)<br\s*/?>", "\n", str(rendered))
|
||||
t = re.sub(r"(?i)</(p|div|li|h[1-6]|tr|blockquote|pre)>", "\n", t)
|
||||
t = re.sub(r"<[^>]+>", "", t)
|
||||
t = html.unescape(t)
|
||||
t = re.sub(r"[ \t\r\f\v]+\n", "\n", t)
|
||||
return re.sub(r"\n{3,}", "\n\n", t).strip()
|
||||
|
||||
|
||||
def _body_text(comment):
|
||||
rendered = comment.get("renderedBody")
|
||||
if rendered:
|
||||
return re.sub(r"<[^>]+>", "", str(rendered))
|
||||
return _html_text(rendered)
|
||||
raw_body = comment.get("body")
|
||||
if isinstance(raw_body, str):
|
||||
return raw_body
|
||||
return ""
|
||||
|
||||
|
||||
def _user_id(u):
|
||||
# Cloud identifies a user by accountId; On-Prem by key, then name.
|
||||
u = u or {}
|
||||
return str(u.get("accountId") or u.get("key") or u.get("name") or "")
|
||||
|
||||
|
||||
def main():
|
||||
inputs = json.loads(os.environ.get("INTEGRATION_INPUTS", "{}"))
|
||||
raw_ref = str(inputs.get("issue_id") or "") or str(inputs.get("issue_key") or "")
|
||||
ref = issue_ref(inputs)
|
||||
limit = inputs.get("limit") or 50
|
||||
order = str(inputs.get("order") or "oldest").strip().lower()
|
||||
if order not in ("oldest", "newest"):
|
||||
raise Exception("order is oldest or newest, not " + order)
|
||||
start_at = inputs.get("start_at")
|
||||
start_at = int(start_at) if str(start_at or "").strip() != "" else 0
|
||||
|
||||
res = request("GET", "/rest/api/" + _api() + "/issue/" + ref + "/comment",
|
||||
params={"maxResults": limit, "expand": "renderedBody"})
|
||||
params={"maxResults": limit, "startAt": start_at,
|
||||
"orderBy": "-created" if order == "newest" else "created",
|
||||
"expand": "renderedBody"})
|
||||
|
||||
comments = []
|
||||
for c in res.get("comments", []) or []:
|
||||
@@ -167,13 +189,15 @@ def main():
|
||||
"id": c.get("id", ""),
|
||||
"body": _body_text(c),
|
||||
"author": c.get("author", {}).get("displayName", ""),
|
||||
"author_id": _user_id(c.get("author")),
|
||||
"created": c.get("created", ""),
|
||||
"updated": c.get("updated", ""),
|
||||
"update_author": c.get("updateAuthor", {}).get("displayName", ""),
|
||||
})
|
||||
|
||||
print(json.dumps({"issue": raw_ref, "comments": comments}))
|
||||
|
||||
total = int(res.get("total") or 0)
|
||||
print(json.dumps({"issue": raw_ref, "comments": comments, "total": total,
|
||||
"next_start_at": start_at + len(comments) if start_at + len(comments) < total else None}))
|
||||
|
||||
try:
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user