From 855be693ba552809e1d85ba585e3acb486c98106 Mon Sep 17 00:00:00 2001 From: Rajesh Mudaliyar Date: Tue, 11 Jan 2022 14:58:00 -0800 Subject: [PATCH 01/12] Added pull request template Added pull request template --- .github/pull_request_template.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..1acd3625 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,18 @@ +# Description + +Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +# Is it been tested? +- [ ] Development testing done + +# Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have performed a peer-reviewed with team member(s) +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] Any dependent changes have been merged and published in downstream modules From 4c314229d1dde0e9721e0559904d7e0f660549df Mon Sep 17 00:00:00 2001 From: Rajesh Mudaliyar Date: Tue, 11 Jan 2022 15:37:10 -0800 Subject: [PATCH 02/12] updated header updated header --- .github/pull_request_template.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1acd3625..1429212d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,13 +1,13 @@ -# Description +## Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. Fixes # (issue) -# Is it been tested? +## Is it been tested? - [ ] Development testing done -# Checklist: +## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code From 7e17e6b3fb5e841953533d1f97102c0d1dda7496 Mon Sep 17 00:00:00 2001 From: Steve Bazyl Date: Tue, 11 Jan 2022 16:40:41 -0700 Subject: [PATCH 03/12] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1429212d..ab678c3a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -## Description +# Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. From 9f55a917bc96456ed0522aaae3b84cec4966da72 Mon Sep 17 00:00:00 2001 From: Steve Bazyl Date: Tue, 11 Jan 2022 16:42:30 -0700 Subject: [PATCH 04/12] Update pull_request_template.md --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ab678c3a..c0834862 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,7 +7,7 @@ Fixes # (issue) ## Is it been tested? - [ ] Development testing done -## Checklist: +## Checklist - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code From 74d534f6ebf1377ed0bc52309c45f6eaf8b2da87 Mon Sep 17 00:00:00 2001 From: Steve Bazyl Date: Tue, 11 Jan 2022 16:46:24 -0700 Subject: [PATCH 05/12] Add unit/integration test to checklist --- .github/pull_request_template.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c0834862..b980437f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,8 +4,9 @@ Please include a summary of the change and which issue is fixed. Please also inc Fixes # (issue) -## Is it been tested? +## Has it been tested? - [ ] Development testing done +- [ ] Unit or integration test implemented ## Checklist From 96c4518eb379141e923e1ae35ced7c890e6ca1b0 Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Wed, 12 Jan 2022 04:21:22 +0000 Subject: [PATCH 06/12] created create_draft.py --- gmail/snippet/send mail/create_draft.py | 76 +++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 gmail/snippet/send mail/create_draft.py diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py new file mode 100644 index 00000000..7f48e4b5 --- /dev/null +++ b/gmail/snippet/send mail/create_draft.py @@ -0,0 +1,76 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START gmail_create_draft] + +from __future__ import print_function +import os +import base64 +from email.mime.text import MIMEText +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from google_auth_oauthlib.flow import InstalledAppFlow +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials + +SCOPES =['https://www.googleapis.com/auth/gmail.compose '] + + +def gmailCreateDraft(): + """Create and insert a draft email. + Print the returned draft's message and id. + Returns: Draft object, including draft id and message meta data. + """ + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json', SCOPES) + # If there are no (valid) credentials available, let the user log in. + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file \ + ('credentials.json', SCOPES) + creds = flow.run_local_server(port=0) + # Save the credentials for the next run + with open('token.json', 'w', encoding='UTF') as token: + token.write(creds.to_json()) + + try: + # create gmail api client + service = build('gmail', 'v1', credentials=creds) + + message = MIMEText('This is automated draft mail') + message['to'] = 'gduser1@workspacesamples.dev' + message['from'] = 'gduser2@workspacesamples.dev' + message['subject'] = 'Automated draft' + encoded_message = base64.urlsafe_b64encode\ + (message.as_string().encode()).decode() + + create_message = { + 'message': { + 'raw' : encoded_message + } + } + draft = service.users().drafts().create(userId="me", + body=create_message).execute() + + print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}') + except HttpError as error: + print(F'An error occurred: {error}') + return draft + + +if __name__ == '__main__': + gmailCreateDraft() +# [END gmail_create_draft] From 8b3f022dc38836c4d08749bd097dd16090d0456a Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Wed, 12 Jan 2022 04:23:12 +0000 Subject: [PATCH 07/12] created create_draft.py to create and insert a draft email --- gmail/snippet/send mail/create_draft.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py index 7f48e4b5..8eed1c47 100644 --- a/gmail/snippet/send mail/create_draft.py +++ b/gmail/snippet/send mail/create_draft.py @@ -54,6 +54,7 @@ def gmailCreateDraft(): message['to'] = 'gduser1@workspacesamples.dev' message['from'] = 'gduser2@workspacesamples.dev' message['subject'] = 'Automated draft' + # encoding encoded_message = base64.urlsafe_b64encode\ (message.as_string().encode()).decode() From 1f1b9119e3c900398ab5e811f3a4768512d599c6 Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Wed, 12 Jan 2022 06:42:38 +0000 Subject: [PATCH 08/12] created create_draft_with_attachment.py to create and insert a draft email with attachment --- gmail/snippet/send mail/create_draft.py | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py index 8eed1c47..e6153ef7 100644 --- a/gmail/snippet/send mail/create_draft.py +++ b/gmail/snippet/send mail/create_draft.py @@ -1,16 +1,19 @@ -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +""" +Copyright 2019 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" # [START gmail_create_draft] @@ -27,7 +30,7 @@ SCOPES =['https://www.googleapis.com/auth/gmail.compose '] -def gmailCreateDraft(): +def gmail_create_draft(): """Create and insert a draft email. Print the returned draft's message and id. Returns: Draft object, including draft id and message meta data. @@ -60,9 +63,10 @@ def gmailCreateDraft(): create_message = { 'message': { - 'raw' : encoded_message + 'raw': encoded_message } } + # pylint: disable=E1101 draft = service.users().drafts().create(userId="me", body=create_message).execute() @@ -73,5 +77,5 @@ def gmailCreateDraft(): if __name__ == '__main__': - gmailCreateDraft() + gmail_create_draft() # [END gmail_create_draft] From c5b4e6ba93968e0b77d9405dafad396d83323ce3 Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Wed, 12 Jan 2022 06:43:18 +0000 Subject: [PATCH 09/12] created create_draft.py to create and insert a draft email with attachment --- gmail/snippet/send mail/create_draft.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py index e6153ef7..9d3db76d 100644 --- a/gmail/snippet/send mail/create_draft.py +++ b/gmail/snippet/send mail/create_draft.py @@ -57,7 +57,6 @@ def gmail_create_draft(): message['to'] = 'gduser1@workspacesamples.dev' message['from'] = 'gduser2@workspacesamples.dev' message['subject'] = 'Automated draft' - # encoding encoded_message = base64.urlsafe_b64encode\ (message.as_string().encode()).decode() From e097fd360531c04b1864a345e4266f6741e1242d Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Wed, 12 Jan 2022 07:07:36 +0000 Subject: [PATCH 10/12] created create_draft.py to create and insert a draft email with attachment --- gmail/snippet/send mail/create_draft.py | 29 ++++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py index 9d3db76d..4cc29050 100644 --- a/gmail/snippet/send mail/create_draft.py +++ b/gmail/snippet/send mail/create_draft.py @@ -18,8 +18,8 @@ # [START gmail_create_draft] from __future__ import print_function -import os import base64 +import os from email.mime.text import MIMEText from googleapiclient.discovery import build from googleapiclient.errors import HttpError @@ -27,7 +27,7 @@ from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials -SCOPES =['https://www.googleapis.com/auth/gmail.compose '] +SCOPES = ['https://www.googleapis.com/auth/gmail.compose'] def gmail_create_draft(): @@ -35,30 +35,30 @@ def gmail_create_draft(): Print the returned draft's message and id. Returns: Draft object, including draft id and message meta data. """ + cred = None if os.path.exists('token.json'): - creds = Credentials.from_authorized_user_file('token.json', SCOPES) + cred = Credentials.from_authorized_user_file('token.json', SCOPES) # If there are no (valid) credentials available, let the user log in. - if not creds or not creds.valid: - if creds and creds.expired and creds.refresh_token: - creds.refresh(Request()) + if not cred or not cred.valid: + if cred and cred.expired and cred.refresh_token: + cred.refresh(Request()) else: - flow = InstalledAppFlow.from_client_secrets_file \ - ('credentials.json', SCOPES) - creds = flow.run_local_server(port=0) + flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) + cred = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.json', 'w', encoding='UTF') as token: - token.write(creds.to_json()) + token.write(cred.to_json()) try: # create gmail api client - service = build('gmail', 'v1', credentials=creds) + service = build('gmail', 'v1', credentials=cred) message = MIMEText('This is automated draft mail') message['to'] = 'gduser1@workspacesamples.dev' message['from'] = 'gduser2@workspacesamples.dev' message['subject'] = 'Automated draft' - encoded_message = base64.urlsafe_b64encode\ - (message.as_string().encode()).decode() + encoded_message = base64.urlsafe_b64encode(message.as_string().encode() + ).decode() create_message = { 'message': { @@ -70,8 +70,11 @@ def gmail_create_draft(): body=create_message).execute() print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}') + except HttpError as error: print(F'An error occurred: {error}') + draft = None + return draft From 4cf1c0571ba96f8583d600600334a2051c518459 Mon Sep 17 00:00:00 2001 From: anuraggoogler Date: Tue, 18 Jan 2022 08:49:54 +0000 Subject: [PATCH 11/12] Create and insert a draft email with and without attachment --- gmail/snippet/send mail/create_draft.py | 32 ++--- .../send mail/create_draft_with_attachment.py | 109 ++++++++++++++++++ 2 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 gmail/snippet/send mail/create_draft_with_attachment.py diff --git a/gmail/snippet/send mail/create_draft.py b/gmail/snippet/send mail/create_draft.py index 4cc29050..cdfe8c7f 100644 --- a/gmail/snippet/send mail/create_draft.py +++ b/gmail/snippet/send mail/create_draft.py @@ -14,44 +14,32 @@ limitations under the License. """ - # [START gmail_create_draft] from __future__ import print_function + import base64 -import os from email.mime.text import MIMEText + +import google.auth from googleapiclient.discovery import build from googleapiclient.errors import HttpError -from google_auth_oauthlib.flow import InstalledAppFlow -from google.auth.transport.requests import Request -from google.oauth2.credentials import Credentials - -SCOPES = ['https://www.googleapis.com/auth/gmail.compose'] def gmail_create_draft(): """Create and insert a draft email. Print the returned draft's message and id. - Returns: Draft object, including draft id and message meta data. + Returns: Draft object, including draft id and message meta data. + + Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity + for guides on implementing OAuth2 for the application. """ - cred = None - if os.path.exists('token.json'): - cred = Credentials.from_authorized_user_file('token.json', SCOPES) - # If there are no (valid) credentials available, let the user log in. - if not cred or not cred.valid: - if cred and cred.expired and cred.refresh_token: - cred.refresh(Request()) - else: - flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) - cred = flow.run_local_server(port=0) - # Save the credentials for the next run - with open('token.json', 'w', encoding='UTF') as token: - token.write(cred.to_json()) + creds, _ = google.auth.default() try: # create gmail api client - service = build('gmail', 'v1', credentials=cred) + service = build('gmail', 'v1', credentials=creds) message = MIMEText('This is automated draft mail') message['to'] = 'gduser1@workspacesamples.dev' diff --git a/gmail/snippet/send mail/create_draft_with_attachment.py b/gmail/snippet/send mail/create_draft_with_attachment.py new file mode 100644 index 00000000..bd9e2b7f --- /dev/null +++ b/gmail/snippet/send mail/create_draft_with_attachment.py @@ -0,0 +1,109 @@ +"""Copyright 2019 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +# [START gmail_create_draft_with_attachment] + +from __future__ import print_function + +import base64 +import mimetypes +import os +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 google.auth +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError + + +def gmail_create_draft_with_attachment(): + """Create and insert a draft email with attachment. + Print the returned draft's message and id. + Returns: Draft object, including draft id and message meta data. + + Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity + for guides on implementing OAuth2 for the application. + """ + creds,_ = google.auth.default() + + try: + # create gmail api client + service = build('gmail', 'v1', credentials=creds) + mime_message = MIMEMultipart() + mime_message['to'] = 'gduser1@workspacesamples.dev' + mime_message['from'] = 'gduser2@workspacesamples.dev' + mime_message['subject'] = 'sample with attachment' + text_part = MIMEText('Hi, this is automated mail with attachment.' + 'Please do not reply.') + mime_message.attach(text_part) + image_attachment = build_file_part(file='photo.jpg') + mime_message.attach(image_attachment) + encoded_message = base64.urlsafe_b64encode(mime_message.as_string() + .encode()).decode() + + create_draft_request_body = { + 'message': { + 'raw': encoded_message + } + } + # pylint: disable=E1101 + draft = service.users().drafts().create(userId="me", + body=create_draft_request_body)\ + .execute() + print(F'Draft id: {draft["id"]}\nDraft message: {draft["message"]}') + except HttpError as error: + print(F'An error occurred: {error}') + draft = None + return draft + + +def build_file_part(file): + """Creates a MIME part for a file. + + Args: + file: The path to the file to be attached. + + Returns: + A MIME part that can be attached to a message. + """ + content_type, encoding = mimetypes.guess_type(file) + + if content_type is None or encoding is not None: + content_type = 'application/octet-stream' + main_type, sub_type = content_type.split('/', 1) + if main_type == 'text': + with open(file, 'rb'): + msg = MIMEText('r', _subtype=sub_type) + elif main_type == 'image': + with open(file, 'rb'): + msg = MIMEImage('r', _subtype=sub_type) + elif main_type == 'audio': + with open(file, 'rb'): + msg = MIMEAudio('r', _subtype=sub_type) + else: + with open(file, 'rb'): + msg = MIMEBase(main_type, sub_type) + msg.set_payload(file.read()) + filename = os.path.basename(file) + msg.add_header('Content-Disposition', 'attachment', filename=filename) + return msg + + +if __name__ == '__main__': + gmail_create_draft_with_attachment() + # [END gmail_create_draft_with_attachment] From e895ecc5a5d94ccdc702e11a62630051b2f4bbf7 Mon Sep 17 00:00:00 2001 From: Steve Bazyl Date: Wed, 19 Jan 2022 10:00:29 -0700 Subject: [PATCH 12/12] Update create_draft_with_attachment.py --- gmail/snippet/send mail/create_draft_with_attachment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmail/snippet/send mail/create_draft_with_attachment.py b/gmail/snippet/send mail/create_draft_with_attachment.py index bd9e2b7f..52816758 100644 --- a/gmail/snippet/send mail/create_draft_with_attachment.py +++ b/gmail/snippet/send mail/create_draft_with_attachment.py @@ -39,7 +39,7 @@ def gmail_create_draft_with_attachment(): TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for the application. """ - creds,_ = google.auth.default() + creds, _ = google.auth.default() try: # create gmail api client