Download Attachments from gmail using Gmail API Download Attachments from gmail using Gmail API python python

Download Attachments from gmail using Gmail API


Expanding @Eric answer, I wrote the following corrected version of GetAttachments function from the docs:

# based on Python example from # https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get# which is licensed under Apache 2.0 Licenseimport base64from apiclient import errorsdef GetAttachments(service, user_id, msg_id):    """Get and store attachment from Message with given id.    :param service: Authorized Gmail API service instance.    :param user_id: User's email address. The special value "me" can be used to indicate the authenticated user.    :param msg_id: ID of Message containing attachment.    """    try:        message = service.users().messages().get(userId=user_id, id=msg_id).execute()        for part in message['payload']['parts']:            if part['filename']:                if 'data' in part['body']:                    data = part['body']['data']                else:                    att_id = part['body']['attachmentId']                    att = service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()                    data = att['data']                file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))                path = part['filename']                with open(path, 'w') as f:                    f.write(file_data)    except errors.HttpError, error:        print 'An error occurred: %s' % error


You can still miss attachments by following @Ilya V. Schurov or @Cam T answers, the reason is because the email structure can be different based on the mimeType.

Inspired by this answer, here is my approach to the problem.

import base64from apiclient import errorsdef GetAttachments(service, user_id, msg_id, store_dir=""):    """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.            store_dir: The directory used to store attachments.    """    try:        message = service.users().messages().get(userId=user_id, id=msg_id).execute()        parts = [message['payload']]        while parts:            part = parts.pop()            if part.get('parts'):                parts.extend(part['parts'])            if part.get('filename'):                if 'data' in part['body']:                    file_data = base64.urlsafe_b64decode(part['body']['data'].encode('UTF-8'))                    #self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], part['size']))                elif 'attachmentId' in part['body']:                    attachment = service.users().messages().attachments().get(                        userId=user_id, messageId=message['id'], id=part['body']['attachmentId']                    ).execute()                    file_data = base64.urlsafe_b64decode(attachment['data'].encode('UTF-8'))                    #self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], attachment['size']))                else:                    file_data = None                if file_data:                    #do some staff, e.g.                    path = ''.join([store_dir, part['filename']])                    with open(path, 'w') as f:                        f.write(file_data)    except errors.HttpError as error:        print 'An error occurred: %s' % error


i tested codes above and doesn't worked. And i updated some stuff for other posts. WriteFileError

    import base64    from apiclient import errors    def GetAttachments(service, user_id, msg_id, prefix=""):       """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:           message = service.users().messages().get(userId=user_id, id=msg_id).execute()           for part in message['payload'].get('parts', ''):              if part['filename']:                  if 'data' in part['body']:                     data=part['body']['data']                  else:                     att_id=part['body']['attachmentId']                     att=service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()                     data=att['data']            file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))            path = prefix+part['filename']            with open(path, 'wb') as f:                f.write(file_data)        except errors.HttpError as error:            print('An error occurred: %s' % error)