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 not making it easy. It's all well and good to suggest we Upgrade to a more secure app that uses the most up to date security measures
, but that doesn't help me work out how to upgrade bits of code that look like this:
server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.login(GMAIL_USER, GMAIL_PASSWORD) server.sendmail(FROM, TO, MESSAGE) server.close()
Sure, I'll go and turn on "Access for less secure apps", but if anyone has worked out what to replace this code with, I'll be grateful.
This was painful, but I seem to have something going now...
I don't think it will be too hard to attain, as I was stumbling through converting packages without hitting anything massive: just the usual 2to3 stuff. Yet after a couple of hours I got tired of swimming upstream. At time of writing, I couldn't find a published package for public consumption for Python 3. The python 2 experience was straight-forward (in comparison).
No doubt, over time, this will change. Ultimately you need to download a client_secret.json
file. You can only (probably) do this setting up stuff via a web browser:
API's and Auth
-> Credentials
OAuth
select Create New Client ID
Installed Application
as the application type and Other Download JSON
. Do that. It's your client_secret.json
—the passwords so to speakBut wait that's not all!
You have to give your application a "Product Name" to avoid some odd errors. (see how much I suffered to give you this ;-)
API's & auth
-> Consent Screen
Newsflash! Whoa. Now there's even more!
Yay. Now we can update the emailing script.
You need to run the script interactively the first time. It will open a web browser on your machine and you'll grant permissions (hit a button). This exercise will save a file to your computer gmail.storage
which contains a reusable token.
[I had no luck transferring the token to a machine which has no graphical browser functionality—returns an HTTPError. I tried to get through it via the lynx graphical browser. That also failed because google have set the final "accept" button to "disabled"!? I'll raise another question to jump this hurdle (more grumbling)]
First you need some libraries:
pip install --upgrade google-api-python-client pip install --upgrade python-gflags
Storage
instructions expect itgmail.storage
fileFinally some code:
import base64 import httplib2 from email.mime.text import MIMEText from apiclient.discovery import build from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import run # Path to the client_secret.json file downloaded from the Developer Console CLIENT_SECRET_FILE = 'client_secret.json' # Check https://developers.google.com/gmail/api/auth/scopes for all available scopes OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.compose' # Location of the credentials storage file STORAGE = Storage('gmail.storage') # Start the OAuth flow to retrieve credentials flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE) http = httplib2.Http() # Try to retrieve credentials from storage or run the flow to generate them credentials = STORAGE.get() if credentials is None or credentials.invalid: credentials = run(flow, STORAGE, http=http) # Authorize the httplib2.Http object with our credentials http = credentials.authorize(http) # Build the Gmail service from discovery gmail_service = build('gmail', 'v1', http=http) # create a message to send message = MIMEText("Message goes here.") message['to'] = "[email protected]" message['from'] = "[email protected]" message['subject'] = "your subject goes here" body = {'raw': base64.b64encode(message.as_string())} # send it try: message = (gmail_service.users().messages().send(userId="me", body=body).execute()) print('Message Id: %s' % message['id']) print(message) except Exception as error: print('An error occurred: %s' % error)
Hopefully that gets us all started. Not as simple as the old way, but does look a lot less complicated now I can see it in the flesh.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With