Advanced mailto use in Python
Asked Answered
C

2

8

I'm trying to send an email with custom recipient, subject and body in Python. This means I don't want to use Python's smtp packages, but something like webbrowser because I need this to open the default email client (Thunderbird in my case) with said arguments.

import webbrowser
webbrowser.open("mailto:[email protected]&subject=mysubject", new=1)

works but I need it to get the recipient from a string I previously found and body from a text file I previously created.

Is there any "simple" way to do it that I cannot find? Thanks in advance.

Charente answered 1/9, 2016 at 9:15 Comment(8)
Use string concatenation to create the argument to webbrowser.open(). What's the problem?Marishamariska
Why does customizing the recipient, subject,and browser mean you have to do it in the web browser? The smtp package can fill those fields in.Marishamariska
I didn't phrase it well, editing the post now.Charente
OK, so what's the problem? Don't you know how to concatenate strings in Python using the + operator?Marishamariska
Do you need also a function for getting the recipient from somewhere and save it to a string or you have no problem for that and you only need a way to get the body from a text file? If you need help also for the recipient, provide more information.Illicit
No I don't know how to concatenate strings in this case. I never coded before in my life, just trying to learn by doing, most the time I can, this time I can't. I got the string that contains the recipient email and the text file for the body. What I need is how to tell Python "Open Thunderbird, use X as recipient, Y as subject and Z.txt as body".Charente
Do you have only 1 recipient or more than 1? If more than 1, do you have a fixed list that never changes? Where do you get the recipients? Do you need to get them programmatically from somewhere or you can simply write a list that you will use for composing the email? If you provide clear info I can give you a complete solution.Illicit
ok so if you just use a variable for the recipient and the subject, I'll code the rest of the program for you.Illicit
I
11

I use the variables recipient and subject to store the relative values. Simply replace the example text between single quotes with your real value.

recipient = 'emailaddress'
subject = 'mysubject'

The subject field can't contain white spaces, so they have to be url encoded using %20 ASCII code

subject = subject.replace(' ', '%20')

the function above replaces the white space with "%20" and assigns the modified subject to the same variable since you can reuse it, you really don't need another one in this case.

It's possible to use also the urllib module for url encoding (see urllib.urlencode() method), but it can be done simply using the replace() method so you can avoid importing another module just for that.

Now you need to load the text from a text file and store it in a variable. Imagine you have a text file called body.txt:

with open('body.txt', 'r') as b:
    body = b.read()

Note that I assumed body.txt is in the same directory of your Python script, otherwise in the filename parameter you have to include the full absolute or relative path to the file, followed by the file name.

I used the open() function and I provide 2 parameters: the first one is the filename, the second one is the mode you want to open the file with. You want to read the file so you have to open it in read mode ('r'). Once you open the file you need to be able to identify the file with a variable in order to perform some operations on it. This kind of variable is technically called handle, in this case I called it b.

Now for reading ALL the text you can use b.read() and then you can assign it to the variable body. (If you wanted to read it line by line, you would have done: b.readline() but you don't want this in this case.)

Note that I used the with statement, this is the preferred way for opening and working with files, because it will automatically close the file at the end, else you would have to do it manually. Before with was available you would have to do something like this:

b = open('body.txt', 'r'):
body = b.read()
b.close()

Now it's better to url encode also the string contained in the variable body, so we do the same thing we did for the subject:

body = body.replace(' ', '%20')

Now it's time to use the webbrowser module and provide the data you got so far as parameter, concatenating the strings.

webbrowser.open('mailto:?to=' + recipient + '&subject=' + subject + '&body=' + body, new=1)

Obviously you also need to import the webbrowser module before using it. I'll rewrite the whole program without comments for clarity:

import webbrowser

recipient = 'emailaddress'
subject = 'mysubject'

with open('body.txt', 'r') as b:
    body = b.read()

body = body.replace(' ', '%20')

webbrowser.open('mailto:?to=' + recipient + '&subject=' + subject + '&body=' + body, new=1)
Illicit answered 1/9, 2016 at 11:2 Comment(5)
Great answer with excellent explanations, thank you very much for taking the time to write this down for me!Charente
prego @FabioMancin :)Illicit
any ideas on how to insert a .jpg either as an attachment or embedded in the body text?Irrawaddy
@Illicit any ideas on how to insert attachments?Oquendo
I’d strongly suggest to use the mentioned urllib.parse.urlencode(). If, e.g., the body contains ampersands, the suggested string replacement is not enough. I would even go so far and suggest to not implement your own encoding/decoding/quoting/unquoting in general if there is a good library available. It is too easy to overlook some edge case. Since it is part of the standard python library in this case, I would not hesitate to use it.Advertent
M
0

Use string concatenation.

recipient = '[email protected]'
subject = 'mysubject'
body = 'This is a message'
webbrowser.open("mailto:?to='+ recipient + '&subject=' + subject + "&body=" + body, new=1)
Marishamariska answered 1/9, 2016 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.