我正在尝试使用 google java api 服务发送基于 Gmail REST API 的邮件。我已经通过 Google Develover Console 配置了一个应用程序客户端并下载了 p12 和 json 文件。
我用过这个示例程序,https://developers.google.com/gmail/api/guides/sending#sending_messages ...
此示例有效,但它基于 GoogleAuthorizationCodeFlow。我只想从服务器到服务器工作,直接调用,而不是打开浏览器来获取访问 token ......我得到了它(访问 token )但最后我收到了一个错误的请求......为什么? ?除了“Bad Request”和“Precondition Failed”
,我没有收到更多信息基于此,我遵循以下步骤:
第一步:根据我的客户帐户邮件和 p12 生成的文件创建一个 GoogleCredential 对象:
GoogleCredential credential = new GoogleCredential.Builder().setTransport(new NetHttpTransport()) .setJsonFactory(new JacksonFactory()) .setServiceAccountId(serviceAccountUserEmail) .setServiceAccountScopes(scopes) .setServiceAccountPrivateKeyFromP12File( new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH)) .build();
在这里我必须指出,我在使用 ClientID 而不是 ClientMail 时遇到了很多问题。它必须使用 @developer.gserviceaccount.com 帐户而不是 .apps.googleusercontent.com 。如果您不发送此参数 ok ,您将收到“无效授权”错误。这在这里解释:https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization
第二步:根据凭据创建 Gmail 服务:
Gmail gmailService = new Gmail.Builder(httpTransport, jsonFactory, credential) .setApplicationName(APP_NAME) .build();
第三步从 MimmeMessage 创建 Google 原始消息:
private static Message _createMessageWithEmail(final MimeMessage email) throws MessagingException, IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); email.writeTo(bytes); String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray()); Message message = new Message(); message.setRaw(encodedEmail); return message;
第四步调用服务:
Message message = _createMessageWithEmail(email); message = service.users() .messages() .send(userId,message) .execute();
- 第五步:执行后获取结果...这里我收到异常:
线程“主”中的异常
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "failedPrecondition"
} ],
"message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
知道哪里出了问题或前提条件失败了吗?
最佳答案
这就是我设法让它与 Google Apps 域一起工作的方式:
1.- 使用谷歌应用程序用户打开 developer console
2.- 创建一个新的项目(即MyProject)
3.- 转到 [Apis & auth] > [Credentials] 并创建一个新的 [Service Account] 客户端 ID
4.- 复制 [service account] 的 [Client ID](比如 xxx.apps.googleusercontent.com)以备后用
5.- 现在你必须 Delegate domain-wide authority to the service account 为了授权您的应用代表 Google Apps 域中的用户访问用户数据 ... 所以去你的 google apps domain admin console
6.- 转到 [安全] 部分并找到 [高级设置] (它可能是隐藏的,因此您必须单击 [显示更多..])
7.- 单击 [管理 API 客户端访问]
8.- 将您之前在 [4] 处复制的 [Client ID] 粘贴到 [Client Name] 文本框中。
9.- 要授予您的应用对 gmail 的完全访问权限,请在 [API 范围] 文本框中输入:https://mail.google.com , https://www.googleapis.com/auth/gmail.compose , https://www.googleapis.com/auth/gmail.modify , https://www.googleapis.com/auth/gmail.readonly (输入所有范围非常重要)
现在您已经完成了所有设置...现在是代码:
1.- 创建一个 HttpTransport
private static HttpTransport _createHttpTransport() throws GeneralSecurityException,
IOException {
HttpTransport httpTransport = new NetHttpTransport.Builder()
.trustCertificates(GoogleUtils.getCertificateTrustStore())
.build();
return httpTransport;
}
2.- 创建一个 JSonFactory
private static JsonFactory _createJsonFactory() {
JsonFactory jsonFactory = new JacksonFactory();
return jsonFactory;
}
3.- 创建谷歌凭证
private static GoogleCredential _createCredentialUsingServerToken(final HttpTransport httpTransport,
final JsonFactory jsonFactory) throws IOException,
GeneralSecurityException {
// Use the client ID when making the OAuth 2.0 access token request (see Google's OAuth 2.0 Service Account documentation).
String serviceAccountClientID = "327116756300-thcjqf1mvrn0geefnu6ef3pe2sm61i2q.apps.googleusercontent.com";
// Use the email address when granting the service account access to supported Google APIs
String serviceAccountUserEmail = "xxxx@developer.gserviceaccount.com";
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountUserEmail) // requesting the token
.setServiceAccountPrivateKeyFromP12File(new File(SERVER_P12_SECRET_PATH))
.setServiceAccountScopes(SCOPES) // see https://developers.google.com/gmail/api/auth/scopes
.setServiceAccountUser("user@example.com")
.build();
credential.refreshToken();
return credential;
}
注意:在 setServiceAccountUser() 方法中使用来自您的 google apps 域的任何用户
4.- 创建 Gmail 服务
private static Gmail _createGmailService(final HttpTransport httpTransport,
final JsonFactory jsonFactory,
final GoogleCredential credential) {
Gmail gmailService = new Gmail.Builder(httpTransport,
jsonFactory,
credential)
.setApplicationName(APP_NAME)
.build();
return gmailService;
}
现在您可以使用 GmailService 做任何您想做的事,比如发送电子邮件 ;-) 如 https://developers.google.com/gmail/api/guides/sending 所述
关于java - Gmail REST API : 400 Bad Request + Failed Precondition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29327846/