Python and Google Gmail API
Hi guys, I will try write this post in english, sorry about some erros, cause I'm studying and improving bit a bit.
Firstly, let me tell you what I intended to do. I'd like built a bot to monitor prices in some sites, if the bot find prices that wourthwhile it send me an email. I could do this using smtplib library, see below:
import
smtplib
gmail_user =
'emailFrom@gmail.com'
gmail_pwd =
'emailFrom@gmail.com password'
FROM =
'emailFrom@gmail.com'
TO = [
'emailTo@gmail.com'
]
#recipient if type(recipient) is list else [recipient]
SUBJECT =
'subject text'
TEXT =
'body text'
# Prepare actual message
message =
"""\From: %s\nTo: %s\nSubject: %s\n\n%s"""
%
(FROM, ", ".join(TO), SUBJECT, TEXT)
try
:
server = smtplib.SMTP(
'smtp.gmail.com'
, 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pwd)
server.sendmail(FROM, TO, message)
server.close()
print
'Successfully sent the mail to emailTo@gmail'
except
:
print
'Failed to send mail'
But, you need
enable access for less secure apps. I didn't like to do this, feeling me unsafe and I would want to use what the Google recomends, and I went study how could use the Google API for Gmail.
I started following the process step by step,
as this tutorial Google asks to do. The quickstart script inside this tutorial enable you only read emails, not send or make other things. When I tried to send an email I received this answer:
HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "Insufficient Permission"
Reading many forums looking for the answer to that message that I could know what was happening.
Note that in quickstart.py, at the line
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly', makes it the only permission is for reading, for another thing you do not have permission.
Here begins the purpose of this post !!!
For it works, follow the steps...
In your
Google Developers Console, click in
Credentials >>
Create credentials and choice
OAuth client ID. Check de option
Other and put any
Name, like
gmail. Click
Create and click
OK to dismiss the resulting dialog. Click the to download (
Download JSON) button to the right of the client ID and move this file to your working directory and rename it
gmail.json.
Note that this step is very similar to Google tutorial.
Now, following the script to send e-mail, it is a mix between quickstart.py and other Google script:
import httplib2
import os
from httplib2 import Http
from apiclient import discovery
from apiclient import errors
import oauth2client
from oauth2client import client
from oauth2client import tools
import base64
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
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://mail.google.com/'
#SCOPES = 'https://mail.google.com/'
CLIENT_SECRET_FILE = 'gmail.json'
APPLICATION_NAME = 'Gmail API Python'
def SendMessage(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: %s' %message['id'])
return message
except errors.HttpError, error:
print ('An error occurred: %s' % error)
def CreateMessage(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 base64 encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.b64encode(message.as_string())}
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-gmail.json')
store = oauth2client.file.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
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
msg = CreateMessage('emailFrom@gmail.com', 'emailTo@gmail.com', 'subject', 'body email')
print SendMessage(service, 'me', msg)
if __name__ == '__main__':
main()
When running for the first time this script opens a tab in your browser requesting permission for this new json. Next time do not need anymore.
I hope this helps, and if it did not work, talk to me.
May the force be with you!