我有一个 SSL 安全 jetty 网络服务器,其任务是代表用户阅读/发送电子邮件。阅读 pub/sub 是首选,而不是 pull。已按照 developers.google.com 中的这些步骤操作
- 在控制台中创建了一个项目,启用了 Gmail API,使用 google apps domain-wide delegation 创建了服务帐户,下载了 json 和 p12 私钥
- 通过选择 Web 应用程序创建 OAuth 客户端 ID,为其命名并将授权重定向 URI 添加到 Web 服务器 API 端点之一
- 使用控制台 api 授予主题的发布权
- 在 pub-sub 中创建主题并使用 HTTPs 端点订阅。使用控制台 API 手动检查发布消息并成功接收
现在剩下要做的就是使用 java 客户端库来利用服务帐户凭据并代表用户与 gmail api 对话(已为该主题从用户那里收集了身份验证和刷新 token )
尝试过的步骤。
使用下载的私钥 (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/