Download Attachments from gmail using Gmail API












9















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']










share|improve this question



























    9















    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']










    share|improve this question

























      9












      9








      9


      2






      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']










      share|improve this question














      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Sep 14 '14 at 11:13









      Rahul KulhariRahul Kulhari

      7401037




      7401037
























          5 Answers
          5






          active

          oldest

          votes


















          29














          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





          share|improve this answer





















          • 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



















          4














          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)





          share|improve this answer































            3














            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.)






            share|improve this answer































              3














              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





              share|improve this answer
























              • 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











              • 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



















              0














              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






              share|improve this answer


























              • 'wb' instead of 'w'

                – CodeFarmer
                Jan 8 at 4:42











              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
              });


              }
              });














              draft saved

              draft discarded


















              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









              29














              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





              share|improve this answer





















              • 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
















              29














              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





              share|improve this answer





















              • 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














              29












              29








              29







              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





              share|improve this answer















              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






              share|improve this answer














              share|improve this answer



              share|improve this answer








              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














              • 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













              4














              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)





              share|improve this answer




























                4














                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)





                share|improve this answer


























                  4












                  4








                  4







                  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)





                  share|improve this answer













                  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)






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 14 '17 at 23:22









                  f9nf9n

                  435




                  435























                      3














                      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.)






                      share|improve this answer




























                        3














                        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.)






                        share|improve this answer


























                          3












                          3








                          3







                          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.)






                          share|improve this answer













                          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.)







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Sep 15 '14 at 16:08









                          Eric DEric D

                          5,4841822




                          5,4841822























                              3














                              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





                              share|improve this answer
























                              • 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











                              • 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
















                              3














                              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





                              share|improve this answer
























                              • 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











                              • 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














                              3












                              3








                              3







                              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





                              share|improve this answer













                              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






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Aug 9 '17 at 13:32









                              TodorTodor

                              7,69323147




                              7,69323147













                              • 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











                              • 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











                              • 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











                              • 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











                              0














                              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






                              share|improve this answer


























                              • 'wb' instead of 'w'

                                – CodeFarmer
                                Jan 8 at 4:42
















                              0














                              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






                              share|improve this answer


























                              • 'wb' instead of 'w'

                                – CodeFarmer
                                Jan 8 at 4:42














                              0












                              0








                              0







                              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






                              share|improve this answer















                              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







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              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



















                              • '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


















                              draft saved

                              draft discarded




















































                              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.




                              draft saved


                              draft discarded














                              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





















































                              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







                              Popular posts from this blog

                              How to pass form data using jquery Ajax to insert data in database?

                              National Museum of Racing and Hall of Fame

                              Guess what letter conforming each word