Download Attachments from gmail using Gmail API
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']
python email gmail gmail-api
add a comment |
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']
python email gmail gmail-api
add a comment |
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']
python email gmail gmail-api
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']
python email gmail gmail-api
python email gmail gmail-api
asked Sep 14 '14 at 11:13
Rahul KulhariRahul Kulhari
7401037
7401037
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
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, 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']['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, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
add a comment |
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)
add a comment |
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.)
add a comment |
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
How are you dealing with those missed attachments? All I see is afile_data = Nonewhich then does nothing with it.
– guival
Sep 20 '17 at 11:57
Take a look at thewhilestatement this is where difference comes from. The lastelse: file_data = Noneis just for code safety.
– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])
– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25832631%2fdownload-attachments-from-gmail-using-gmail-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
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, 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']['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, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
add a comment |
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, 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']['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, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
add a comment |
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, 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']['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, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
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, 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']['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, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
edited Jan 19 '16 at 17:09
Simon Johansson
18114
18114
answered Dec 6 '14 at 19:44
Ilya V. SchurovIlya V. Schurov
4,06211852
4,06211852
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
add a comment |
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
1
1
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
For those who are not able to write in the file, use 'wb' because sometimes data is not string it is actually binary.
– Shashank
Dec 3 '17 at 11:06
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
and inline images ?
– PreguntonCojoneroCabrón
Mar 31 '18 at 10:19
add a comment |
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)
add a comment |
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)
add a comment |
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)
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)
answered Dec 14 '17 at 23:22
f9nf9n
435
435
add a comment |
add a comment |
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.)
add a comment |
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.)
add a comment |
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.)
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.)
answered Sep 15 '14 at 16:08
Eric DEric D
5,4841822
5,4841822
add a comment |
add a comment |
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
How are you dealing with those missed attachments? All I see is afile_data = Nonewhich then does nothing with it.
– guival
Sep 20 '17 at 11:57
Take a look at thewhilestatement this is where difference comes from. The lastelse: file_data = Noneis just for code safety.
– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])
– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
How are you dealing with those missed attachments? All I see is afile_data = Nonewhich then does nothing with it.
– guival
Sep 20 '17 at 11:57
Take a look at thewhilestatement this is where difference comes from. The lastelse: file_data = Noneis just for code safety.
– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])
– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
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
answered Aug 9 '17 at 13:32
TodorTodor
7,69323147
7,69323147
How are you dealing with those missed attachments? All I see is afile_data = Nonewhich then does nothing with it.
– guival
Sep 20 '17 at 11:57
Take a look at thewhilestatement this is where difference comes from. The lastelse: file_data = Noneis just for code safety.
– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])
– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
How are you dealing with those missed attachments? All I see is afile_data = Nonewhich then does nothing with it.
– guival
Sep 20 '17 at 11:57
Take a look at thewhilestatement this is where difference comes from. The lastelse: file_data = Noneis just for code safety.
– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])
– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
How are you dealing with those missed attachments? All I see is a
file_data = None which then does nothing with it.– guival
Sep 20 '17 at 11:57
How are you dealing with those missed attachments? All I see is a
file_data = None which then does nothing with it.– guival
Sep 20 '17 at 11:57
Take a look at the
while statement this is where difference comes from. The last else: file_data = None is just for code safety.– Todor
Sep 20 '17 at 12:25
Take a look at the
while statement this is where difference comes from. The last else: file_data = None is just for code safety.– Todor
Sep 20 '17 at 12:25
ah, I see, the difference is you also also deal with the data in the upper most level (
payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])– guival
Sep 20 '17 at 13:57
ah, I see, the difference is you also also deal with the data in the upper most level (
payload['body']['data']) while other answers only look at the body within the parts (payload['parts'])– guival
Sep 20 '17 at 13:57
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
what is urlsafe_b64decode ?
– PreguntonCojoneroCabrón
Apr 1 '18 at 10:54
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
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
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
edited Jan 8 at 7:03
Todor
7,69323147
7,69323147
answered Mar 23 '17 at 16:18
Cam TCam T
594
594
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
'wb' instead of 'w'
– CodeFarmer
Jan 8 at 4:42
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25832631%2fdownload-attachments-from-gmail-using-gmail-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown