Gmail API设置服务账户并代表用户阅读/发送邮件

3

我有一个SSL安全的Jetty Web服务器,任务是代表用户读取/发送电子邮件。为了读取消息,推荐使用发布/订阅模式而不是轮询。按照developers.google.com上的以下步骤执行:

  1. 在控制台中创建项目,启用Gmail API,创建具有Google应用程序域委派的服务帐户,并下载json和p12私钥
  2. 通过选择Web应用程序创建OAuth cliend-id,给其命名并将授权重定向URI添加到其中一个Web服务器API端点
  3. 使用控制台API授予主题发布权限
  4. 在pub-sub中创建主题并订阅HTTPs端点。使用控制台API手动检查以发布消息并成功接收

现在所剩的就是使用Java客户端库利用服务帐户凭据并代表用户与Gmail API进行通信(已从用户那里收集了主题的认证和刷新标记)

尝试的步骤:

  1. Using the private key downloaded (p12) tried creating credential and for sample retrieving labels of the mail

    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所需的所有必要密钥文件。
请告诉我是否有遗漏的内容。

你有记录最终请求的方式吗? :) 这将非常有用。例如,方法、URL 和标头。 - Tholle
你解决了吗?如何代表用户发送? - Mild Fuzz
是的,使用GoogleCredential.getApplicationDefault()。 - Itachi
1个回答

1
起初,我使用OAuth 2.0客户端ID来获取特定Gmail帐户的邮件。后来,我意识到我的应用程序根本不需要询问同意,并因此偶然发现了谷歌服务帐户,消除了同意提示和授权令牌存储。我尝试了以上发布的相同代码,但遇到了完全相同的响应 "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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接