Gmail REST API:400错误的请求+失败的前提条件

我正尝试使用Google Java API服务基于Gmail REST API发送邮件。 我通过Google Develover Consoleconfiguration了一个应用程序客户端,并下载了p12和json文件。

我已经使用这个示例程序, https://developers.google.com/gmail/api/guides/sending#sending_messages …

此示例工作,但这是基于GoogleAuthorizationCodeFlow。 我只想从服务器到服务器,直接调用,而不是打开浏览器来获取访问令牌…我得到它(访问令牌),但最后我收到一个错误的请求….为什么? ? 我没有收到更多的信息比“坏请求”和“先决条件失败”

基于这个我遵循下面的步骤:

  1. 第一步 :根据我的客户帐户邮件和p12生成的文件创build一个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(); 

在这里,我必须指出,我有很多问题,而不是ClientMail ClientID。 它必须使用@ developer.gserviceaccount.com帐户而不是.apps.googleusercontent.com。 如果你不发送这个参数确定,你会得到一个“无效授予”的错误。 这在这里解释: https : //developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization

  1. 第二步 :根据凭据创buildGmail服务:

     Gmail gmailService = new Gmail.Builder(httpTransport, jsonFactory, credential) .setApplicationName(APP_NAME) .build(); 
  2. 第三步从MimmeMessage创buildGoogle原始消息:

     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; 

    }

  3. 第四步调用服务:

      Message message = _createMessageWithEmail(email); message = service.users() .messages() .send(userId,message) .execute(); 
  4. 第五步 :执行后得到结果…在这里我收到exception:

线程“主”中的exception

 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.-使用谷歌应用程序用户打开开发者控制台

2.-创build一个新的项目 (即MyProject

3.-转到[Apis&auth]> [Credentials]并创build一个新的[Service Account]客户端ID

4.-复制[服务帐户]的[客户端ID](如xxx.apps.googleusercontent.com之一)供以后使用

5.-现在,您必须将域范围的权限授权给服务帐户 ,以便授权您的应用程序代表Google Apps域中的用户访问用户数据…所以请转到您的Google应用程序域pipe理员控制台

6.-进入[安全]部分,find[高级设置] (它可能被隐藏,所以你必须点击[显示更多..])

7.-点击[pipe理API客户端访问]

8.-将先前在[4]处复制的[客户端ID]粘贴到[客户端名称]文本框中。

9.-要授予您的应用程序完全访问 gmail的权限 ,请在[API范围]文本框中input: 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 (input所有范围非常重要)


现在你已经完成了所有的设置…现在的代码:

1.-创build一个HttpTransport

 private static HttpTransport _createHttpTransport() throws GeneralSecurityException, IOException { HttpTransport httpTransport = new NetHttpTransport.Builder() .trustCertificates(GoogleUtils.getCertificateTrustStore()) .build(); return httpTransport; } 

2.-创build一个JSonFactory

 private static JsonFactory _createJsonFactory() { JsonFactory jsonFactory = new JacksonFactory(); return jsonFactory; } 

3.-创build一个谷歌凭据

 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.-创build一个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; } 

现在,您可以按照https://developers.google.com/gmail/api/guides/sending中所述,使用GmailService执行任何操作,例如发送电子邮件;;-)