diff --git a/fs2zammad b/fs2zammad index a914be3..ee83d8e 100755 --- a/fs2zammad +++ b/fs2zammad @@ -5,6 +5,7 @@ import json import os import pickle import sys +import html2text from zammad_py import ZammadAPI from zammad_py.api import Resource, TagList, TicketArticle @@ -55,15 +56,20 @@ def get_zammad_session(impersonated_user=None): def maybe_create_zammad_user(userdata, zammad_session, attr="login", default=None): # Map disabled users (in RT) to mock user in Zammad. - if type(userdata) is str or "EmailAddress" not in userdata: + if type(userdata) is str and userdata.lower() in USERMAP: + email = userdata + elif type(userdata) is str or "EmailAddress" not in userdata: userdata = { 'EmailAddress': 'technik@ungleich.ch', 'RealName': 'Disabled RT' } + email = userdata["EmailAddress"] + elif "EmailAddress" in userdata: + email = userdata["EmailAddress"] + else: + raise ValueError("Invalid userdata") - email = userdata["EmailAddress"] lowercase_email = email.lower() - if lowercase_email not in USERMAP: kwargs = {"email": email} kwargs.update(config["userdata"]) @@ -95,6 +101,15 @@ def maybe_create_zammad_user(userdata, zammad_session, attr="login", default=Non return USERMAP[lowercase_email].get(attr, default) +# def ensure_user_is_zammad_agent(user, zammad_session): +# print(f"Promoting user {user} to Agent") +# id = maybe_create_zammad_user(user, zammad_session, "id") +# roles = maybe_create_zammad_user(user, zammad_session, "roles") +# if "Agent" not in roles: +# zammad_session.user.update( +# id, {"roles": roles.append("Agent")} +# ) + ### main logic ### if not os.path.exists("rt2zammad.json"): @@ -106,6 +121,7 @@ if not os.path.exists("rt2zammad.json"): with open("rt2zammad.json") as handle: config = json.load(handle) +h2t = html2text.HTML2Text() zammad = get_zammad_session() os.makedirs("users", exist_ok=True) @@ -188,33 +204,56 @@ for id in ticket_ids: # Attachments. files = [] + may_contain_entry_content = None for a, title in entry["Attachments"]: with open(f"attachments/{id}/{a}", "rb") as handle: data = pickle.load(handle) - if data["Filename"] in ("", "signature.asc"): + if data["Filename"] == "signature.asc": continue - files.append( - { + + file_template = { "filename": data["Filename"], "data": base64.b64encode(data["Content"]).decode("utf-8"), "mime-type": data["ContentType"], } - ) + if data["Filename"] == '': + if may_contain_entry_content is None: + may_contain_entry_content = file_template + else: + files.append(file_template) + # Comment/note. entry_creator = entry["Creator"] with open(f"users/{entry_creator}", "rb") as handle: rt_entry_creator = pickle.load(handle) - zammad_creator = maybe_create_zammad_user(rt_entry_creator, zammad) + zammad_entry_creator = maybe_create_zammad_user(rt_entry_creator, zammad) + entry_content = entry["Content"] + if entry_content == '' and may_contain_entry_content: + file = may_contain_entry_content + entry_content = base64.b64decode(file["data"]).decode("utf-8") + if file["mime-type"]: + entry_content = h2t.handle(entry_content) + zammad_entry_template = { "ticket_id": zammad_ticket["id"], - "body": entry["Content"], + "body": entry_content, "internal": entry["Type"] == "Comment", "attachments": files, } - try: - TicketArticle(get_zammad_session(zammad_creator)).create(zammad_entry_template) - except: - print(f"FIXME: Failed to add comment to ticket RT#{id}/Zammad#{zammad_ticket["id"]}: user permission issue?") + entry_creator_id = maybe_create_zammad_user(zammad_entry_creator, zammad, "id") + + # We temporarly change the ticket's creator to create a new entry + # without giving its author 'Agent' privileges. + restore_creator_to = None + if entry_creator_id != zammad_ticket["customer_id"]: + zammad_ticket = zammad.ticket.update(zammad_ticket["id"], {"customer_id": entry_creator_id}) + restore_creator_to = zammad_ticket["customer_id"] + + print(f"-> Adding a new entry/comment to ticket {zammad_ticket["id"]} ({zammad_entry_creator})...") + TicketArticle(get_zammad_session(zammad_entry_creator)).create(zammad_entry_template) + + if restore_creator_to != None: + zammad.ticket.update(zammad_ticket["id"], {"customer_id": restore_creator_to})