Skip to content

feat(chat): support file attachments in messages send#694

Open
omothm wants to merge 1 commit into
openclaw:mainfrom
omothm:feat/chat-send-attachments
Open

feat(chat): support file attachments in messages send#694
omothm wants to merge 1 commit into
openclaw:mainfrom
omothm:feat/chat-send-attachments

Conversation

@omothm
Copy link
Copy Markdown
Contributor

@omothm omothm commented Jun 4, 2026

Adds a repeatable --attach flag to chat messages send for uploading local files (e.g. images) alongside a message. Each file is uploaded through the Chat Media API to obtain an attachment data ref, then attached to the single Messages.Create call. --text becomes optional when at least one attachment is provided, so attachment-only messages are allowed.

No new OAuth scope is required — the existing chat.messages scope already authorizes the upload endpoint. Attachments render as image/file cards beneath the message (Chat's standard preview), not embedded inline in the text body.

Verification

The Chat command test suite covers the upload→ref→attach flow, attachment-only sends, and the no-text/no-attach validation error. make lint reports 0 issues.

Also exercised live against the real Chat API — a two-attachment message posted successfully. Redacted server response (auth tokens in downloadUri/thumbnailUri stripped):

$ gog --json --account <me> chat messages send spaces/<space> \
    --text "<message>" \
    --attach 20-e2etestcrs-FIXED-address-management.png \
    --attach 21-sbmmstestt-FIXED-address-management.png
{
  "message": {
    "name": "spaces/REDACTED/messages/9WtvBkoxp3k.9WtvBkoxp3k",
    "thread": { "name": "spaces/REDACTED/threads/9WtvBkoxp3k" },
    "createTime": "2026-06-04T19:09:42.621295Z",
    "sender": { "name": "users/REDACTED", "type": "HUMAN" },
    "attachment": [
      {
        "contentName": "20-e2etestcrs-FIXED-address-management.png",
        "contentType": "image/png",
        "source": "UPLOADED_CONTENT",
        "attachmentDataRef": { "resourceName": "REDACTED" },
        "downloadUri": "https://chat.google.com/api/get_attachment_url?...&attachment_token=REDACTED",
        "thumbnailUri": "https://chat.google.com/api/get_attachment_url?...&attachment_token=REDACTED"
      },
      {
        "contentName": "21-sbmmstestt-FIXED-address-management.png",
        "contentType": "image/png",
        "source": "UPLOADED_CONTENT",
        "attachmentDataRef": { "resourceName": "REDACTED" },
        "downloadUri": "https://chat.google.com/api/get_attachment_url?...&attachment_token=REDACTED",
        "thumbnailUri": "https://chat.google.com/api/get_attachment_url?...&attachment_token=REDACTED"
      }
    ]
  }
}

Both files came back as source: UPLOADED_CONTENT / contentType: image/png, confirming the upload→ref→attach path end to end.

🤖 Generated with Claude Code

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented Jun 4, 2026

Codex review: needs maintainer review before merge. Reviewed June 4, 2026, 4:39 PM ET / 20:39 UTC.

Summary
The PR adds a repeatable --attach flag to gog chat messages send, uploads each local file through Chat Media, attaches returned refs to the message create call, and updates command docs/tests.

Reproducibility: not applicable. this is a feature PR, not a bug report. Source inspection confirms current main has no --attach flag for chat messages send, while the PR adds that capability.

Review metrics: 1 noteworthy metric.

  • Changed files: 4 files changed, 190 additions, 6 deletions. The feature is bounded to Chat send implementation, helper code, generated command docs, and command tests.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • [P2] No repair lane is needed because no discrete patch defect was found; maintainers can continue normal review and CI gating.

Security
Cleared: The diff adds an explicit user-requested local-file upload path for Google Chat without new dependencies, workflow changes, or broader credential handling; no concrete security or supply-chain regression was found.

Review details

Best possible solution:

Land the focused --attach support after normal CI and maintainer review, preserving text-only behavior and the uploaded-attachment-ref flow covered by the added tests.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this is a feature PR, not a bug report. Source inspection confirms current main has no --attach flag for chat messages send, while the PR adds that capability.

Is this the best way to solve the issue?

Yes: using the generated Chat Media upload API and passing the returned attachmentDataRef values into one Messages.Create call is a narrow, maintainable fit for the requested feature.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3d5c9cef65fa.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied live command output and a redacted Chat API response showing two uploaded attachments returned as UPLOADED_CONTENT image/png entries.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied live command output and a redacted Chat API response showing two uploaded attachments returned as UPLOADED_CONTENT image/png entries.
  • remove rating: 🌊 off-meta tidepool: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority Google Chat CLI feature with limited blast radius, tests, and live API proof.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied live command output and a redacted Chat API response showing two uploaded attachments returned as UPLOADED_CONTENT image/png entries.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied live command output and a redacted Chat API response showing two uploaded attachments returned as UPLOADED_CONTENT image/png entries.
Evidence reviewed

What I checked:

  • Current main behavior: On current main, ChatMessagesSendCmd has only Space, Text, and Thread, and Run rejects empty text before creating the Chat service, so the requested attachment-send behavior is not already implemented. (internal/cmd/chat_messages.go:156, 3d5c9cef65fa)
  • PR implementation: The PR adds Attach []string, allows --text to be omitted when attachment paths exist, includes attachment paths in dry-run output, uploads files before Messages.Create, and sets message.Attachment from upload refs. (internal/cmd/chat_messages.go:156, 4c6675e43bc8)
  • Upload helper: The PR adds path expansion/validation and an ordered uploadChatAttachments helper that calls svc.Media.Upload(space, req).Media(f).Context(ctx).Do() and returns chat.Attachment values containing the upload data refs. (internal/cmd/chat_helpers.go:188, 4c6675e43bc8)
  • Test coverage: The PR adds tests for upload-to-message ref forwarding, attachment-only sends, and the no-text/no-attachment validation error. (internal/cmd/execute_chat_test.go:445, 4c6675e43bc8)
  • Live behavior proof: The PR body includes copied live gog --json ... chat messages send ... --attach ... --attach ... output and a redacted Chat API response showing two UPLOADED_CONTENT image/png attachments. (4c6675e43bc8)
  • Generated API surface: The pinned Google API client exposes MediaService.Upload, UploadAttachmentRequest.Filename, UploadAttachmentResponse.AttachmentDataRef, and Message.Attachment, matching the PR's implementation path. (google.golang.org/api/chat/v1/chat-gen.go:7923)

Likely related people:

  • steipete: Recent GitHub path history shows multiple Chat command validation and service-constructor changes, including the current main behavior around Chat command validation. (role: recent area contributor; confidence: high; commits: f03cd6ad07a3, dc81a136af3f, cd37734c99f9; files: internal/cmd/chat_messages.go, internal/cmd/chat_helpers.go, internal/googleapi/chat.go)
  • salmonumbrella: GitHub path history points to the original broad Chat support commit that introduced the Chat command area touched by this PR. (role: introduced behavior; confidence: medium; commits: 33685adafea1; files: internal/cmd/chat_messages.go, internal/cmd/chat_helpers.go, internal/googleapi/chat.go)
  • fernandopps: GitHub path history shows adjacent Google Chat message/reaction command work that touched the same Chat helpers and API surface. (role: adjacent feature contributor; confidence: medium; commits: 380d88c1a249; files: internal/cmd/chat_messages.go, internal/cmd/chat_helpers.go, internal/googleapi/chat.go)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. labels Jun 4, 2026
@omothm omothm marked this pull request as ready for review June 4, 2026 20:07
Add a repeatable --attach flag to `chat messages send` for uploading
local files (e.g. images) alongside a message. Each file is uploaded via
the Chat Media API to obtain an attachment data ref, then attached to the
single Messages.Create call. --text becomes optional when at least one
attachment is provided, so attachment-only messages are allowed.

No new OAuth scope is required: the existing chat.messages scope already
authorizes the upload endpoint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@omothm omothm force-pushed the feat/chat-send-attachments branch from ca648b9 to 4c6675e Compare June 4, 2026 20:16
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 4, 2026
@omothm
Copy link
Copy Markdown
Contributor Author

omothm commented Jun 4, 2026

@clawsweeper re-review

The previous automated review failed to complete (execution error, not a finding). Retrying as suggested. Both prior items are already addressed: the CHANGELOG.md edit was dropped from the branch, and the PR body now includes an inspectable redacted server response from the live two-attachment send.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented Jun 4, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant