← Commit history

Merge PR #45: chat send: stamp clientAssignedMessageId so agent-sent messages are detectable

Kyle Bergstedt ·b6ccef0bb4 ·2mo ago ·parent 6350c1d
2 files changed +20−4
SKILL.md+8
@@ -193,6 +193,14 @@ adom-google chat send --to <space-id|email> "here's the clip" --attach demo.webm #   attaches it. Repeatable for several files. Text is optional when attaching. Same #   chat.messages scope as a text post, so no re-consent. adom-google chat read --from <space-id|email> [--limit N] [--json]   # recent messages+#   Every post is stamped clientAssignedMessageId=client-agent-<20 hex> so the RECEIVING+#   side can tell an agent-sent message from a hand-typed one. Chat shows an "Adom Google"+#   attribution badge in the UI for anything posted through the API with user credentials,+#   but exposes that attribution NOWHERE in the REST API — not on Message/User/Annotation,+#   not in searchMessages filters, not in the Workspace Events payload, not in the Admin SDK+#   chat audit log. The marker is the only durable signal, and it is invisible in the UI.+#   Read it back with: adom-google api <message-url> | jq -r .clientAssignedMessageId+#   Suppress it with --no-agent-marker.  adom-google auth --admin   # ALSO request the Workspace ADMIN bundle in the SAME consent: #   admin.directory.group + .group.member + .user.readonly + apps.groups.settings.
bin/adom-google+12−4
@@ -789,11 +789,19 @@ def cmd_chat_send(a):     attachments = [_chat_upload(cfg, space, p) for p in (getattr(a, "attach", None) or [])]     if attachments:         body["attachment"] = [{"attachmentDataRef": ref} for ref in attachments]-    params = None+    params = {}     if a.thread:         body["thread"] = {"threadKey": a.thread}-        params = {"messageReplyOption": "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"}-    msg = _chat(cfg, f"{space}/messages", method="POST", body=body, params=params)+        params["messageReplyOption"] = "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"+    # Stamp agent-sent messages so the RECEIVING side can detect them exactly.+    # Google Chat renders an app-attribution badge ("Adom Google") in the UI for+    # anything posted through the API with user credentials, but exposes that+    # attribution NOWHERE in the REST API. A custom clientAssignedMessageId is+    # the only durable, machine-readable signal, and it is invisible in the UI.+    # Opt out with --no-agent-marker.+    if not getattr(a, "no_agent_marker", False):+        params["messageId"] = "client-agent-" + secrets.token_hex(10)+    msg = _chat(cfg, f"{space}/messages", method="POST", body=body, params=params or None)     uri = sp.get("spaceUri", "")     who = (msg.get("sender") or {}).get("displayName") or "you"     print(msg.get("name", "") + (f"  ·  {uri}" if uri else ""))@@ -1937,7 +1945,7 @@ def main():     ch = sub.add_parser("chat"); chx = ch.add_subparsers(dest="sub")     x = chx.add_parser("spaces"); x.add_argument("--json", action="store_true"); x.set_defaults(fn=cmd_chat_spaces)     x = chx.add_parser("dm"); x.add_argument("email"); x.add_argument("--json", action="store_true"); x.set_defaults(fn=cmd_chat_dm)-    x = chx.add_parser("send"); x.add_argument("--to", required=True, help="spaces/XXX id OR an email (auto-resolves the DM)"); x.add_argument("text", nargs="?", default="", help="message text, or '-' for stdin, or '@file' (optional when --attach is used)"); x.add_argument("--thread", help="threadKey for a threaded reply"); x.add_argument("--attach", action="append", metavar="PATH", help="attach a local file (image/video/PDF/any); repeatable"); x.set_defaults(fn=cmd_chat_send)+    x = chx.add_parser("send"); x.add_argument("--to", required=True, help="spaces/XXX id OR an email (auto-resolves the DM)"); x.add_argument("text", nargs="?", default="", help="message text, or '-' for stdin, or '@file' (optional when --attach is used)"); x.add_argument("--thread", help="threadKey for a threaded reply"); x.add_argument("--attach", action="append", metavar="PATH", help="attach a local file (image/video/PDF/any); repeatable"); x.add_argument("--no-agent-marker", action="store_true", help="don't stamp clientAssignedMessageId=client-agent-*"); x.set_defaults(fn=cmd_chat_send)     x = chx.add_parser("read"); x.add_argument("--from", dest="frm", required=True, help="spaces/XXX id OR an email"); x.add_argument("--limit", type=int, default=20); x.add_argument("--json", action="store_true"); x.set_defaults(fn=cmd_chat_read)      # Calendar (issue #662)