Gmail API - невозможно перечислить все письма по ярлыкам - PullRequest
0 голосов
/ 19 марта 2020

Привет и большое спасибо за ваши ответы

Я начал свое программистское путешествие пару дней go просто для удовольствия, и потому что мне какое-то время нравился Python, но на самом деле никогда Я попытался разобраться в этом или попытаться поэкспериментировать с ним.

Однажды go мне пришло в голову, что если бы я мог загружать вложения из определенного набора c электронных писем с помощью пользовательских меток , ie "MyEmail" или "EmailCool" и сохраняйте все вложения, которые были под этими метками.

Я немного поэкспериментировал с API Gmail и провел некоторые начальные испытания самостоятельно: https://developers.google.com/gmail/api/v1/reference/users/messages/list но проблема в том, что я могу захватывать и хранить вложения только в том случае, если в качестве параметра я указал только одну из пользовательских меток, которые я создал ie "MyEmail".

Если я ввожу обе эти метки в качестве параметров, API выдаст ответ resultSizeEstimate = 0, что означает, что сообщений не было.

Есть ли что-то неправильное, что я применяю под сервом Метод ice.users (). messages.list ()? И снова мой код работает, если я даю одну метку в качестве параметра, но не две пользовательских метки одновременно.

Вот мой код для справки:

import base64
import email
import os
import requests
import google.oauth2.credentials
import pickle
import sys

from google_auth_oauthlib.flow import InstalledAppFlow
from apiclient.discovery import build
from httplib2 import Http
from apiclient import errors
from apiclient import discovery
from google.auth.transport.requests import Request


def ListMessagesWithLabels(service, user_id, label_ids):
  """List all Messages of the user's mailbox with label_ids applied.

  Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    label_ids: Only return Messages with these labelIds applied.

  Returns:
    List of Messages that have all required Labels applied. Note that the
    returned list contains Message IDs, you must use get with the
    appropriate id to get the details of a Message.
  """
  try:
    response = service.users().messages().list(userId=user_id,
                                               labelIds=label_ids,
                                               maxResults=500).execute()
    print(response)
    messages = []

    if 'messages' in response:
      messages.extend(response['messages'])

    while 'nextPageToken' in response:
      page_token = response['nextPageToken']

      response = service.users().messages().list(userId=user_id,
                                                 labelIds=label_ids,
                                                 pageToken=page_token,
                                                 maxResults=500).execute()

      messages.extend(response['messages'])

      print('... total %d emails on next page [page token: %s], %d listed so far' % (len(response['messages']), page_token, len(messages)))
      sys.stdout.flush()

    return messages

  except errors.HttpError as error:
      print('An error occurred: %s' % error)

def GetAttachments(service, user_id, store_dir, label_ids):

    """Get and store attachment from Message with given id.

    Args:
    service: Authorized Gmail API service instance.
    user_id: User's email address. The special value "me"
    can be used to indicate the authenticated user.
    msg_id: ID of Message containing attachment.
    prefix: prefix which is added to the attachment filename on saving
    """

    try:
        # email_list = ListMessagesWithLabels(GMAIL, user_id, [label_id_one,label_id_two])  # to read unread emails from inbox
        email_list = ListMessagesWithLabels(service, user_id, label_ids)

        for email in email_list:
            message_id = email['id'] # get id of individual message
            message = service.users().messages().get(userId='me', id=message_id).execute()

            for part in message['payload']['parts']:
                newvar = part['body']

                if 'attachmentId' in newvar:
                    att_id = newvar['attachmentId']
                    att = service.users().messages().attachments().get(userId=user_id, messageId=message_id, id=att_id).execute()
                    data = att['data']
                    file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
                    print(part['filename'])
                    path = ''.join([store_dir, part['filename']])
                    f = open(path, 'wb')
                    f.write(file_data)
                    f.close()

    except Exception as error:
        print('An error occurred: %s' % error)




# Setup the Gmail API
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', ]
CLIENT_SECRETS_FILE = 'client_secret.json'
mail_labels = ['Label_3679404043833618922', 'Label_7190264889161813326']

workingDir = os.environ['USERPROFILE']

gmailDownloadDir = os.path.join(workingDir, 'GmailDownload/')
attachDir = os.path.join(gmailDownloadDir, 'attachments/')
cred_file = os.path.join(gmailDownloadDir, 'credentials.token')
refreshtoken_file = os.path.join(gmailDownloadDir, 'refresh.token')

if 'GmailDownload' not in os.listdir(workingDir):
    os.mkdir(gmailDownloadDir)

if 'attachments' not in os.listdir(gmailDownloadDir):
    os.mkdir(attachDir)


# Get Gmail Credentials
if not os.path.exists(cred_file):
    flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
    credentials = flow.run_local_server()

    with open(cred_file, 'wb') as token:
        pickle.dump(credentials, token)
else:
    with open(cred_file, 'rb') as token:
        credentials = pickle.load(token)

if credentials.expired:
    credentials.refresh(Request())

service = discovery.build('gmail','v1',credentials=credentials)

#GMAIL = discovery.build('gmail', 'v1', http=creds.authorize(Http()))
#service = build('gmail', 'v1', http=creds.authorize(Http()))


GetAttachments(service, user_id='me', label_ids=mail_labels, store_dir=attachDir)

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

вы можете использовать свои собственные ярлыки, если вы уверены, что в именах вы можете передавать их через lablelIds= [], если вы не уверены в первом списке имен ярлыков и выбирать, какие ярлыки вы хотите использовать.

Gmail API может получить все метки, если вы используете метод labels().list(), используйте ссылки ниже

https://developers.google.com/gmail/api/v1/reference/users/labels/list

http://googleapis.github.io/google-api-python-client/docs/dyn/gmail_v1.users.labels.html#list

0 голосов
/ 19 марта 2020

Если вы посмотрите на ссылку, которую вы разместили, то по labelIds[] будет написано

Only return messages with labels that match all of the specified label IDs.

Таким образом, в письме должны быть все ярлыки в списке, а не просто ярлык.

Альтернативой является использование параметра q с чем-то вроде label:MyEmail or label:EmailCool or ...

Проверьте эту страницу: https://support.google.com/mail/answer/7190

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