Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download Attachments from gmail using Gmail API

Tags:

I am using Gmail API to access my Gmail data and Google Python API client.

According to documentation to get the message attachment they gave one sample for Python. But the same code I tried then I am getting an error:

AttributeError: 'Resource' object has no attribute 'user'

The line where I am getting error:

message = service.user().messages().get(userId=user_id, id=msg_id).execute() 

So I tried users() by replacing user():

message = service.users().messages().get(userId=user_id, id=msg_id).execute() 

But I am not getting part['body']['data'] in for part in message['payload']['parts'].

like image 434
Rahul Kulhari Avatar asked Sep 14 '14 11:09

Rahul Kulhari


People also ask

Can you automatically download attachments from Gmail?

Save Emails is an email backup and archiving tool for Gmail that lets you automatically download email messages and file attachments from Gmail to Google Drive.

How do I find my Gmail API attachment?

In order to retrieve the the ID of the attachments of a certain message, you would have to get the message resource via Users. messages. get, and from that response, retrieve the ID of the attachment.

How do I bulk download attachments in Gmail?

How to bulk-download all attachments in Gmail. The fastest and easiest way to get all of the Gmail attachments in one go is to forward the whole email back to yourself. To do this, open the email, and in the top menu, select More—>Forward All. One email window will now contain all email conversations.


2 Answers

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 License  import base64 from apiclient import errors  def 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 
like image 56
Ilya V. Schurov Avatar answered Sep 24 '22 17:09

Ilya V. Schurov


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 base64 from apiclient import errors  def 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 
like image 24
Todor Avatar answered Sep 20 '22 17:09

Todor