java - Gmail API 代表用户设置服务帐户和阅读/发送邮件

标签 java webserver gmail-api google-api-java-client

我有一个 SSL 安全 jetty 网络服务器,其任务是代表用户阅读/发送电子邮件。阅读 pub/sub 是首选,而不是 pull。已按照 developers.google.com 中的这些步骤操作

  1. 在控制台中创建了一个项目,启用了 Gmail API,使用 google apps domain-wide delegation 创建了服务帐户,下载了 json 和 p12 私钥
  2. 通过选择 Web 应用程序创建 OAuth 客户端 ID,为其命名并将授权重定向 URI 添加到 Web 服务器 API 端点之一
  3. 使用控制台 api 授予主题的发布权
  4. 在 pub-sub 中创建主题并使用 HTTPs 端点订阅。使用控制台 API 手动检查发布消息并成功接收

现在剩下要做的就是使用 java 客户端库来利用服务帐户凭据并代表用户与 gmail api 对话(已为该主题从用户那里收集了身份验证和刷新 token )

尝试过的步骤。

  1. 使用下载的私钥 (p12) 尝试创建凭据和样本检索邮件标签

    HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();    
    String serviceAccount = "service-account@myproject.iam.gserviceaccount.com";
    Credential credential = GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)    
    .setJsonFactory(JSON_FACTORY)
    .setServiceAccountId(serviceAccount)
    .setServiceAccountPrivateKeyFromP12File(new File("/path-to-key-file.p12"))
    .setServiceAccountScopes(Collections.singleton(GmailScopes.GMAIL_LABELS))
    .build();
    Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, cred).setApplicationName("web-application-name-created-via-console").build();
    String user = "me"; //Tried direct email id also  
    service.users().labels().list(user).execute();
    

响应,

{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Bad Request",
    "reason" : "failedPrecondition"
  } ],
  "message" : "Bad Request"
}

注意:编码部分是在本地服务器上尝试的,而不是在有 SSL 的服务器上。我想这应该不是问题,因为我拥有访问 api 所需的所有 key 文件。

如果我遗漏了什么,请告诉我。

最佳答案

最初,我使用 OAuth 2.0 客户端 ID 为我的 Web 应用程序从特定的 Gmail 帐户获取邮件。然后我意识到我的应用程序根本不需要同意提示,那时我偶然发现了消除授权 token 的同意提示和存储的谷歌服务帐户。我确实尝试了上面发布的完全相同的代码,并遇到了发布的完全相同的响应 "message": "Bad Request", "reason": "failedPrecondition"

要解决此问题,请添加 .setServiceAccountUser(googleServiceAccountUser),其中 googleServiceAccountUser 设置为我的应用程序试图从中读取消息的我的 google 电子邮件 ID (xxx@gmail.com)。在您的代码片段中,如果缺少调用“.setServiceAccountUser()”,添加它可能会帮助您解决问题。

private static Credential authorize() throws Exception {

  GoogleCredential credential = new GoogleCredential.Builder()
  .setTransport(httpTransport)
  .setJsonFactory(JSON_FACTORY)
  .setServiceAccountId(googleServiceAccountId)
  .setServiceAccountPrivateKeyFromP12File(new File(privatekeyFile))
  .setServiceAccountScopes(Collections.singleton(GmailScopes.MAIL_GOOGLE_COM))
  .setServiceAccountUser(googleServiceAccountUser)
  .build();

  return credential;
}

关于java - Gmail API 代表用户设置服务帐户和阅读/发送邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35207042/

相关文章:

android - MesageID Android Gmail API

java - Paypal PDT 返回 HTTP 状态 307

java - 如何在我的游戏中添加声音字节?

sql - 将 Web 服务器日志(apache、iis 等)转换为关系数据库

nginx - nginx web服务器支持哪种服务器端语言

javascript - xpage csjs 代码未通过 gmail api 以正确格式发送内联图像和附件电子邮件

java - 如何使用 Gmail API 获取电子邮件正文内容

java - Firebase Android getValue(class) 不起作用

java - 为什么我的 DelayQueue 没有延迟并以错误的顺序打印?

java - 如何停止 Web 服务器中的线程