How to send an email through gmail without enabling 'insecure access'?

后端 未结 6 671
你的背包
你的背包 2020-12-12 17:35

Google are pushing us to improve the security of script access to their gmail smtp servers. I have no problem with that. In fact I\'m happy to help.

But they\'re n

6条回答
  •  囚心锁ツ
    2020-12-12 17:55

    I'm including some code that has been updated for python 3 usage - it seems to send emails once you get the necessary permissions and OAuth tokens working. It's mostly based off the google api website samples

        from __future__ import print_function
    
    import base64
    import os
    from email.mime.text import MIMEText
    
    import httplib2
    from apiclient import discovery
    from googleapiclient import errors
    from oauth2client import client
    from oauth2client import tools
    from oauth2client.file import Storage
    
    try:
        import argparse
    
        flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
    except ImportError:
        flags = None
    
    # If modifying these scopes, delete your previously saved credentials
    # at ~/.credentials/gmail-python-quickstart.json
    SCOPES = 'https://www.googleapis.com/auth/gmail.send'
    CLIENT_SECRET_FILE = 'client_secret.json'
    APPLICATION_NAME = 'Gmail API Python Quickstart'
    
    
    def get_credentials():
        """Gets valid user credentials from storage.
    
        If nothing has been stored, or if the stored credentials are invalid,
        the OAuth2 flow is completed to obtain the new credentials.
    
        Returns:
            Credentials, the obtained credential.
        """
        home_dir = os.path.expanduser('~')
        credential_dir = os.path.join(home_dir, '.credentials')
        if not os.path.exists(credential_dir):
            os.makedirs(credential_dir)
        credential_path = os.path.join(credential_dir,
                                       'gmail-python-quickstart.json')
    
        store = Storage(credential_path)
        credentials = store.get()
        if not credentials or credentials.invalid:
            flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
            flow.user_agent = APPLICATION_NAME
            if flags:
                credentials = tools.run_flow(flow, store, flags)
            else:  # Needed only for compatibility with Python 2.6
                credentials = tools.run(flow, store)
            print('Storing credentials to ' + credential_path)
        return credentials
    
    
    to = 'test@email.com'
    sender = 'test@email.com'
    subject = 'test emails'
    message_text = 'hello this is a text test message'
    user_id = 'me'
    
    def create_message(sender, to, subject, message_text):
        """Create a message for an email.
    
        Args:
          sender: Email address of the sender.
          to: Email address of the receiver.
          subject: The subject of the email message.
          message_text: The text of the email message.
    
        Returns:
          An object containing a base64url encoded email object.
        """
        message = MIMEText(message_text)
        message['to'] = to
        message['from'] = sender
        message['subject'] = subject
        return {'raw': (base64.urlsafe_b64encode(message.as_bytes()).decode())}
    
    
    def send_message(service, user_id, message):
        """Send an email message.
    
        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.
          message: Message to be sent.
    
        Returns:
          Sent Message.
        """
        try:
            message = (service.users().messages().send(userId=user_id, body=message)
                       .execute())
            print('Message Id: {}'.format(message['id']))
            return message
        except errors.HttpError as error:
            print('An error occurred: {}'.format(error))
    
    
    def main():
        """Shows basic usage of the Gmail API.
    
        Creates a Gmail API service object and outputs a list of label names
        of the user's Gmail account.
        """
        credentials = get_credentials()
        http = credentials.authorize(httplib2.Http())
        service = discovery.build('gmail', 'v1', http=http)
    
        msg = create_message(sender,to,subject,message_text)
        message = (service.users().messages().send(userId=user_id, body=msg)
                   .execute())
        print('Message Id: {}'.format(message['id']))
        results = service.users().messages().list(userId='me').execute()
        labels = results.get('labels', [])
    
        if not labels:
            print('No labels found.')
        else:
            print('Labels:')
            for label in labels:
                print(label['name'])
    
    
    if __name__ == '__main__':
        main()
    

提交回复
热议问题