【问题标题】:GoogleJsonResponseException: Not Found error when using Gmail API sendAs.patch method to change signature for user on domainGoogleJsonResponseException:使用 Gmail API sendAs.patch 方法更改域上用户的签名时未找到错误
【发布时间】:2023-04-05 05:29:01
【问题描述】:

我想以 G Suite 管理员身份通过 Google Apps 脚本更新域用户的签名。

我按照 Mike 的示例 here 使用对 Gmail API 的 HTTP 请求,并且能够正常工作。

这是我所做的总结:

以下代码效果很好(参见原始版本here

function setSignatureWithHTTPRequest(email, signature) {
  var signatureSetSuccessfully = false;
  var authorizationScope = ['https://www.googleapis.com/auth/gmail.settings.sharing'];
  
  var service = getDomainWideDelegationService("Gmail: ", authorizationScope, email);

  if (!service.hasAccess()) {
    Logger.log("failed to authenticate as user " + email);
    Logger.log(service.getLastError());

    signatureSetSuccessfully = service.getLastError();

    return signatureSetSuccessfully;
  } else {
    Logger.log("successfully authenticated as user " + email);
  }
  
  var username = email.split("@")[0];
  var resource = { signature: signature };
  
  var requestBody                = {};
  requestBody.headers            = {"Authorization": "Bearer " + service.getAccessToken()};
  requestBody.contentType        = "application/json";
  requestBody.method             = "PUT";
  requestBody.payload            = JSON.stringify(resource);
  requestBody.muteHttpExceptions = false;

  var emailForUrl = encodeURIComponent(email);

  var url = "https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/" + emailForUrl;

  try {
    var setSignatureResponse = UrlFetchApp.fetch(url, requestBody);
    signatureSetSuccessfully = true;
    Logger.log("setSignatureResponse on successful attempt:" + setSignatureResponse);
  } catch (e) {
    Logger.log("Set signature with HTTP request failed: " + e);
  }
  
  return signatureSetSuccessfully;
}

但是,当我修改代码以使用 Gmail API 中的 patch 方法而不是带有 UrlFetchApp 的 HTTP 请求时,我收到 GoogleJsonResponseException: Not Found 错误。

function setSignatureWithMethod(email, signature) {
  var signatureSetSuccessfully = false;
  var authorizationScope = ['https://www.googleapis.com/auth/gmail.settings.sharing'];
  
  var service = getDomainWideDelegationService("Gmail: ", authorizationScope, email);

  if (!service.hasAccess()) {
    Logger.log("failed to authenticate as user " + email);
    Logger.log(service.getLastError());

    signatureSetSuccessfully = service.getLastError();

    return signatureSetSuccessfully;
  } else {
    Logger.log("successfully authenticated as user " + email);
  }
  
  var resource = { signature: signature };
  
  try {
    var setSignatureResponse = Gmail.Users.Settings.SendAs.patch(resource, "me", email);
    Logger.log("setSignatureResponse on successful attempt:" + setSignatureResponse);
    signatureSetSuccessfully = true;
  } catch (e) {
    Logger.log("Set signature with method failed: " + e);
  }

  return signatureSetSuccessfully;
}

我的问题是双重的。

  • 为什么function setSignatureWithMethod()会产生错误?

  • 另一位发帖者提到 here 说“...您将需要使用使用 UrlFetchApp 服务的 Gmail REST 接口而不是 Gmail 服务来进行调用...因为脚本不能作为服务帐户运行,只有一个用户帐户。”这是准确的吗? Gmail API 提供的方法(列表、补丁、更新等)是否仅用于设置您自己的电子邮件签名(或自己的 Gmail 设置),而不用于域中的其他用户?

【问题讨论】:

    标签: google-apps-script gmail-api google-oauth google-admin-sdk


    【解决方案1】:

    好的,有两件事。

    1 - Gmail.Users.Settings.SendAs.patch() 不起作用。我认为这要么是 Gmail API 如何以任何语言实现的示例,要么是 Google 提供的 Java library 的一部分,不能在 Apps 脚本中使用。

    尝试改变这一行:

    var setSignatureResponse = Gmail.Users.Settings.SendAs.patch(resource, "me", email);
    

    到这个块:

    var requestBody                = {};
    requestBody.headers            = {"Authorization": "Bearer " + service.getAccessToken()};
    requestBody.contentType        = "application/json";
    requestBody.method             = "PATCH";
    requestBody.payload            = JSON.stringify(resource);
    requestBody.muteHttpExceptions = false;
    
    var emailForUrl = encodeURIComponent(email);
    
    var url = "https://www.googleapis.com/gmail/v1/users/me/settings/sendAs/" + emailForUrl;
    
    try {
    
      var setSignatureResponse = UrlFetchApp.fetch(url, requestBody);
    
      signatureSetSuccessfully = true;
    
      Logger.log("setSignatureResponse on successful attempt:" + setSignatureResponse);
    
    } catch (e) {
    
      Logger.log("Set signature with HTTP request failed: " + e.message);
    
    }
    

    2 - 不确定这是否重要,但您发送一个数组作为授权范围,但我的原始示例和我所有的工作代码都使用字符串。

    尝试改变这个:

    var authorizationScope = ['https://www.googleapis.com/auth/gmail.settings.sharing'];
    

    到这个...

    var authorizationScope = 'https://www.googleapis.com/auth/gmail.settings.sharing';
    

    【讨论】:

    • 是的,我认为 Gmail.Users.Settings.SendAs.patch() 是您自己的设置,而不是其他域用户。我在某处读到,指定多个范围的唯一方法是将它们放入一个数组中。此外,正如我所提到的,使用 UrlFetcheApp.fetch() 进行 HTTP 请求是有效的。我只是想知道为什么使用 Gmail API 提供的方法会产生错误。
    • 好的,只是回答您关于为什么该 patch() 方法在理论上不起作用的问题,我会说这是因为您不会发送任何授权标头或访问令牌 -您只是发送resource"me"email,但没有授权。我的回答中的这一行是在 API 调用中包含授权信息的内容:requestBody.headers = {"Authorization": "Bearer " + service.getAccessToken()};
    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 2018-02-12
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    • 2021-09-21
    • 1970-01-01
    相关资源
    最近更新 更多