‫With the file upload part
‫of the section finished,
‫let's now turn our attention to sending emails.
‫And we actually already sent email before,
‫for the password reset, but in the next couple of lectures
‫we're gonna take that to a whole new level.
‫And what we're gonna do is to build email templates
‫with pug and sending real emails
‫using the SendGrid service.
‫And now in this first lecture,
‫we're gonna build a more robust email handler
‫than the one that we had before.
‫So, let's open up our utilities folder,
‫and then in here, remember, we already have an email file.
‫But right now what we have here
‫is just a very simple email sending handler,
‫which is not able to take in a lot of options.
‫And so now we're going to build
‫a much more robust solution here.
‫All right?
‫So what I'm gonna do is to create a class,
‫and that class is gonna be called email.
‫So module.exports,
‫and so also this class is what we're going
‫to be exporting from this file.
‫And then as always, a class needs a constructor function,
‫which is basically the function that is gonna be running
‫when a new object is created through this class.
‫Now let's actually take a look
‫at how we would use this class in practice.
‫And so the idea, basically,
‫whenever we want to send a new email,
‫is to import this email class and then use it like this.
‫So creating a new email,
‫and then into it, we want to paste a user,
‫and so that user will then contain the email address,
‫and also the name in case we want to personalize the email.
‫And also a URL.
‫And a good example for this one
‫is for example, the reset URL for resetting the password.
‫Okay?
‫So, a new email object, and then on there
‫we want to call the method that is actually going
‫to send the email.
‫So, let's say sendWelcome.
‫And so that one is gonna be sent
‫whenever a new user signs up for our application.
‫All right?
‫We will then also have send password reset.
‫And the way we will set all this up
‫will make it really easy to then keep adding
‫new and new methods similar to this one
‫to send different emails for different scenarios.
‫All right?
‫Anyway, since we paste the user and the URL
‫into a new email, well, our constructor then needs
‫to take these in as arguments.
‫So user and URL.
‫And so what happens in this constructor is that this.to
‫will be equal to the user.email
‫Then we also want to define the first name of the user,
‫again in order to basically personalize the email.
‫And so that's user.name and let's split it
‫and take only the first element in the resulting array.
‫So we did this one before,
‫but then also this.url is equal to the incoming URL.
‫Finally, let's also set this.from right here.
‫so basically at the object level.
‫And so each object created from this class
‫will then get this property.
‫And so this one will be similar to what we have here.
‫So it's basically this from,
‫so let's just copy it
‫but it's nice to have it in a one central place like this.
‫Now one thing that I really want to do,
‫is to basically define this email address here
‫as a configuration variable,
‫and so an environment variable
‫that we can very easily change
‫by manipulating the config.env file.
‫All right?
‫So let's call this one EMAIL_FROM.
‫And then we only want the email address itself.
‫All right?
‫So another case where it's very helpful
‫to use environment variables.
‫And now let's make this a template string.
‫And of course plug that in here.
‫So that's process.env.EMAIL_FROM.
‫Next up, let's create a method here
‫in order to create the transport.
‫So similar to what we have here.
‫So createTransport.
‫And now here we actually want to have different transports
‫whether we are in production or not.
‫So when we're in production,
‫we actually want to send real emails,
‫and we will do that a bit later using SendGrid,
‫but if we are not in production
‫then we still want to use our Mailtrap application
‫just like we did it before when we send emails.
‫So instead of the email going to a real email address,
‫it will get caught into our Mailtrap inbox so that
‫we can actually take a look at it
‫in our development process.
‫So that transporter will be exactly the same as this one,
‫so let's just copy it but first let's say
‫if(process.env.NODE_ENV).
‫So, remember, that's how we checked
‫whether we're in production or not.
‫And so if that is in production,
‫and so if we're in production,
‫then we want to create a transporter for SendGrid.
‫So let's just put that here,
‫and again we will do that later.
‫For now let's just return something from here.
‫Doesn't matter, lets say one.
‫All right?
‫And then basically otherwise
‫we want to return this nodemailer.createTransport.
‫Okay?
‫So this Transport here
‫will basically return a new nodemailer transport like this.
‫Or, on the other hand when we're in production,
‫then the one that's going to be here.
‫Okay?
‫So let's actually delete it from here.
‫Also, we want to delete this one.
‫And now let's create the send method.
‫And so this is gonna be the method
‫that will do the actual sending.
‫Okay?
‫And this one will receive a template and a subject.
‫And you will understand a bit better
‫why that is once this entire class is complete.
‫Okay?
‫So template and subject.
‫So let's put a comment here of what this will do.
‫And now before we actually write out this function,
‫let me show you how we're gonna use it,
‫and so why we need the template and the subject here.
‫So, remember how we said up here
‫that we're gonna have one method called sendWelcome,
‫and also like a method for sending a reset password email.
‫And so, let's now actually add that here, so sendWelcome.
‫And this one doesn't receive any argument
‫and all it really does is to call send
‫with the template and the subject
‫that we want for this email.
‫Okay?
‫And so again, this makes it really easy
‫to then create different emails
‫for all kinds of different situations.
‫Okay?
‫So we have this one route send function here
‫and then all of these more specific ones,
‫which will then in turn call the router send function
‫which is doing the actual work.
‫Okay?
‫And actually here it is this.send
‫because of course these methods here,
‫they are going to be defined on the current object.
‫And so that's this.
‫Then here we paste in the template name.
‫And so this template name that I put here,
‫will in the future be a pug template
‫that we're gonna create.
‫So, actually in the next lecture,
‫we're gonna be creating this pug template
‫in order to send this welcome email.
‫Okay?
‫And then just the subject line.
‫Let's say 'Welcome to the Natours Family!'
‫And so, just like this, we do not need to worry
‫about any of the implementation details
‫when we're actually sending the email.
‫So for example in the point of our code
‫where we want to send the welcome email
‫we do not have to worry about template names
‫or about the subject lines.
‫All we're gonna do is to say send welcome email
‫and that's it.
‫And then our class will take care
‫of dealing with the implementation.
‫All right?
‫Anyway, let's now actually then build this send function.
‫And so, what we're gonna do in this function,
‫is to first render the HTML for the email
‫based on a pug template.
‫So basically the one that we're pasting
‫into here with template.
‫Then, define the email options,
‫and so that's once more gonna be very similar to this one,
‫and in fact let me go ahead
‫and cut it from here and paste it here.
‫Okay?
‫Of course it's not going to be exactly the same,
‫but we will leave that for a bit later.
‫All right?
‫And then finally,
‫Create a transport and send email.
‫Okay?
‫And so that's, I'll leave that one for later as well.
‫So, starting with point number one.
‫And usually up until this point, we only ever use pug
‫to create a template,
‫and then we pass the name of the template
‫into the render function on the response.
‫Right.
‫So we always just used it like this
‫res.render,
‫and then here the name of the template.
‫Right?
‫And what this render function does behind the scenes
‫is to basically create the HTML based on the pug template
‫and then send it to the client.
‫Now in this case we do not really want to render,
‫all we want to do is to basically create the HTML
‫out of the template so that we can then send that HTML
‫as the email.
‫So basically defining it here as an HTML option
‫into these mail options.
‫Okay?
‫So, remember how we can specify text and HTML.
‫And mainly we are interested in sending an HTML email.
‫And so that's why we're gonna have a pug template
‫from which we will generate this HTML.
‫Okay?
‫So it's not gonna be working like this,
‫but instead we actually need to require
‫the pug package here.
‫So,
‫pug like this,
‫and then we need to use
‫pug.renderFile.
‫Okay?
‫And so this will take in the file
‫and then render the pug code into real HTML.
‫Okay?
‫And so that we can then save into a variable HTML.
‫All right?
‫So, where is that file?
‫Well, it is at dirname,
‫so D-I-R name,
‫which remember is the location
‫of the currently running script,
‫and so that is, right now, at this utilities folder.
‫Okay?
‫And so from there we need to move one step up,
‫then go into views, and from there go into an emails folder
‫that we're gonna also create in a second.
‫And then in there
‫is where we're gonna have the template file.
‫So
‫template}.pug.
‫So for the welcome email, this template
‫is gonna be called welcome.
‫And so let's now actually create that here in the views,
‫create a new folder,
‫email, and then in there new file,
‫welcome.pug.
‫Okay?
‫And we're not going to really be creating
‫this template in this video but I just wanted to show you
‫how all of this is gonna work.
‫Okay?
‫So this welcome will be paste here into template
‫and then it will grab that file from the views folder.
‫Right?
‫So, that is the first step.
‫Next up, let's define the email options.
‫So, from is now this.from.
‫Remember?
‫So right here.
‫Next up, we have
‫this.to, and we also have the subject
‫which is equal to the subject that's coming in right here,
‫and so, yah, actually we don't even need to define this one
‫and we have our HTML.
‫So like this, or of course,
‫that is not even necessary because it's the same name.
‫Now, next up, we also want to include a text version of
‫our email into the email.
‫Okay?
‫And that's actually really important because it's better
‫for email delivery rates and also for spam folders.
‫All right?
‫And also some people just prefer plain simple text emails
‫instead of having the more formatted HTML emails.
‫All right?
‫And so basically, we need a way of converting
‫all the HTML to simple text.
‫So stripping out all of the HTML leaving only the content.
‫And for doing that, we are going to install
‫yet another package,
‫and so this one is called html-to-text.
‫All right?
‫Let's include that here,
‫ToText.
‫require('html-to-text'), like this.
‫Okay?
‫Now let's use that to convert our HTML.
‫So we use htmlToText.fromString
‫and then that string is stored in HTML.
‫Right?
‫So, these are our mail options,
‫And actually I forgot something very, very important,
‫here in this first step, so in this render file,
‫because just like with response.render,
‫we can also paste data into render file.
‫And of course, that is very important
‫if we want to actually do or email personalization
‫with the name and also paste in the URL.
‫And so let's do it just like we did normally
‫in the render function.
‫So that's firstName, send it to this.firstName,
‫and the URL is this.url,
‫and also let's paste in the subject
‫and you will see a bit later why we need that.
‫Okay?
‫So, now let's finally create a transport
‫using our create transport function,
‫and then send the email.
‫So, fair enough, that's this.createTransport.
‫So, remember that this is just this method here, this one,
‫and it has the exact same name
‫as this function here coming from nodemailer.
‫So that's a bit confusing,
‫so let's call it newTransport here.
‫Okay, and so here that's also newTransport,
‫so that it's a bit less confusing.
‫All right?
‫Now let's remember how we did it here before.
‫So we had our transporter,
‫which we created separately in this case,
‫and then onto that we chained sendMail with the options.
‫So let's just grab that here, delete all the remaining code.
‫So basically put that here as a reference.
‫Okay?
‫So this transporter is now this.
‫All right?
‫And so then on to that, we chain send email
‫and then with the mail options that we defined up here.
‫Then, we need to await all of this,
‫because, of course, it's an asynchronous function.
‫And so let's now mark this one here as async.
‫Okay?
‫And so now, we also need to await the function here.
‫All right?
‫Because this.send is now indeed an async function.
‫And so here we await that so that this function only returns
‫as soon as the email has actually been sent.
‫And so, of course, mark this one as async as well.
‫Awesome.
‫That's actually it for this class.
‫So we no longer need this example.
‫Okay?
‫And so in the next video, we will then actually go ahead
‫and use this new class in order to send a welcome email.
‫So, just very quickly recap what we did here.
‫So we created a new email class
‫from which we can create email objects
‫that we can then use to send actual emails.
‫And to create a new email object, we will paste in the user
‫and also a URL that we want to be in that email.
‫So then here we assign all that stuff to the current object,
‫and also some other settings that we want to have available,
‫such as the first name and the sender email.
‫So basically to abstract this information
‫away from the send function,
‫and to have it all in one central place.
‫Then we have here a new transport function
‫which makes it really easy to create different transports
‫for different environments.
‫And so once more, abstracting that logic
‫away from the actual send function
‫which should only be concerned about sending the email.
‫Okay?
‫So then here is that send function which takes in a template
‫and a subject, and based on that it creates the HTML
‫from a pug template which will then be set
‫into the email options, which will,
‫at the end of the function, then finally be sent
‫in this line of code.
‫Okay?
‫But it's not going to be this send function
‫that we will use in our code.
‫So instead, we're going to be creating
‫one different function for each type of email
‫that we want to send.
‫And the first one that I created here is the sendWelcome.
‫All right?
‫And so for sendWelcome, we basically then preset
‫the template name as welcome,
‫and the subject as this string.
‫Okay?
‫So, I hope that made sense, and I see you in a second.