GmailApi 快速入门 -

Posted

技术标签:

【中文标题】GmailApi 快速入门 -【英文标题】:GmailApiQuickstart - 【发布时间】:2014-11-12 02:23:48 【问题描述】:

我很尴尬,我只是在一段示例代码上失败了,但我会把它归咎于它迟到的事实......

我已经复制并粘贴了:https://developers.google.com/gmail/api/quickstart/quickstart-java 并下载了客户端库:https://code.google.com/p/google-api-java-client/ 和https://developers.google.com/api-client-library/java/apis/gmail/v1

当我运行示例时,出现以下异常:

Exception in thread "main" java.lang.IllegalArgumentException
    at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
    at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
    at com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.getDetails(GoogleClientSecrets.java:82)
    at com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder.<init>(GoogleAuthorizationCodeFlow.java:195)
    at com.emailreply.musterion.GmailApiQuickstart.main(GmailApiQuickstart.java:40)

谷歌搜索,我找不到简单的答案,所以我假设是愚蠢的或图书馆丢失/不正确。

我拥有的库是:

/libs/commons-logging-1.1.1.jar
/libs/google-api-client-1.19.0.jar
/libs/google-api-client-android-1.19.0.jar
/libs/google-api-client-appengine-1.19.0.jar
/libs/google-api-client-gson-1.19.0.jar
/libs/google-api-client-jackson2-1.19.0.jar
/libs/google-api-client-java6-1.19.0.jar
/libs/google-api-client-servlet-1.19.0.jar
/libs/google-http-client-1.19.0.jar
/libs/google-http-client-android-1.19.0.jar
/libs/google-http-client-appengine-1.19.0.jar
/libs/google-http-client-gson-1.19.0.jar
/libs/google-http-client-jackson2-1.19.0.jar
/libs/google-http-client-jdo-1.19.0.jar
/libs/google-oauth-client-1.19.0.jar
/libs/google-oauth-client-appengine-1.19.0.jar
/libs/google-oauth-client-java6-1.19.0.jar
/libs/google-oauth-client-jetty-1.19.0.jar
/libs/google-oauth-client-servlet-1.19.0.jar
/libs/gson-2.1.jar
/libs/httpclient-4.0.1.jar
/libs/httpcore-4.0.1.jar
/libs/jackson-core-2.1.3.jar
/libs/jdo2-api-2.3-eb.jar
/libs/jetty-6.1.26.jar
/libs/jetty-util-6.1.26.jar
/libs/jsr305-1.3.9.jar
/libs/transaction-api-1.1.jar
google-api-services-gmail-v1-rev10-1.19.0.jar

上面提到的例子:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleOAuthConstants;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.ListThreadsResponse;
import com.google.api.services.gmail.model.Thread;


public class GmailApiQuickstart 

  // Check https://developers.google.ciom/gmail/api/auth/scopes for all available scopes
  private static final String SCOPE = "https://www.googleapis.com/auth/gmail.readonly";
  private static final String APP_NAME = "Gmail API Quickstart";
  // Email address of the user, or "me" can be used to represent the currently authorized user.
  private static final String USER = "me";
  // Path to the client_secret.json file downloaded from the Developer Console
  private static final String CLIENT_SECRET_PATH = "./client_secret.json";


  public static void main (String [] args) throws IOException 
    HttpTransport httpTransport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory,  new BufferedReader(new InputStreamReader(GmailApiQuickstart.class.getResourceAsStream(CLIENT_SECRET_PATH))));

    // Allow user to authorize via url.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, jsonFactory, clientSecrets, Arrays.asList(SCOPE))
        .setAccessType("online")
        .setApprovalPrompt("auto").build();

    String url = flow.newAuthorizationUrl().setRedirectUri(GoogleOAuthConstants.OOB_REDIRECT_URI).build();


    System.out.println("Please open the following URL in your browser then type the authorization code:\n" + url);

    // Read code entered by user.
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String code = br.readLine();

    // Generate Credential using retrieved code.
    GoogleTokenResponse response = flow.newTokenRequest(code)
        .setRedirectUri(GoogleOAuthConstants.OOB_REDIRECT_URI).execute();
    GoogleCredential credential = new GoogleCredential()
        .setFromTokenResponse(response);

    // Create a new authorized Gmail API client
    Gmail service = new Gmail.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName(APP_NAME).build();

    // Retrieve a page of Threads; max of 100 by default.
    ListThreadsResponse threadsResponse = service.users().threads().list(USER).execute();
    List<Thread> threads = threadsResponse.getThreads();

    // Print ID of each Thread.
    for (Thread thread : threads) 
        System.out.println("Thread ID: " + thread.getId());
    
  


我将CLIENT_SECRET_PATH 的引用替换为:

new BufferedReader(new InputStreamReader(GmailApiQuickstart.class.getResourceAsStream(CLIENT_SECRET_PATH)))

只是为了尝试不同的东西。它确实可以正常工作并正确读取文件。

有什么想法吗?

【问题讨论】:

【参考方案1】:

好吧,经过更多研究(请教同事/天才),我发现了问题所在。基本上GoogleClientSecrets 对象没有与我的client_secrets.json 文件中的信息正确绑定。这意味着在身份验证期间,对象为null,从而导致IllegalArgumentException

原来的文件是这样的:


      "private_key_id": "zzz",
      "private_key": "-----BEGIN PRIVATE KEY-----\nxyz\n-----END PRIVATE KEY-----\n",
      "client_email": "1234@developer.gserviceaccount.com",
      "client_id": "1wdfghyjmp.apps.googleusercontent.com",
      "type": "service_account"

被编辑成这样:


    "web" : 
      "private_key_id": "zzz",
      "private_key": "-----BEGIN PRIVATE KEY-----\nxyz\n-----END PRIVATE KEY-----\n",
      "client_email": "1234@developer.gserviceaccount.com",
      "client_id": "1wdfghyjmp.apps.googleusercontent.com",
      "type": "service_account"
    

这让我可以通过身份验证来完成代码。

希望这会有所帮助。

【讨论】:

是的,非常有帮助。谢谢! Exxxxtremelyyy 帮助...谢谢!你是怎么发现的?我的意思是,为什么把这个“网络”解决了。 类似问题。原始文件是在 Google 控制台上使用“服务帐户”生成的。 json 文件没有“web”元素并且构建流程障碍。使用“web”而不是“service account”重新生成凭据提供了一个包含“web”和构建的“流”的结构。 Google 的例子很糟糕 我的天啊,这东西的谷歌文档已经够糟糕了,不需要重新构建凭据文件!【参考方案2】:

这是 Google Non-interactive authorization with Google OAuth2 的非交互式身份验证的工作示例 问题不在于客户端 json 中的“web”标签,而在于他们的示例用于 Web 身份验证,而他们建议的生成凭据的方式是用于非交互式“服务帐户”。他们的文档存在多个问题。

【讨论】:

这对我有帮助!完美,因为我想要非交互式身份验证,所选答案提示我浏览器身份验证..

以上是关于GmailApi 快速入门 -的主要内容,如果未能解决你的问题,请参考以下文章

Gmail API 推送通知速率限制究竟是啥意思?

Gmail API 是不是支持没有 SMTP 的 Codeigniter?

Gmail API - Oauth2/google:找不到凭据(Golang)

Gmail API - ListUsersLabels - 没有邮件总数

使用 Gmail API 从 Gmail 下载附件

使用 gmail API 阅读独特的邮件