--I'm struggling to send an email with a file attached to it.Hi!I'm struggling with the create_message_with_attachment function (the rest works, create_message_without_attachment works ).I did read google documentation. The stack threads talking about it focus on complex issue (while mixing up on the top of it different syntax of python version). Posting this in stack will be down-voted as duplicated (stack has its limit).I'm just trying with the script bellow to create an email, attach a file to it and send it.The python 3.6 script returns:encoders.encode_base64(part)
NameError: name 'encoders' is not defined
import httplib2
import os
import oauth2client
from oauth2client import client, tools
import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from apiclient import errors, discovery
SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Send Email'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir) #create folder if doesnt exist
credential_path = os.path.join(credential_dir, 'gmail-python-email-send.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
credentials = tools.run_flow(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def SendMessage(sender, to, subject, msgHtml, msgPlain):
credentials = get_credentials()
http = httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('gmail', 'v1', http=http)
# #with attachement
message_with_attach = create_message_with_attachment(sender, to, subject, msgHtml, msgPlain)
SendMessageInternal(service, "me", message_with_attach)
# #without attachment
# message_without_attachment = create_message_without_attachment(sender, to, subject, msgHtml, msgPlain)
# SendMessageInternal(service, "me", message_without_attachment)
def SendMessageInternal(service, user_id, message):
try:
message = (service.users().messages().send(userId=user_id, body=message).execute()) ####need to get user_id before
message_ID = message['id']
print(f'Message Id: {message_ID}')
return [message, message_ID] #return value as list
except errors.HttpError as error:
print(f'An error occurred: {error}')
def create_message_without_attachment (sender, to, subject, msgHtml, msgPlain):
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = to
msg.attach(MIMEText(msgPlain, 'plain'))
msg.attach(MIMEText(msgHtml, 'html'))
raw = base64.urlsafe_b64encode(msg.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
def create_message_with_attachment(sender, to, subject, msgHtml, msgPlain):
msg = MIMEMultipart('alternative')
msg['To'] = to
msg['From'] = sender
msg['Subject'] = subject
msg.attach(MIMEText(msgPlain, 'plain'))
msg.attach(MIMEText(msgHtml, 'html'))
# the problem comes from this part
part = MIMEBase('application', "octet-stream")
part.set_payload( open(r"C:\Users\xx\Desktop\test_Attachment.txt","rb").read() )
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(f)))
msg.attach(part)
raw = base64.urlsafe_b64encode(msg.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
def main():
to = "your...@gmail.com"
sender = "mye...@gmail.com"
subject = "subject test1"
msgHtml = r'Hi<br/>Html <b>hello</b>'
msgPlain = "Hi\nPlain Email"
message_text= "this is message text"
SendMessage(sender, to, subject, msgHtml, msgPlain)
if __name__ == '__main__':
main()
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/7c6e9e54-6d62-473a-bc80-5d5c71e75be5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Thanks a lot Alex, you are right the from email import encoders was missing. Now it sends the email but without the file attached to it.Any idea what could go wrong with this function? (I corrected other things on it, it's the result of patchwork of code I took from several places)
def create_message_with_attachment(sender, to, subject, msgHtml, msgPlain):
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['To'] = to
msg['From'] = sender
msg['Subject'] =
subject
# Record the MIME types of both parts - text/plain and text/html
part1 = MIMEText(msgPlain, 'plain')
part2 = MIMEText(msgHtml, 'html')
# create .txt attachment
filename=r"C:\Users\xxx\Desktop\test_Attachment.txt"
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="txt")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
# Attach parts into message container.
msg.attach(att)
msg.attach(part1)
msg.attach(part2)
# raw = base64.urlsafe_b64encode(msg.as_bytes())
raw= encoders.encode_base64(msg)
raw = raw.decode()
body = {'raw': raw}
return body
--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/3017717e-019f-47a8-96ce-4c45723e9d31%40googlegroups.com.
--
You received this message because you are subscribed to a topic in the Google Groups "Google App Engine" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-appengine/O94qnKnQu-k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/CAE46Be-tAdEGj84ExamTXv5HOGptW-CanLpDxYy8t%3DnTgqmhVw%40mail.gmail.com.
I understand that this kind of question bother you, and the people of this group, but as I mention in my email, it does also bother people on the stack. (This question will be seen and down-voted as duplicate.)Since it’s a question about a Google product (Gmail API), the logical way would be to post it in forum own by Google,
since users seeking help are under its responsibility. This Google group seems to be the only one talking about Gmail api.
The reality is that Google escape from its responsibility by asking users to use stack. But you seem to ignore that Google doesn’t own stack, and that stack has not been built to serve as Gmail api discussion*. Stack has its own rules, you can’t ask such question (without losing points).
So asking Gmail API user seeking for help to leave this group might clear your conscience but that’s pretty much all it does.
* Just another example: I did struggle with several points from the code Google that causes an error in python 3 (google don't update its code). I wanted to share one of them on a stack, in order to help other users. It cost me some reputation point for those —so I
won’t do it again. (I then set my answer as "wiki", to don’t lose more points)
ps: By the way if I deleted the question and posted it again in this group it’s because I could not edit it, the topic was not accurate anymore and misleading (Google should probably learn from what other company is doing, like Microsoft
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/CA%2BECagPy-nLc0kKpd5ugHJbEoVcmrW7YV_n3OXrkt4eaj_bSMA%40mail.gmail.com.
Note that these functions are not meaningful for a multipart message. They must be applied to individual subparts instead, and will raise a TypeError
if passed a message whose type is multipart.
My reputation score there is over half a million, so I must not have lost too many points by asking inappropriate questions -- which suggests to me that I do know which questions are or are not appropriate there.
"Sharing to help other users", not in response to specific technical questions, is not within this remit
--
You received this message because you are subscribed to a topic in the Google Groups "Google App Engine" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-appengine/O94qnKnQu-k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/afa7d415-2146-4650-a0fa-5618b7665cd5%40googlegroups.com.
Hi Alex,First I apologize for the italic, that wasn't mature. But your reaction was super: I warmly thank you for that!
I also thank you for the quality of your answer. Especially for pointing me to the right forum (I'm both impressed and sorry. Impressed you did not send me to the right forum right away, it says a lot about you. I'm also sorry to have wasted your time).
Regarding the Google group: I did the "brief search" you are talking about to try to find the right Gmail api forum, I just typed "Gmail api" and this group was the most accurate group name. The other result asked me to post downvoted question on Stack.The Google-appengine name surprised me, but since I usually find Google documentation obscure, coming from Google an obscure name sounds logical (it's even more obscure since the right group did not even come as the first result).
Concerning Stack, I have a completely different experience, or I would say you have a completely different perception than all the stack users I know. Your explanation is interesting:My reputation score there is over half a million, so I must not have lost too many points by asking inappropriate questions -- which suggests to me that I do know which questions are or are not appropriate there.But I have an even simpler explanation : Your question are not down-voted because the questions you ask aren't basic.
Basic users struggle in Stack, because they are looking for basic information, the one that seem so obvious to people like you (it's not judgmental, on the contrary) that nobody asks them. Asking these basic questions aren't welcome on Stack (at all) because they look stupid, or lacking a research investment. (It also applies to the "a brief search suggests". My brief search suggested this Google-appengine group). Many stack people don't really get that some stack users aren't all programmers. I understand that stack hasn't been made for the basic users, I accept it and I'm glad to have it, but I have a completely different opinion than yours. ((It's fascinating how people could have different way to look at the same reality.))
"Sharing to help other users", not in response to specific technical questions, is not within this remitOk, but that's a kind of answers that are very, very precious for basic users (because they seems too obvious that nobody talks about it).
I just finish by warmly thanking you for the million people you have helped, that's really something to be proud of ―more of anything. I also thank you for the kindness of your message.I wish you the best, and greeting from the other stack universe: the wild west stack of the basic user!(*You would have guess that the stack users I know aren't programmers either!)
--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/afa7d415-2146-4650-a0fa-5618b7665cd5%40googlegroups.com.
Hi again Alex, I just found your email in the thread, the one you were talking about the raw= encoders.encode_base64(msg) .I discovered that bug yesterday and commented that line (which correctly send the email ― without the attachment though, would have been too easy!). But I did not know what was wrong with this encoder (so many thing to understand in that code), so I thank you for your explanation.
I'm really impressed you helped me despite the italic line and above all: despite the fact I ended up in the wrong forum (it's embarrassing!) you are an amazing guy...
So thanks a lot, I finally took the "risk"to face a downvote mob justice by posted it in stack. I'm also curious to see if it will be downvoted (so I could sue Google for that!)
--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-appengine+unsubscribe@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at https://groups.google.com/group/google-appengine.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/CA%2BECagMZZ8CwjSo9-aMhtVbynw42EmfGGFXmndxfmjDRefhzNw%40mail.gmail.com.
Since most Qs are basic, how could SO have become so popular if basic Qs were discouraged?!
- yes, our docs (and in particular, product naming) could definitely be better,
To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/CAE46Be9yk5pSnUdNa6_8K%2Br2CBJ%2BU83VMMSp0BVC5FWAtXvN8w%40mail.gmail.com.