问题
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
https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
but the same code i tried then i am getting error:
AttributeError: 'Resource' object has no attribute 'user'
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']
回答1:
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
回答2:
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
回答3:
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)
回答4:
It's definitely "users()". The format of the response Message is largely dependent on the format parameter you use. If you use the default (FULL) then parts will either have part['body']['data'] or, when data is large, with an "attachment_id" field that you can pass to messages().attachments().get().
If you look at the attachments docs you'll see this: https://developers.google.com/gmail/api/v1/reference/users/messages/attachments
(Would be nice if this was also mentioned on the main messages docs page also.)
回答5:
I made the following changes for the code above and works totally fine for every email id contains attachment documents, I hope this can help because with the API example you will get an error Key.
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.
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']['parts']:
newvar = part['body']
if 'attachmentId' in newvar:
att_id = newvar['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'))
print(part['filename'])
path = ''.join([store_dir, part['filename']])
f = open(path, 'wb')
f.write(file_data)
f.close()
except errors.HttpError, error:
print 'An error occurred: %s' % error
Google Official API for Attachments
来源:https://stackoverflow.com/questions/25832631/download-attachments-from-gmail-using-gmail-api