I think that this might not be relevant but for those who are interested and getting the same problem :
I am using the google API example too (the one without the attachment) and I realised that the attachment is put only when the text in the subject or the body is NOT a complete string i.e. the string which is being put in the subject or the body is not a single string but an collection of strings.
To explain better :
message = (service.users().messages().send(userId='me', body=body).execute())
body = ("Your OTP is", OTP)
This (body = ("Your OTP is", OTP)
) may work for print() command, but it doesn't work for this case. You can change this :
message = (service.users().messages().send(userId='me', body=body).execute())
body = ("Your OTP is", OTP)
to :
CompleteString = "Your OTP is " + OTP
message = (service.users().messages().send(userId='me', body=body).execute())
body = (CompleteString)
The above lines make the 2 parts of the body into a single string.
Also : The 'noname' file that is put as an attachment contains only the written string. So, if you follow this :
message = (service.users().messages().send(userId='me', body=body).execute())
body = ("Your OTP is", OTP)
So all you'll get in the file will be : "Your OTP is "
I am also adding the entire code that I got after modifying the already existing sample code here : https://developers.google.com/gmail/api/quickstart/python
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from email.mime.text import MIMEText
import base64
sender = "sender_mail"
print("Welcome to the Mail Service!")
reciever = input("Please enter whom you want to send the mail to - ")
subject = input("Please write your subject - ")
msg = input("Please enter the main body of your mail - ")
SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 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.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
message = MIMEText(msg)
message['to'] = reciever
message['from'] = sender
message['subject'] = subject
raw = base64.urlsafe_b64encode(message.as_bytes())
raw = raw.decode()
body = {'raw' : raw}
message = (service.users().messages().send(userId='me', body=body).execute())
Please also note that this code only works for text that is put through the mail.
P.S. I am using Python 3.8 so the above code might not work for Python 2.