Python for Entrepreneurs Transcripts
Chapter: Sending and receiving email
Lecture: Demo: Sending rich templated email

Login or purchase this course to watch this video and the rest of the course contents.
0:03 Well, this technically worked, I probably should have done a little bit of this, maybe a few more "brs" here, to put some new lines, things like that,
0:12 but this worked, but this is not how you want to write your email, right,
0:17 it would be much better if you just had either actually the ability to edit the email,
0:21 maybe you write it as markdown and then transform it to HTML as you send it, or at least have a separate file so it's not in your Python code.
0:28 So that's what we are going to look at now, so let's come over here and I'll make a folder called email,
0:35 and what we are going to do is we are going to create some templates, so let me go ahead and make a folder named templates as well,
0:44 in here we are going to put the base HTML, because not only are we going to have stuff like this with all the HTML in it,
0:50 you will see that there is going to be styles galore to make this work in all of various email clients and look pretty and things like that,
0:57 so you definitely don't want it in here, so let's go and change this, we want to create a welcome.html file, and it's going to look like this,
1:07 now, not all of these pieces really mean anything, like this title doesn't really mean anything, as far as the email client goes,
1:13 because it's just going to use whatever the subject is. Let me copy the Talk Python Training welcome message
1:19 and we'll start with that and then we'll build it up. Alright, so here we have our title, we can go and set it to "Blue Yellow Rockets",
1:26 but I don't think it's going to show up in any client anywhere. Now notice here, we are setting all sorts of styles on the body,
1:34 now, you might be tempted to say "well Michael, why don't you do this and put a CSS style here or even better,
1:42 why don't you create a CSS style sheet and link to it?" I didn't do that, because it doesn't work.
1:47 Sometimes, under certain circumstances, some of it will work but style sheets are not a good idea for these email messages,
1:55 you need it to be totally self-contained and even then not every style you set will be respected by the various clients,
2:01 some of them just strip pieces out. But, basically you've got to set the styles right on here,
2:06 so I am setting things like line height 1.5, to make it more readable, I am getting rid of the padding, so I can set a background color,
2:14 make the fonts little bigger, things like that. Now notice at the top we have this image, if I come over here and pull up in a browser
2:23 you will see what it looks like, it's basically this image edited down just a little bit,
2:27 so here is this, so that right at the top, I am just leave this here,
2:30 I am not going to create a separate image for the email, but obviously, in your app, you will not create a Blue / Yellow Rockets picture,
2:38 instead you will create one for whatever your app is. So notice we are linking back to it, HTTPS is very important,
2:45 it's very likely that their client is HTTPS, so you are better off with that. We are setting a max-width, this margin-left, right, and a max-width
2:57 makes it float in the middle of the page, that's cool, so let's just change this around a little bit, congratulations,
3:03 and let's go and put in their email address, how do I know I can type {email}
3:10 because I just made that up and I'll show you how we replace that in just a minute, "congratulations {email}" you wouldn't really do this
3:16 but I just wanted to show you we have something to replace. "Thank you for registering with our site!"
3:25 And we got a little bit here, this div we can just drop this, we don't need that right now, and down here we have this "find your course right now",
3:32 how about we change this to "find your favorite album". OK, and notice we've got links back to wherever we want to go,
3:42 and the style is set straight on it, right, I wish we could do CSS but it doesn't seem to work reliably, so we are not doing it,
3:49 and here is a little bit, right, there is a little picture of me, with some links and stuff at the bottom,
3:54 "thanks for registering... and the band", something like that. Now, let's just go over here, say reveal this in finder,
4:01 alright this is what it looks like in its raw form it has, congratulations {email},
4:06 obviously this is going to be replaced dynamically, so how does that work, we have our favorite album, these all needs to be like a link to back,
4:14 the images and stuff, full URL back, whatever your real domain is, we don't have a domain yet for our Blue / Yellow Rockets,
4:22 so I can't really easily do that. Alright, so here is the template, now how do we load and expand this?
4:27 We basically want to take all this content in here, replace things like this,
4:33 and then use this as the HTML body that we are going to send in that basic send the message,
4:38 So let me add a function, let me add a file here, we'll call this template_parser,
4:46 so what we are going to do in this template parser, spelled correctly, is we are going to have all the templates loaded up and set, so over here,
4:54 let's have a welcome and initially it's going to be None, let's have a reset_password, it's None as well.
5:04 And then, let's add a function that we can call, so that at the start of our app we can pull this in and it will like load up what goes in there
5:14 and then we can use them throughout, OK, so let's do this, we don't need any arguments here but we are going to need to call this one time
5:21 and we are going to need to use the path module, so let's do this, we'll say "templates...", now what we need is we need to get this current folder
5:34 that contains the template folder and then we are going to add on templates, so that is easy enough, so os.path.dirname from this particular file,
5:44 so get just the directory that this file is contained in, that will be email, the full path to it, and then we are going to say "join... 'templates'".
5:53 Alright, so that is going to create folder and then what we want to do is just load up each one of these. Say "welcome".
6:02 So here we'll get the welcome file, and then we'll say like this, we'll say "welcome_file", we are going to open that,
6:08 "as fin", and then we want to set welcome on a class just the content, OK, so we'll do this and we would also do this
6:25 let's say we'll do one for password reset, there won't be any content for this one,
6:32 but just to show that we'll do this for each type of email we want to set, so welcome email, a reset, a purchase and so on,
6:41 you might have like five or ten of these. OK, so this we need to call somewhere, let's do that in our __init__.
6:55 So we are just going to import this, and we'll call global_init(), we just need to call it once, "templates",
7:06 you might as well group it down here with the other email stuff, like so,
7:13 so that should read our email templates, let's make sure that didn't break anything,
7:17 this is still running, it looks like we loaded them up correctly, great. So the next thing we need to do is they've got that raw template in them,
7:25 we want to actually expand them, so let's do this, so here we will write a function called expand_welcome and as you saw in our welcome email over here
7:41 we have this little curly such and such called email. OK, so we can come down here and actually, let me just show you more general way,
7:59 so we can do it like this, we can come down here and for a given template we could do something to this effect
8:05 so we are going to do something like pass EmailTemplateParser.welcome, EmailTemplateParser.reset_password and so on. And we'll say grab the final text,
8:17 we want to start out and say "for k in data", so data is going to be a dictionary, and then we want to replace the key that's going to be,
8:29 so here if we get a dictionary with a key called email, and a value for what the email should be, then we will be able to pass that in here,
8:38 so that should be perfect, and we won't do anything fancy we are just going to replace our key with the actual value that we got
8:47 and when we are done expanding all that we will return final text. So this way we can have as many templates as we want,
8:52 we don't have to keep rewriting this, or whatever, maybe you want to have like expand(welcome) and it just takes the email
8:59 and then it calls this internally, who knows, but this will let us expand that out.
9:03 So let's go to our email service, and we are going to change our send_welcome_email, now our body is not this anymore,
9:13 so HTML_body is going to be our EmailTemplateParser and what we are going to so is we are going to say "expand"
9:24 and what do we want to give it, not a huge fan of the way this looks but we want to give it welcome and we are going to give it a dictionary with email
9:32 and the value is going to be just whatever the email is. And that is all we are going to change, we want to go to that template parser,
9:39 we want to say grab that HTML that we stored in the file, that is easy to edit with smart tools that have IntelliSense,
9:46 and give that to a designer they can do whatever they want with it. We are going to load that up and we have already loaded it in memory
9:52 we are going to transform it to do the replacements with our little curly bracket syntax I made up and then we are just going to send it.
9:59 So let's register one more time. And let's just put a 3 right here. Alright, fingers crossed, again, there is a lot of moving parts what we just wrote,
10:08 let's see if it works. It looks like it works because it's already sending the mail, and it's talking a moment and now it is redirected and done
10:18 you might consider kicking this off to a background thread or some sort of like Celery queue or something like this,
10:24 it didn't make it asynchronous but for our purposes this is good enough. Let me check my email. Look at what we got here, how cool is that?
10:34 So remember we got this version that we had in memory before, and I said that is not good, let's do better, so now we got this better one, right,
10:43 here is our picture, congratulations, this is the email expansion that used to be {email} and we passed the value when we registered,
10:51 and it expanded it to this, right, so you can use this as URL fragments like "hey, you just bought the album, click here to go download it",
10:59 whatever you need to do you can pass in as many of those things in that dictionary as you need to, and of course, everything else is static HTML
11:07 and here is thanks for registering, Michael & the band and so on. So this is, by the way, I recommend you guys send emails,
11:14 you come up with these little email templates, and you just write them as pure HTML,
11:18 you put little placeholders where the values have to pop in and off it goes, you already have all the infrastructure you are going to need to do this
11:26 with this template parser, all you have to do to continue to add new email capabilities, is basically the add new templates,
11:34 so you obviously have to write the HTML of the email you are going to send,
11:38 and then in the email service, we had to know that this thing required an email and the template to expand it, so you are going to have to write
11:47 a send_password_reset and it is going to take like, you know, the reset password URL and things like that.
11:52 Alright, this Blue / Yellow Rockets web app is totally hooked up with outbound email,
11:56 with mailing list, the last thing we need to talk about with regard to email is how do we let people contact us, how do we put something like
12:03 "send me a message at michael@blueyellowrockets.com" or whatever it is, we'll talk about that in just a moment.


Talk Python's Mastodon Michael Kennedy's Mastodon