diff --git a/.changeset/fix-gmail-triage-scope.md b/.changeset/fix-gmail-triage-scope.md new file mode 100644 index 00000000..c14c6287 --- /dev/null +++ b/.changeset/fix-gmail-triage-scope.md @@ -0,0 +1,5 @@ +--- +"@googleworkspace/cli": patch +--- + +Fix gmail +triage 403 error by using gmail.readonly scope instead of gmail.modify to avoid conflict with gmail.metadata scope that does not support the q parameter diff --git a/src/helpers/gmail/mod.rs b/src/helpers/gmail/mod.rs index b7019d53..da82d1e6 100644 --- a/src/helpers/gmail/mod.rs +++ b/src/helpers/gmail/mod.rs @@ -34,6 +34,7 @@ use std::pin::Pin; pub struct GmailHelper; pub(super) const GMAIL_SCOPE: &str = "https://www.googleapis.com/auth/gmail.modify"; +pub(super) const GMAIL_READONLY_SCOPE: &str = "https://www.googleapis.com/auth/gmail.readonly"; pub(super) const PUBSUB_SCOPE: &str = "https://www.googleapis.com/auth/pubsub"; impl Helper for GmailHelper { diff --git a/src/helpers/gmail/triage.rs b/src/helpers/gmail/triage.rs index 6899d4a8..d8adffba 100644 --- a/src/helpers/gmail/triage.rs +++ b/src/helpers/gmail/triage.rs @@ -32,8 +32,12 @@ pub async fn handle_triage(matches: &ArgMatches) -> Result<(), GwsError> { .map(|s| crate::formatter::OutputFormat::from_str(s)) .unwrap_or(crate::formatter::OutputFormat::Table); - // Authenticate - let token = auth::get_token(&[GMAIL_SCOPE]) + // Authenticate — use gmail.readonly instead of gmail.modify because triage + // is read-only and the `q` query parameter is not supported under the + // gmail.metadata scope. When a token carries both metadata and modify + // scopes the API may resolve to the metadata path and reject `q` with 403. + // gmail.readonly always supports `q`. + let token = auth::get_token(&[GMAIL_READONLY_SCOPE]) .await .map_err(|e| GwsError::Auth(format!("Gmail auth failed: {e}")))?;