from apiclient.discovery import build from apiclient import errors from email.message import EmailMessage from httplib2 import Http from oauth2client import client, tools import argparse import base64 import json import oauth2client import os SCOPES = 'https://www.googleapis.com/auth/gmail.modify' CLIENT_SECRET_FILE = 'secret.json' APPLICATION_NAME = 'Swaptions' def get_gmail_service(): """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. """ credential_dir = '.credentials' if not os.path.exists(credential_dir): os.makedirs(credential_dir) credential_path = os.path.join(credential_dir, 'guillaume.horel@serenitascapital.com.json') store = oauth2client.file.Storage(credential_path) credentials = store.get() if not credentials or credentials.invalid: flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES) flow.user_agent = APPLICATION_NAME credentials = tools.run_flow(flow, store, flags) print('Storing credentials to ' + credential_path) service = build('gmail', 'v1', http=credentials.authorize(Http())) return service def ListMessagesWithLabels(service, user_id, label_ids=[]): """List all Messages of the user's mailbox with label_ids applied. 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. label_ids: Only return Messages with these labelIds applied. Returns: List of Messages that have all required Labels applied. Note that the returned list contains Message IDs, you must use get with the appropriate id to get the details of a Message. """ try: response = service.users().messages().list(userId=user_id, labelIds=label_ids).execute() if 'messages' in response: yield from response['messages'] while 'nextPageToken' in response: page_token = response['nextPageToken'] response = service.users().messages().list(userId=user_id, labelIds=label_ids, pageToken=page_token).execute() yield from response['messages'] except errors.HttpError as error: print(json.loads(error.content.decode('utf-8'))['error']['message']) def ListHistory(service, user_id, label_id=None, start_history_id=10000): """List History of all changes to the user's mailbox. 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. start_history_id: Only return Histories at or after start_history_id. Returns: A list of mailbox changes that occurred after the start_history_id. """ history = (service.users().history().list(userId=user_id, startHistoryId=start_history_id, historyTypes="messageAdded", labelId=label_id) .execute()) changes = history['history'] if 'history' in history else [] for change in changes: if 'messagesAdded' in change: for c in change['messagesAdded']: yield c['message'] while 'nextPageToken' in history: page_token = history['nextPageToken'] history = (service.users().history().list(userId=user_id, startHistoryId=start_history_id, pageToken=page_token).execute()) for change in history['history']: if 'messagesAdded' in change: for c in change['messagesAdded']: yield c['message'] def labels_dict(service, user_id): """Returns a dictionary mapping labels to labelids. Args: service: Authorized Gmail API service instance. user_id: User's email address. The special value "me" Returns: dictionary mapping labels to labelids. """ try: response = service.users().labels().list(userId=user_id).execute() labels = response['labels'] return {label['name']: label['id'] for label in labels} except errors.HttpError as error: print(json.loads(error.content.decode('utf-8'))['error']['message']) class GmailMessage(EmailMessage): _service = get_gmail_service() _labels = labels_dict(_service, 'me') def msgdict(self): return {'raw': base64.urlsafe_b64encode(self.as_bytes()).decode()} def send(self): try: message = (self._service.users().messages(). send(userId='me',body=self.msgdict()) .execute()) print('Message Id: %s' % message['id']) except errors.HttpError as error: print('An error occurred: %s' % error) @staticmethod def list_msg_ids(label, start_history_id=None): if start_history_id is not None: return ListHistory(GmailMessage._service, 'me', label_id=GmailMessage._labels[label], start_history_id=start_history_id) else: return ListMessagesWithLabels(GmailMessage._service, 'me', label_ids=[GmailMessage._labels[label]]) @classmethod def from_id(cls, msg_id, user_id='me'): try: message = (cls._service.users().messages(). get(userId=user_id, id=msg_id, format='raw').execute()) instance = email.message_from_bytes( base64.urlsafe_b64decode(message['raw']), policy=email.policy.EmailPolicy()) instance.history_id = message['historyId'] return instance except errors.HttpError as error: print(json.loads(error.content.decode('utf-8'))['error']['message']) 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. """ message = GmailMessage() message.set_content("Hello everyone!") message['To'] = 'guillaume.horel@gmail.com' message['Subject'] = 'pomme' message.send() if __name__ == '__main__': message = main()