Skip to content

Fix message deletion and add restore for chats and channel replies - #100

Open
aberoham wants to merge 4 commits into
osodevops:mainfrom
aberoham:fix/message-soft-delete-upstream
Open

aberoham wants to merge 4 commits into
osodevops:mainfrom
aberoham:fix/message-soft-delete-upstream

Conversation

@aberoham

Copy link
Copy Markdown
Contributor

message delete currently sends HTTP DELETE to a message resource, which Graph does not support. Use the softDelete action instead and add message undelete using undoSoftDelete, with chat, channel-root, and channel-reply targets.

  • Require --yes before resolving authentication; missing confirmation returns the JSON invalid-input envelope and exit code 2.
  • Require delegated authentication and explain the additional channel scope on permission errors.
  • Read the message back after mutation, preserving deletedDateTime. If that read fails, retain success and include readBackError; reply targets report the reply ID rather than the parent ID.
  • Update command help, README, man pages, and command documentation.

Recovered from the unpublished local feat/message-soft-delete branch and rebased onto current upstream main. Fork-specific release routing is excluded. The reply-ID regression was reproduced before fixing it.

Validation on macOS: 359 tests passed (cargo test --locked --all-targets), cargo fmt -- --check, cargo check --locked --all-targets, cargo clippy --locked --all-targets -- -D warnings, and git diff --check. Tests disabled keyring access and used local HTTP mocks. No live Graph mutation was performed during this review; historical live observations in source comments were not revalidated. Linux/Windows validation remains for upstream CI.

Microsoft documents softDelete and undoSoftDelete. Chat /me routing and an empty JSON request body preserve the original branch's implementation and recorded live observations; the published examples use /users/{userId} and no request body.

This is a feature/fix PR, not a release: package version remains 0.7.0, with changes recorded under Unreleased.

aberoham and others added 4 commits September 18, 2026 21:10
`teams message delete` sent the DELETE verb to the channel message URL,
which Microsoft Graph rejects for messages ("Requested API is not
supported"), so the command could never delete anything. Deletion is now
the v1.0 `softDelete` action, and a new `message undelete` reverses it
with `undoSoftDelete`.

Both commands take `--chat <chat-id>` or the `--team`/`--channel` pair,
plus `--reply <reply-id>` for channel thread replies, through the
`MessageRef` resolver the attachments commands already use. The chat arm
posts to `/me/chats/{chat}/messages/{id}/<action>`: the plain
`/chats/...` form answers 405, while `/me/chats/...` and the documented
`/users/{oid}/chats/...` answer 204 (verified with a delegated token on
2026-08-20). Graph also answers 204 for a repeat softDelete, so each
command reads the message back and prints it; `deletedDateTime` is added
to the model for that purpose.

`delete` requires `--yes`, enforced at argument parsing so a missing flag
exits with code 2 before any token is resolved or request is sent. It is
the first confirmation flag in the CLI. Channel targets need the
`ChannelMessage.ReadWrite` delegated scope, which the default login does
not request; a 403 on a channel target now names that scope.

The read-back after `update` is consolidated into the same helper, so a
read-back serialization failure after a successful edit is reported as
`readBackError` alongside the success rather than failing the command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SoPJXwA85is7Cq4gGX9Rvr
Address review findings on the soft-delete branch.

The missing-confirmation refusal moved from a clap `required` flag to an
application-level invalid-input error raised before any token is
resolved, so `--output json` callers get the usual `{success: false,
error: {code: "INVALID_INPUT"}}` envelope with exit code 2 instead of a
bare parse error on stderr.

`resolve_message_ref` now lives in `cli/message.rs`, where the message
commands share it, and the attachments module imports it from there
rather than the other way round.

Tests cover what the first round left out: the read-back after a delete
shows `deletedDateTime` and a blanked body, after a restore it is absent
again, a failed read-back still reports the outcome with `readBackError`,
a repeat softDelete is 204 and not an error, the 403/404 mappings carry
exit codes 4 and 5, the channel scope hint applies only to channel
targets, and the `--yes` refusal arrives as the JSON envelope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SoPJXwA85is7Cq4gGX9Rvr

This branch has not been deployed

No deployments
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.

1 participant