Скачивание вложений из невидимых сообщений - PullRequest
2 голосов
/ 25 мая 2020

Работаю над университетским проектом в java. Мне нужно загрузить вложения из новых писем, используя GMAIL API .

Я успешно подключился к учетной записи Gmail, используя OAuth 2.0 авторизацию.

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

Я пытался получать невидимые письма, используя

ListMessagesResponse listMessageResponse = service.users().messages().list(user).setQ("is:unseen").execute();

listMessageResponse is not null , но когда я вызываю метод .getResultSizeEstimate () , он возвращает 0 также я пытался преобразовать listMessageResponse в List (я думаю, это более удобно), используя

List<Message> list = listMessageResponse.getMessages();

Но список запускает 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 вместо - это: непрочитанные . Теперь приложение успешно достигает непрочитанных писем. (Например, было два непрочитанных письма, и оба были успешно достигнуты, я могу легко получить их идентификаторы).

Теперь эта часть вызывает 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
                      }
                   }
                }
            }
        }

Загрузка работает как шарм, приложение протестировано с разными типами писем. Осталось только изменить ярлык непрочитанного сообщения (до которого дошло приложение) на чтение. Есть какие-нибудь советы, как это сделать?

И один крошечный вопрос: я хочу, чтобы это приложение получало почту каждые 10 минут с использованием абстрактного класса TimerTask. Есть ли необходимость в ручном "закрытии" соединения с gmail или это делается автоматически после завершения итерации метода run ()?

 @Override
 public void run(){

 // Some fancy code

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

1 Ответ

1 голос
/ 25 мая 2020

Я не думаю, что ListMessagesResponse когда-либо станет нулевым. Даже если нет сообщений, соответствующих вашему запросу, по крайней мере resultSizeEstimate будет заполнено в результирующем ответе: см. Users.messages: list> Response .

Я думаю, вы используете правильный подход, просто нет сообщения, соответствующего вашему запросу. На самом деле, я никогда раньше не видел is:unseen. Вы имели в виду is:unread вместо этого?

Обновление:

При использовании Users.messages: list заполняются только id и threadId каждого сообщения , поэтому вы не можете получить доступ к сообщению payload. Чтобы получить полный ресурс сообщения, вы должны вместо этого использовать Users.messages: get, как вы можете видеть в указанной ссылке:

Обратите внимание, что каждый ресурс сообщения содержит только id и threadId. Дополнительные сведения о сообщении можно получить с помощью метода messages.get .

Итак, в этом случае, после получения списка сообщений, вы должны пройти по списку и сделать следующее для каждого сообщения в списке:

  • Получить сообщение id через m.getId () .
  • После получения сообщения 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
}

Ссылка:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...