从看不见的邮件中下载附件

Downloading attachments from unseen messages

我在 java 从事大学项目。我必须使用 GMAIL API.

从新电子邮件下载附件

我使用 OAuth 2.0 授权成功连接到 gmail 帐户。

private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_READONLY);

我尝试使用

获取看不见的邮件
ListMessagesResponse listMessageResponse = service.users().messages().list(user).setQ("is:unseen").execute();

listMessageResponse 不是 null 但是当我调用方法 .getResultSizeEstimate() 它 returns 0 我还尝试使用

listMessageResponse 转换为 List < Message > (我想这更有用)
List<Message> list = listMessageResponse.getMessages();

但是 list 启动 NullPointerException

然后尝试通过

获取每个附件
for(Message m : list) {
            List<MessagePart> part = m.getPayload().getParts();
            for(MessagePart p: part) {
                if(p.getFilename()!=null && p.getFilename().length()>0) {
                    System.out.println(p.getFilename()); // Just to check attachment filename
                }
            }
        }

我的方法是否正确(如果不正确如何修复)以及我应该如何下载这些附件。

编辑 1:

修复了q参数,我错误地写了is:unseen而不是is:unread . 现在应用程序成功到达未读邮件。 (例如有两封未读邮件,都成功到达,我可以轻松获得他们的ID)。

现在这部分抛出了 NullPointerException

List<MessagePart> part = m.getPayload().getParts();

两封邮件都有附件,并且 m 不是 null(我用 .getID())

有什么办法可以解决这个问题并下载附件吗?

编辑 2:

附件下载部分

for(MessagePart p : parts) {

            if ((p.getFilename() != null && p.getFilename().length() > 0)) {
                String filename = p.getFilename();
                String attId = p.getBody().getAttachmentId();
                MessagePartBody attachPart;
                FileOutputStream fileOutFile = null;
                try { 
                   attachPart = service.users().messages().attachments().get("me", p.getPartId(), attId).execute();
                   byte[] fileByteArray = Base64.decodeBase64(attachPart.getData());


                   fileOutFile = new FileOutputStream(filename); // Or any other dir
                   fileOutFile.write(fileByteArray);
                   fileOutFile.close();
                }catch (IOException e) {
                    System.out.println("IO Exception processing attachment: " + filename);
                } finally {
                   if (fileOutFile != null) {
                      try {
                         fileOutFile.close();
                      } catch (IOException e) {
                         // probably doesn't matter
                      }
                   }
                }
            }
        }

下载非常有效,经过测试的应用程序具有不同类型的电子邮件。 唯一剩下的就是将未读消息(应用程序到达)的标签更改为已读。有什么技巧吗?

还有一个小问题: 我希望此应用使用 TimerTask 摘要 class 每 10 分钟获取一次邮件。是否需要手动 "closing" 连接 gmail 或在 运行() 方法迭代结束后自动完成?

 @Override
 public void run(){

 // Some fancy code

 service.close(); // Something like that if even exists
 }

我不认为 ListMessagesResponse 会变成 null。即使没有与您的查询匹配的消息,至少 resultSizeEstimate 将填充到结果响应中:请参阅 Users.messages: list > Response.

我认为您使用的方法是正确的,只是没有与您的查询匹配的邮件。实际上,我以前从未见过is:unseen。您是说 is:unread 吗?

更新:

使用 Users.messages: list 时,仅填充每条消息的 idthreadId,因此您无法访问消息 payload。为了获得完整的消息资源,您必须改用 Users.messages: get,正如您在引用的 link:

中看到的那样

Note that each message resource contains only an id and a threadId. Additional message details can be fetched using the messages.get method.

所以在这种情况下,在获取消息列表后,您必须遍历列表,并对列表中的每条消息执行以下操作:

  • 通过 m.getId() 获取消息 id
  • 检索消息 id 后,使用它调用 Gmail.Users.Messages.Get 并获取完整的消息资源。检索到的邮件应填充所有字段,包括有效负载,并且您应该能够访问相应的附件。

代码示例:

List<Message> list = listMessageResponse.getMessages();
for(Message m : list) {
  Message message = service.users().messages().get(user, m.getId()).execute();
  List<MessagePart> part = message.getPayload().getParts();
  // Rest of code
}

参考: