Gmail REST API:400错误请求+失败的前提条件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gmail REST API:400错误请求+失败的前提条件相关的知识,希望对你有一定的参考价值。
我正在尝试使用google java api服务发送基于Gmail REST API的邮件。我已通过Google Develover Console配置了应用程序客户端并下载了p12和json文件。
我用过这个示例程序,https://developers.google.com/gmail/api/guides/sending#sending_messages ......
此示例有效,但这是基于GoogleAuthorizationCodeFlow。我只想从服务器到服务器工作,直接调用,而不是打开浏览器来获取访问令牌......我得到了它(访问令牌)但最后我收到了错误请求....为什么? ?我收到的信息不仅仅是“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。如果你不发送这个参数确定,你得到一个“无效授予”错误。这在这里解释: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();
- 第五步:执行后获得结果......这里我收到例外:
线程“main”中的异常
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]> [凭据]并创建新的[服务帐户]客户端ID
4.-复制[服务帐户]的[客户端ID](类似xxx.apps.googleusercontent.com)以供日后使用
5.-现在你需要Delegate domain-wide authority to the service account才能授权你的appl代表Google Apps域中的用户访问用户数据...所以转到你的google apps domain admin console
6.-转到[安全]部分找到[高级设置](可能会隐藏,因此您必须单击[显示更多..])
7.-单击[管理API客户端访问]
8.-将先前在[4]中复制的[客户端ID]粘贴到[客户端名称]文本框中。
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()方法中,使用谷歌应用程序域中的任何用户
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所述
非常感谢您的详细解答。我试图让这个工作为asp.net MVC。但是在遵循给定步骤的所有内容之后,我的代码给出了同样的错误。
花了两天时间来解决这个错误,我可以通过以下方式解决这个问题。在ServiceAccountCredential.Initializer构造函数中,您需要指定您尝试使用此服务帐户模拟的用户ID。
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = "<USER@YOUR_GSUIT_DOMAIN.COM>",
Scopes = new[] { GmailService.Scope.MailGoogleCom }
}.FromPrivateKey(<YOUR_PRIVATE_KEY>);
if (credential != null)
{
var service = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result,
ApplicationName = "Enquiry Email Sender"
});
var list = service.Users.Messages.List("me").Execute();
var count = "Message Count is: " + list.Messages.Count();
return count;
}
我在现有线程上进行标记,因为我正面临同样的问题,并且在执行上述操作后仍然遇到同样的错误:
screenshot of node console error
就我而言,我正在整理一个将发送电子邮件的nodeJS服务。我正在使用googleapis npm模块。代码块的一个例子是这样的:
const { google } = require("googleapis");
const gmailCredentials = require("./credentials.json");
const SCOPES = [
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/gmail.compose",
"https://www.googleapis.com/auth/gmail.readonly",
];
const jwtClient = new google.auth.JWT(
gmailCredentials.client_email,
null,
gmailCredentials.private_key,
SCOPES
);
//authenticate
jwtClient.authorize((err, tokens) => {
if (err) {
console.log(err);
return;
} else {
console.log("Successfully connected!");
const gmail = google.gmail("v1");
gmail.users.messages.list({
auth: jwtClient,
userId: "me",
});
}
});
gmailCredentials
是我在创建服务帐户时下载的。我还经历了以下步骤:
- 给定开发人员控制台中的服务帐户域级访问权限
- 在admin.google.com的安全性(高级配置)中为我的GSuite域授予了具有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)
还是没有解决。我能错过什么?
以上是关于Gmail REST API:400错误请求+失败的前提条件的主要内容,如果未能解决你的问题,请参考以下文章
Gmail REST API:400 Bad Request + Failed Precondition
Firebase 动态链接 REST API 返回 400 错误请求
Google API (Gmail) 因失败的前提条件 400 而失败