Hello and many thanks for your replies
I have begun my programming journey a couple of days ago just for fun, and because I have liked Python for a while now, but never actually took a chance to look into it or try to experiment with it.
A day ago it came across my mind what if I could download attachments from a specific set of emails by custom user labels, ie "MyEmail" or "EmailCool", and store all of the attachments that were under these labels.
I have experimented a bit with the Gmail API, and did some of the initial testing myself through: https://developers.google.com/gmail/api/v1/reference/users/messages/list but the problem being is that I can only grab and store attachments if I only specify one of the custom labels I had created ie "MyEmail" as a parameter.
If I input both of these labels as parameters, the API throws a response of resultSizeEstimate = 0, meaning as if there were no e-mails.
Is there anything wrong I am applying under the service.users().messages.list() method? Again my code works if I give one label as a parameter, but not two custom labels at the same time.
Here is my code, for your reference:
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)