首页 > 解决方案 > 如何使用服务帐户在 Spring Boot 2.x 中调用 gmail api?

问题描述

我有一个配置为访问企业用户 gmail 帐户的 GSuite 服务帐户,我已为其提供了 G Suite 管理控制台中的所有权限,包括域范围访问权限。我创建了一个服务帐户,现在想使用凭据代表他们发送电子邮件。

到目前为止,这是我的代码:

  public void gmailTest(){
  log.info("Gmail test");

  List<String> SCOPES = new ArrayList<String>(GmailScopes.all());
  // List<String> SCOPES = GmailScopes.all();
  InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Program Name-12345678.json");

  try {
  if(resourceAsStream != null) {
    NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

    log.info("Reading credential file");
    GoogleCredential credential = GoogleCredential.fromStream(resourceAsStream);
    log.info("Creating scopes");
    credential = credential.createScoped(SCOPES);

    log.info("building gmail api service");
    Gmail gmailService = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName("ept-mailer").build();
    String user = "deusrex@mygenericdomain.com";

    log.info("calling gmail api");
    ListLabelsResponse listResponse = gmailService.users().labels().list(user).execute();
    log.info("call did not error");
    List<Label> labels = listResponse.getLabels();
    if (labels.isEmpty()) {
      System.out.println("No labels found.");
    } else {
      System.out.println("Labels:");
      for (Label label : labels) {
        System.out.printf("- %s\n", label.getName());
      }
    }
  }
  }
  catch (IOException | GeneralSecurityException ex) {
  log.error(ex.getMessage());
  }

以下是我的特权:

 Email (Manage labels)  https://www.googleapis.com/auth/gmail.labels 
 https://www.googleapis.com/auth/gmail.metadata 
 Email (Read/Write)  https://www.googleapis.com/auth/gmail.modify 

这是我得到的错误:

 400 Bad Request
 {
   "code" : 400,
   "errors" : [ {
     "domain" : "global",
     "message" : "Bad Request",
     "reason" : "failedPrecondition"
   } ],
   "message" : "Bad Request"
 }

标签: spring-bootgmail-apiservice-accounts

解决方案


好的,答案是您必须在创建凭据时指定用户。在较新版本的 API 中,此调用已更改为:.createDelegated()。只需将您希望模拟的用户电子邮件放在那里。

 GoogleCredential credential = GoogleCredential.fromStream(resourceAsStream).createDelegated("deusrex@mygenericdomain.com");

推荐阅读