humhub: mail-send loest Empfaenger zu GUIDs auf #10

Merged
sko merged 3 commits from fix/humhub-mail-guid into main 2026-09-25 11:07:45 +02:00
2 changed files with 34 additions and 10 deletions
Showing only changes of commit 57c1910734 - Show all commits

No files matched your search

+7
View File
@@ -102,6 +102,13 @@ und Wiki-Seiten.
Empfänger sind Benutzername, Profil-URL oder numerische ID; mehrere mit Komma. Empfänger sind Benutzername, Profil-URL oder numerische ID; mehrere mit Komma.
**`recipient` will GUIDs, keine User-IDs.** `mail-send` löst jede Angabe
deshalb bis zur GUID auf (`/user/<id>` liefert sie, die Benutzerliste je nach
Fassung nicht). Mit numerischen IDs antwortet die API `400 Validation failed`
und „Du kannst keine Nachricht ohne Empfänger senden!" — die Meldung klingt
nach einem leeren Feld, obwohl das Feld gefüllt ist, und weist damit in die
falsche Richtung.
`mail-reply` hängt einen Beitrag an eine bestehende Konversation `mail-reply` hängt einen Beitrag an eine bestehende Konversation
(`POST /mail/<id>/entry`). Die ID steht in der URL der Konversation: (`POST /mail/<id>/entry`). Die ID steht in der URL der Konversation:
`…/mail/mail/index?id=35`. `…/mail/mail/index?id=35`.
+27 -10
View File
@@ -350,8 +350,25 @@ def cmd_comment_create(args: argparse.Namespace) -> None:
# ── Mail (Direktnachrichten) ───────────────────────────────────────────────── # ── Mail (Direktnachrichten) ─────────────────────────────────────────────────
def resolve_user(session: requests.Session, value: str) -> int: def user_guid(session: requests.Session, user: dict) -> str:
"""Resolve a user ID, username, or profile URL (…/u/<slug>/) to a user ID. """GUID eines Benutzers, notfalls über /user/<id> nachgeladen.
Die Benutzerliste liefert die GUID je nach Fassung nicht mit.
"""
guid = user.get("guid") or (user.get("account") or {}).get("guid")
if guid:
return str(guid)
uid = user.get("id") or (user.get("account") or {}).get("id")
return str(api_get(session, f"/user/{uid}")["guid"])
def resolve_user(session: requests.Session, value: str) -> str:
"""Resolve a user ID, username, or profile URL (…/u/<slug>/) to a user GUID.
**GUID, nicht ID.** `POST /mail` nimmt als `recipient` ausschließlich
GUIDs an; mit numerischen IDs antwortet die API `400 Validation failed`
und „Du kannst keine Nachricht ohne Empfänger senden!" — eine Meldung,
die nach einem leeren Feld klingt, obwohl das Feld gefüllt ist.
Slug und Benutzername sind nicht dasselbe: zu https://…/u/serge/ gehört der Slug und Benutzername sind nicht dasselbe: zu https://…/u/serge/ gehört der
Benutzername "Serge". `get-by-username` kennt nur den Benutzernamen und Benutzername "Serge". `get-by-username` kennt nur den Benutzernamen und
@@ -360,7 +377,7 @@ def resolve_user(session: requests.Session, value: str) -> int:
""" """
value = value.strip() value = value.strip()
if value.isdigit(): if value.isdigit():
return int(value) return user_guid(session, {"id": int(value)})
name = value name = value
if "/" in value: if "/" in value:
teile = [t for t in urlparse(value).path.split("/") if t] teile = [t for t in urlparse(value).path.split("/") if t]
@@ -370,7 +387,7 @@ def resolve_user(session: requests.Session, value: str) -> int:
r = session.get(f"{BASE_URL}/user/get-by-username", r = session.get(f"{BASE_URL}/user/get-by-username",
params={"username": name}) params={"username": name})
if r.ok: if r.ok:
return int(r.json()["id"]) return user_guid(session, r.json())
page = 1 page = 1
while True: while True:
@@ -381,7 +398,7 @@ def resolve_user(session: requests.Session, value: str) -> int:
slug_teile = [t for t in urlparse(u.get("url", "")).path.split("/") if t] slug_teile = [t for t in urlparse(u.get("url", "")).path.split("/") if t]
slug = slug_teile[-1] if slug_teile else "" slug = slug_teile[-1] if slug_teile else ""
if name.lower() in (username.lower(), slug.lower()): if name.lower() in (username.lower(), slug.lower()):
return int(u["id"]) return user_guid(session, u)
if len(results) < 50: if len(results) < 50:
break break
page += 1 page += 1
@@ -390,17 +407,17 @@ def resolve_user(session: requests.Session, value: str) -> int:
def cmd_mail_send(args: argparse.Namespace) -> None: def cmd_mail_send(args: argparse.Namespace) -> None:
session, _ = get_session() session, _ = get_session()
ids = [resolve_user(session, teil) for teil in args.to.split(",") if teil.strip()] guids = [resolve_user(session, teil) for teil in args.to.split(",") if teil.strip()]
if not ids: if not guids:
sys.exit("Error: kein Empfänger angegeben") sys.exit("Error: kein Empfänger angegeben")
message = read_file(args.file) message = read_file(args.file)
data = api_post(session, "/mail", { data = api_post(session, "/mail", {
"title": args.title, "title": args.title,
"message": message, "message": message,
"recipient": ids, "recipient": guids,
}) })
empfaenger = ", ".join(str(i) for i in ids) empfaenger = ", ".join(guids)
print(f"Nachricht gesendet (Konversation {data.get('id')}) an Benutzer {empfaenger}") print(f"Nachricht gesendet (Konversation {data.get('id')}) an {empfaenger}")
def cmd_mail_reply(args: argparse.Namespace) -> None: def cmd_mail_reply(args: argparse.Namespace) -> None: