Skip to content

feat(mail): add --attachment to send, drafts create and replies#13

Open
okuegow wants to merge 1 commit into
visionik:mainfrom
okuegow:feat/mail-attachments
Open

feat(mail): add --attachment to send, drafts create and replies#13
okuegow wants to merge 1 commit into
visionik:mainfrom
okuegow:feat/mail-attachments

Conversation

@okuegow

@okuegow okuegow commented Jun 18, 2026

Copy link
Copy Markdown

Problem

mog couldn't attach files to outgoing mail — mail send and mail drafts create only supported recipients, subject and body.

Changes

  • New repeatable --attachment <path> flag for mail send and mail drafts create. Each file becomes an inline base64 microsoft.graph.fileAttachment (typed payload struct); content type is inferred from the extension (fallback application/octet-stream).
  • Up-front validation with clear errors: empty path, missing file, directory, and files at/over Graph's 3 MB inline limit (larger files would need an upload session).
  • Replies (--reply-to-message-id) support attachments too. The single-step /reply action can't carry inline attachments, so the reply is built via createReply (keeping the quoted original), then PATCH (recipients; for HTML also the body), one POST .../attachments per file, and POST .../send. Text replies pass the user's text as the createReply comment; HTML replies prepend the user's HTML before the quoted draft body. On a pre-send failure the orphaned draft is deleted (best effort); if sending fails the draft is kept and named in the error.
  • Also fixes the pre-existing non-attachment reply path, which set both comment and message.body (Graph wants one or the other and can return 400): now comment for text, message.body for HTML.

Tests

  • buildAttachments: content-type inference, and empty/missing/directory/oversize rejection.
  • mail send and mail drafts create POST payloads include the attachment (asserted via the mock client).
  • Reply flow end-to-end via the mock client: exact call order createReply → patch → attach → send, attachment/recipient payloads, HTML quote prepending, and the createReply/attach/send error paths incl. orphan-draft cleanup.
  • Verified live against a real Microsoft 365 account: attachments on a new mail and a draft, and a reply-with-attachment that arrived with the correct file.
  • go build / go vet / go test ./... pass. README and --ai-help updated.

Closes #10

mog could not attach files. Add a repeatable `--attachment <path>` flag
to `mail send` and `mail drafts create`: each file becomes an inline
base64 microsoft.graph.fileAttachment (typed payload struct), content
type inferred from the extension (fallback application/octet-stream).
Paths are validated up front with clear errors: empty path, missing
file, directory, and files at/over Graph's 3 MB inline limit.

Replies (`--reply-to-message-id`) also support attachments. The
single-step /reply action cannot carry inline attachments, so the reply
is built via createReply, then PATCH/attach/send. The quoted original is
preserved: text replies pass the user's text as the createReply comment;
HTML replies prepend the user's HTML before the quoted draft body. On a
pre-send failure the orphaned draft is deleted (best effort); if sending
fails the draft is kept and named in the error.

Also fixes the existing non-attachment reply path, which set both
`comment` and `message.body` (Graph wants one or the other, can 400):
now comment for text, message.body for HTML.

Tests cover buildAttachments (content-type, empty/missing/dir/oversize),
the send + drafts-create payloads, and the reply flow end to end:
call order createReply->patch->attach->send, the attachment/recipient
payloads, HTML quote prepending, and the createReply/attach/send error
paths incl. orphan-draft cleanup. README and --ai-help updated.

Closes visionik#10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add --attachment flag to mail drafts create and mail send

1 participant