title
Nodemailer - Send Emails From Your Node.js App

description
In this video we will create a simple Node.js and Express app and implement the Nodemailer module to add a contact form. CODE: Complete Node app repo https://github.com/bradtraversy/nodecontactform ORIGINAL HTML/CSS FORM DOWNLOAD: http://www.traversymedia.com/downloads/responsiveform.zip INMOTION HOSTING SIGNUP: https://inmotion-hosting.evyy.net/c/396530/260033/4222 BECOME A PATRON: Show support & get perks! http://www.patreon.com/traversymedia ONE TIME DONATIONS: http://www.paypal.me/traversymedia COURSES & MORE INFO: http://www.traversymedia.com FOLLOW TRAVERSY MEDIA: http://www.facebook.com/traversymedia http://www.twitter.com/traversymedia http://www.instagram.com/traversymedia

detail
{'title': 'Nodemailer - Send Emails From Your Node.js App', 'heatmap': [{'end': 862.695, 'start': 818.354, 'weight': 0.764}, {'end': 1383.954, 'start': 1326.564, 'weight': 1}, {'end': 1417.509, 'start': 1399.295, 'weight': 0.712}, {'end': 1493.065, 'start': 1471.317, 'weight': 0.807}], 'summary': 'Learn to create a node.js and express application with nodemailer to implement a mailing module for form submission, set up email configuration, warning against using gmail smtp for production, create a responsive form, implement a post route for form submission, and send emails in node.js without spam markings.', 'chapters': [{'end': 92.051, 'segs': [{'end': 51.237, 'src': 'embed', 'start': 7.495, 'weight': 0, 'content': [{'end': 8.836, 'text': "hey, what's going on, guys?", 'start': 7.495, 'duration': 1.341}, {'end': 14.82, 'text': 'so a couple weeks ago i created a video on creating a responsive contact form using.', 'start': 8.836, 'duration': 5.984}, {'end': 19.544, 'text': 'we used a little bit of grid css and it was just the front end, it was just the ui,', 'start': 14.82, 'duration': 4.724}, {'end': 24.728, 'text': 'and i had a bunch of requests asking to actually hook up a backend so that the form would actually work.', 'start': 19.544, 'duration': 5.184}, {'end': 27.229, 'text': 'So we went with Firebase.', 'start': 25.348, 'duration': 1.881}, {'end': 28.829, 'text': 'That seemed to be the consensus.', 'start': 27.289, 'duration': 1.54}, {'end': 38.333, 'text': "We said that we created another video where we took the form and made it so that we could submit and the fields would go to a database in Google's Firebase.", 'start': 29.53, 'duration': 8.803}, {'end': 47.196, 'text': 'So what I want to do now is I want to take that same form and I want to create a simple Node.js and Express application and implement NodeMailer,', 'start': 38.893, 'duration': 8.303}, {'end': 49.697, 'text': 'which is a mailing module for Node.js.', 'start': 47.196, 'duration': 2.501}, {'end': 51.237, 'text': "and we're going to use that.", 'start': 50.357, 'duration': 0.88}], 'summary': 'Created responsive contact form using grid css. added backend with firebase. now integrating node.js and nodemailer.', 'duration': 43.742, 'max_score': 7.495, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk7495.jpg'}, {'end': 99.018, 'src': 'embed', 'start': 70.334, 'weight': 3, 'content': [{'end': 75.195, 'text': 'consider becoming a patron to push me to keep bringing you high quality educational videos.', 'start': 70.334, 'duration': 4.861}, {'end': 78.296, 'text': 'Showing your support with even $1 means the world.', 'start': 75.615, 'duration': 2.681}, {'end': 84.898, 'text': "We have different perks and tiers, including a $2 tier that'll give you every Udemy course that I release absolutely free.", 'start': 78.356, 'duration': 6.542}, {'end': 88.699, 'text': 'To learn more, check out patreon.com slash Traverse Media.', 'start': 85.218, 'duration': 3.481}, {'end': 92.051, 'text': "Alright guys, so we're going to get started here.", 'start': 90.049, 'duration': 2.002}, {'end': 99.018, 'text': "This is the NodeMailer website and if we go down here you'll see that there's actually a snippet basically showing us what we need to do.", 'start': 92.071, 'duration': 6.947}], 'summary': 'Traverse media offers educational videos on patreon, with perks including free udemy courses for $2 patrons.', 'duration': 28.684, 'max_score': 70.334, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk70334.jpg'}], 'start': 7.495, 'title': 'Creating a node.js and express application with nodemailer', 'summary': 'Involves creating a node.js and express application with nodemailer to implement a mailing module for form submission to a specific email address, leveraging firebase as the backend.', 'chapters': [{'end': 92.051, 'start': 7.495, 'title': 'Creating node.js and express application with nodemailer', 'summary': 'Involves creating a node.js and express application with nodemailer to implement a mailing module, enabling form submission to a specific email address, leveraging firebase as the backend.', 'duration': 84.556, 'highlights': ['The chapter involves creating a Node.js and Express application with NodeMailer to implement a mailing module.', 'The application will allow form submission to a specific email address, leveraging Firebase as the backend.', 'The video aims to fulfill requests to hook up a backend for the previously created responsive contact form using Firebase as the consensus choice.', 'Viewers are encouraged to consider becoming a patron to support the creation of high-quality educational content.']}], 'duration': 84.556, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk7495.jpg', 'highlights': ['The application will allow form submission to a specific email address, leveraging Firebase as the backend.', 'The chapter involves creating a Node.js and Express application with NodeMailer to implement a mailing module.', 'The video aims to fulfill requests to hook up a backend for the previously created responsive contact form using Firebase as the consensus choice.', 'Viewers are encouraged to consider becoming a patron to support the creation of high-quality educational content.']}, {'end': 670.791, 'segs': [{'end': 138.552, 'src': 'embed', 'start': 92.071, 'weight': 1, 'content': [{'end': 99.018, 'text': "This is the NodeMailer website and if we go down here you'll see that there's actually a snippet basically showing us what we need to do.", 'start': 92.071, 'duration': 6.947}, {'end': 101.44, 'text': 'We need to bring in NodeMailer once we install it.', 'start': 99.078, 'duration': 2.362}, {'end': 111.35, 'text': 'We need to call this create transport function, pass in a configuration object with our email SMTP information.', 'start': 101.881, 'duration': 9.469}, {'end': 118.255, 'text': 'Now, as far as SMTP, you can use Gmail if you want, but you may have some issues.', 'start': 111.99, 'duration': 6.265}, {'end': 124.2, 'text': "In fact, if we go to usage and then using Gmail, it'll tell you that it's by no means a preferable solution,", 'start': 118.315, 'duration': 5.885}, {'end': 126.602, 'text': "unless you're using OAuth 2 authentication.", 'start': 124.2, 'duration': 2.402}, {'end': 130.384, 'text': 'Gmail has a concept of less secure apps,', 'start': 127.562, 'duration': 2.822}, {'end': 138.552, 'text': "and that's what your application will be considered if you just straight up use the Gmail SMTP without this OAuth authentication.", 'start': 130.384, 'duration': 8.168}], 'summary': 'Nodemailer website provides code snippet for smtp setup, gmail usage discouraged without oauth 2 authentication.', 'duration': 46.481, 'max_score': 92.071, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk92071.jpg'}, {'end': 192.341, 'src': 'embed', 'start': 164.875, 'weight': 0, 'content': [{'end': 168.679, 'text': 'All right, so I use InMotion hosting for my services.', 'start': 164.875, 'duration': 3.804}, {'end': 176.606, 'text': "I'm actually going to be doing a web hosting series on YouTube showing you how to upload your website, how to create the account,", 'start': 168.699, 'duration': 7.907}, {'end': 178.729, 'text': 'how to create email accounts all that stuff.', 'start': 176.606, 'duration': 2.123}, {'end': 181.852, 'text': "And we're going to be using InMotion for that as well.", 'start': 179.369, 'duration': 2.483}, {'end': 183.853, 'text': "But you'll see that down here.", 'start': 182.712, 'duration': 1.141}, {'end': 187.897, 'text': 'I have an email called test at Traverse you media comm.', 'start': 183.873, 'duration': 4.024}, {'end': 192.341, 'text': "so I'm going to use that as my email account to send from,", 'start': 187.897, 'duration': 4.444}], 'summary': 'Using inmotion hosting for web hosting series on youtube, demonstrating website upload, account creation, and email setup.', 'duration': 27.466, 'max_score': 164.875, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk164875.jpg'}, {'end': 346.84, 'src': 'embed', 'start': 311.521, 'weight': 3, 'content': [{'end': 313.782, 'text': "so we're going to be using express.", 'start': 311.521, 'duration': 2.261}, {'end': 317.364, 'text': "since we're using a form that's going to be submitted as a post request.", 'start': 313.782, 'duration': 3.582}, {'end': 322.247, 'text': 'we need to install body parser so that we can get the information from the form.', 'start': 317.364, 'duration': 4.883}, {'end': 323.988, 'text': 'we also need a template engine.', 'start': 322.247, 'duration': 1.741}, {'end': 327.95, 'text': "so we're going to use express handlebars and then, of course, we need node mailers.", 'start': 323.988, 'duration': 3.962}, {'end': 346.84, 'text': "so let's say npm, install dash dash, save express body dash parser, express dash handlebars and node mailer alright.", 'start': 327.95, 'duration': 18.89}], 'summary': 'Using express with form submission, installing body parser, express handlebars, and node mailers', 'duration': 35.319, 'max_score': 311.521, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk311521.jpg'}, {'end': 396.389, 'src': 'embed', 'start': 364.695, 'weight': 4, 'content': [{'end': 369.077, 'text': "well, I already have installed, but I'm going to show you how to install something called nodemon,", 'start': 364.695, 'duration': 4.382}, {'end': 374.92, 'text': "which will continuously watch your application so you don't have to keep restarting the server every time you make a change.", 'start': 369.077, 'duration': 5.843}, {'end': 384.585, 'text': 'So you probably want to install that globally, and you can do that with npm install-g for global and then nodemon.', 'start': 375.32, 'duration': 9.265}, {'end': 387.146, 'text': 'All right, so just go ahead and run that.', 'start': 385.585, 'duration': 1.561}, {'end': 396.389, 'text': 'All right, so in our app.js file, first thing we need to do is just bring in all of our stuff, all of our dependencies.', 'start': 388.74, 'duration': 7.649}], 'summary': 'Demonstrate installing nodemon to avoid server restarts for code changes.', 'duration': 31.694, 'max_score': 364.695, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk364695.jpg'}], 'start': 92.071, 'title': 'Using nodemailer for email configuration and setting up node application with express and node mailer', 'summary': 'Covers the setup of nodemailer for email configuration, using smtp servers like gmail and inmotion hosting, and provides a warning against using gmail smtp for production applications, along with setting up a node application using express, installing dependencies, initializing the app with routes and middleware, and starting the server on port 3000.', 'chapters': [{'end': 213.845, 'start': 92.071, 'title': 'Using nodemailer for email configuration', 'summary': 'Covers the setup of nodemailer for email configuration, including the usage of smtp servers such as gmail and inmotion hosting, with a warning against using gmail smtp for production applications due to security concerns.', 'duration': 121.774, 'highlights': ['NodeMailer requires the create transport function, along with an SMTP configuration object, for email setup. The chapter emphasizes the necessity of using the create transport function and an SMTP configuration object for email setup.', 'Using Gmail SMTP without OAuth 2 authentication is not recommended for production applications due to security concerns. The transcript highlights the security concerns of using Gmail SMTP without OAuth 2 authentication for production applications.', 'InMotion Hosting is recommended for email setup, with specific parameters such as the SMTP port and server name provided. InMotion Hosting is recommended for email setup, with specific parameters like SMTP port and server name provided for configuration.']}, {'end': 670.791, 'start': 213.926, 'title': 'Setting up node application with express and node mailer', 'summary': 'Covers setting up a node application using express, including installing dependencies like body parser and express handlebars, and initializing the app with routes and middleware, with a server started on port 3000.', 'duration': 456.865, 'highlights': ['Setting up Node Application with Express and Node Mailer The chapter covers setting up a Node application using Express, including installing dependencies like body parser and express handlebars, and initializing the app with routes and middleware, with a server started on port 3000.', 'Installing nodemon for continuous application watching The tutorial explains installing nodemon globally to continuously watch the application and avoid restarting the server with every change.', 'Initializing app with routes and middleware The transcript explains initializing the app with routes and middleware, setting up the view engine with handlebars, and adding body parser middleware for form submissions.', 'Installing necessary dependencies for the application It includes installing necessary dependencies like express, body parser, express handlebars, and node mailer for the Node application.']}], 'duration': 578.72, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk92071.jpg', 'highlights': ['InMotion Hosting is recommended for email setup, with specific parameters like SMTP port and server name provided for configuration.', 'NodeMailer requires the create transport function, along with an SMTP configuration object, for email setup.', 'Using Gmail SMTP without OAuth 2 authentication is not recommended for production applications due to security concerns.', 'Setting up Node Application with Express and Node Mailer including installing dependencies like body parser and express handlebars, and initializing the app with routes and middleware, with a server started on port 3000.', 'Installing nodemon globally to continuously watch the application and avoid restarting the server with every change.']}, {'end': 1088.427, 'segs': [{'end': 791.356, 'src': 'embed', 'start': 670.851, 'weight': 0, 'content': [{'end': 672.772, 'text': "I think that's it, actually, for middleware.", 'start': 670.851, 'duration': 1.921}, {'end': 674.672, 'text': 'Oh, we need to set up our public folder.', 'start': 672.812, 'duration': 1.86}, {'end': 687.135, 'text': "So with Node.js and Express, if you want a public folder, which is actually where we're going to put our CSS file, we need to set that up.", 'start': 674.812, 'duration': 12.323}, {'end': 688.995, 'text': "So let's create a folder called public.", 'start': 687.175, 'duration': 1.82}, {'end': 699.741, 'text': 'Okay, so any assets you have, any images or CSS files, any client-side JavaScript, things like that will go in public.', 'start': 692.076, 'duration': 7.665}, {'end': 706.245, 'text': "All right, we'll actually have a folder in here called CSS, and that's where our form CSS will go.", 'start': 700.321, 'duration': 5.924}, {'end': 710.608, 'text': "But we need to let Express know that that's the folder we wanna use.", 'start': 706.885, 'duration': 3.723}, {'end': 715.391, 'text': "So we'll say public, or we'll say static.", 'start': 711.248, 'duration': 4.143}, {'end': 718.762, 'text': "It's actually called a static folder.", 'start': 717.059, 'duration': 1.703}, {'end': 722.189, 'text': 'So for that, we need to say app.use.', 'start': 719.544, 'duration': 2.645}, {'end': 736.341, 'text': "And we're going to say slash public Okay, and then we need to say express.static.", 'start': 724.413, 'duration': 11.928}, {'end': 741.743, 'text': 'All right, now we actually need to bring in one more module, which is a core module.', 'start': 737.161, 'duration': 4.582}, {'end': 743.323, 'text': "That's why we didn't have to install it.", 'start': 741.783, 'duration': 1.54}, {'end': 745.084, 'text': "And that's the path module.", 'start': 743.664, 'duration': 1.42}, {'end': 747.985, 'text': "And that's just to deal with file paths.", 'start': 745.624, 'duration': 2.361}, {'end': 755.143, 'text': "So we're gonna say require path, all right,", 'start': 748.805, 'duration': 6.338}, {'end': 766.428, 'text': "and then let's go back into the Express dot static method and we're just gonna pass in path dot join and we're gonna say two parameters here.", 'start': 755.143, 'duration': 11.285}, {'end': 773.431, 'text': "one's gonna be double underscore, dur name, which just basically represents the current directory, and then public.", 'start': 766.428, 'duration': 7.003}, {'end': 782.235, 'text': "okay, so we're just defining our static folder as this public folder, so it knows where where to look and what to treat as as the static folder.", 'start': 773.431, 'duration': 8.804}, {'end': 784.993, 'text': "All right, so let's go ahead and save that.", 'start': 782.932, 'duration': 2.061}, {'end': 791.356, 'text': "Now I'm going to stop this server with Control-C and I'm going to restart it with NodeMon,", 'start': 785.553, 'duration': 5.803}], 'summary': 'Setting up a public folder for css and assets using node.js and express.', 'duration': 120.505, 'max_score': 670.851, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk670851.jpg'}, {'end': 846.539, 'src': 'embed', 'start': 818.354, 'weight': 5, 'content': [{'end': 826.382, 'text': "and inside views we're going to have one view and I'm going to call it contact dot.", 'start': 818.354, 'duration': 8.028}, {'end': 831.526, 'text': "It's going to have a handlebars extension by default.", 'start': 827.803, 'duration': 3.723}, {'end': 833.308, 'text': 'And this is where we put our form.', 'start': 831.967, 'duration': 1.341}, {'end': 837.772, 'text': "Now, just to test it out first, let's just say contact and save.", 'start': 833.348, 'duration': 4.424}, {'end': 840.114, 'text': "And then we'll go back to our app.js.", 'start': 838.252, 'duration': 1.862}, {'end': 846.539, 'text': "And for our home route, instead of just res.send hello, we're going to say res.render.", 'start': 840.915, 'duration': 5.624}], 'summary': "Creating a view named 'contact' with handlebars extension to replace 'hello' with 'res.render' in the home route.", 'duration': 28.185, 'max_score': 818.354, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk818354.jpg'}, {'end': 862.695, 'src': 'heatmap', 'start': 818.354, 'weight': 0.764, 'content': [{'end': 826.382, 'text': "and inside views we're going to have one view and I'm going to call it contact dot.", 'start': 818.354, 'duration': 8.028}, {'end': 831.526, 'text': "It's going to have a handlebars extension by default.", 'start': 827.803, 'duration': 3.723}, {'end': 833.308, 'text': 'And this is where we put our form.', 'start': 831.967, 'duration': 1.341}, {'end': 837.772, 'text': "Now, just to test it out first, let's just say contact and save.", 'start': 833.348, 'duration': 4.424}, {'end': 840.114, 'text': "And then we'll go back to our app.js.", 'start': 838.252, 'duration': 1.862}, {'end': 846.539, 'text': "And for our home route, instead of just res.send hello, we're going to say res.render.", 'start': 840.915, 'duration': 5.624}, {'end': 851.183, 'text': 'And we want to render the contact form or the contact view.', 'start': 847.24, 'duration': 3.943}, {'end': 854.987, 'text': 'And save, reload, and we get contact.', 'start': 851.884, 'duration': 3.103}, {'end': 857.186, 'text': 'Alright, so now we need our form.', 'start': 855.583, 'duration': 1.603}, {'end': 862.695, 'text': 'Now, the link is in the description for the zip file, which will include the index page.', 'start': 857.266, 'duration': 5.429}], 'summary': 'Creating a contact form view with handlebars extension and rendering it in the app.js home route.', 'duration': 44.341, 'max_score': 818.354, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk818354.jpg'}, {'end': 944.761, 'src': 'embed', 'start': 911.744, 'weight': 6, 'content': [{'end': 913.586, 'text': 'Where the hell is it? Oh, there it is.', 'start': 911.744, 'duration': 1.842}, {'end': 914.688, 'text': 'All right.', 'start': 914.327, 'duration': 0.361}, {'end': 917.672, 'text': "So let's open that up and.", 'start': 914.788, 'duration': 2.884}, {'end': 927.712, 'text': "Let's open up our project folder as well, which is in let's see projects node contact form.", 'start': 920.788, 'duration': 6.924}, {'end': 936.297, 'text': "So those files that you just downloaded, we're going to put the style CSS into public and then CSS.", 'start': 928.292, 'duration': 8.005}, {'end': 937.918, 'text': 'Okay, just bring that over.', 'start': 936.557, 'duration': 1.361}, {'end': 943.02, 'text': "And then the index HTML, I'm just going to open that.", 'start': 938.638, 'duration': 4.382}, {'end': 944.761, 'text': "Let's see, I'll open it with sublime.", 'start': 943.181, 'duration': 1.58}], 'summary': 'Opening and organizing project files for contact form implementation.', 'duration': 33.017, 'max_score': 911.744, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk911744.jpg'}, {'end': 1026.515, 'src': 'embed', 'start': 999.078, 'weight': 7, 'content': [{'end': 1001.94, 'text': 'Now there is a couple things we need to do.', 'start': 999.078, 'duration': 2.862}, {'end': 1003.641, 'text': 'Let me just make this smaller.', 'start': 1001.96, 'duration': 1.681}, {'end': 1008.785, 'text': "There's a couple things we need to do for this form to actually work with Node.js.", 'start': 1004.102, 'duration': 4.683}, {'end': 1014.049, 'text': 'So one thing we need to do is go to the form tag and we need to add in an action and a method.', 'start': 1008.865, 'duration': 5.184}, {'end': 1017.671, 'text': 'Okay, so the method is going to be post.', 'start': 1014.649, 'duration': 3.022}, {'end': 1026.515, 'text': "It's going to be a post request, and then the action is going to be a route that we're going to create, which is going to be slash send.", 'start': 1017.731, 'duration': 8.784}], 'summary': 'Need to add action and method to form for node.js to work, post request with route /send', 'duration': 27.437, 'max_score': 999.078, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk999078.jpg'}, {'end': 1094.269, 'src': 'embed', 'start': 1066.271, 'weight': 8, 'content': [{'end': 1070.094, 'text': 'By the way, that animation that you see is coming from animate CSS.', 'start': 1066.271, 'duration': 3.823}, {'end': 1077.6, 'text': 'We just brought it in with a CDN and we added this animated class and this bounce in left.', 'start': 1070.615, 'duration': 6.985}, {'end': 1080.763, 'text': "That's what that is in case you didn't watch the initial video.", 'start': 1077.64, 'duration': 3.123}, {'end': 1083.164, 'text': 'and, like i said, you can use your own form.', 'start': 1081.343, 'duration': 1.821}, {'end': 1088.427, 'text': "you don't have to use this one that we created, but you know whatever.", 'start': 1083.164, 'duration': 5.263}, {'end': 1094.269, 'text': "so let's now go into our app.js and let's create a post route for the submission.", 'start': 1088.427, 'duration': 5.842}], 'summary': 'Using animate css, added animation with bounce in left class. creating a post route for submission in app.js.', 'duration': 27.998, 'max_score': 1066.271, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1066271.jpg'}], 'start': 670.851, 'title': 'Setting up public folder in node.js and creating a responsive form', 'summary': 'Explains setting up a public folder in node.js and express for storing assets and demonstrates creating a responsive form with node.js, including static folder definition, view rendering, css integration, and form configuration.', 'chapters': [{'end': 766.428, 'start': 670.851, 'title': 'Setting up public folder in node.js and express', 'summary': 'Explains the process of setting up a public folder in node.js and express to store assets like css files, images, and client-side javascript, and also demonstrates the use of the path module for dealing with file paths.', 'duration': 95.577, 'highlights': ["The process of setting up a public folder in Node.js and Express involves creating a folder called 'public' to store assets like CSS files, images, and client-side JavaScript.", "Express needs to be informed about the folder to be used for static files, which is achieved by using the 'app.use' method and the 'express.static' function.", "The path module is brought in to deal with file paths, and the 'path.join' function is used within the 'express.static' method to specify the folder for static files."]}, {'end': 1088.427, 'start': 766.428, 'title': 'Creating a responsive form with node.js', 'summary': 'Demonstrates the process of creating a responsive form with node.js, including defining static folders, rendering views, integrating css, and configuring form actions and methods.', 'duration': 321.999, 'highlights': ['The chapter demonstrates the process of creating a responsive form with Node.js, including defining static folders, rendering views, integrating CSS, and configuring form actions and methods.', 'The server is restarted using NodeMon for constant monitoring and updates.', "A view for the form is created in a folder named 'views' with the file name 'contact.handlebars'.", "The style.css file is placed in the 'public/css' directory, and the index.html content is pasted into 'contact.handlebars'.", 'The form is made responsive and additional attributes like action, method, and a submit button are added to make it functional for Node.js.', 'The use of animate CSS for animations is mentioned as an optional feature for the form.']}], 'duration': 417.576, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk670851.jpg', 'highlights': ["The process of setting up a public folder in Node.js and Express involves creating a folder called 'public' to store assets like CSS files, images, and client-side JavaScript.", "Express needs to be informed about the folder to be used for static files, which is achieved by using the 'app.use' method and the 'express.static' function.", "The path module is brought in to deal with file paths, and the 'path.join' function is used within the 'express.static' method to specify the folder for static files.", 'The chapter demonstrates the process of creating a responsive form with Node.js, including defining static folders, rendering views, integrating CSS, and configuring form actions and methods.', 'The server is restarted using NodeMon for constant monitoring and updates.', "A view for the form is created in a folder named 'views' with the file name 'contact.handlebars'.", "The style.css file is placed in the 'public/css' directory, and the index.html content is pasted into 'contact.handlebars'.", 'The form is made responsive and additional attributes like action, method, and a submit button are added to make it functional for Node.js.', 'The use of animate CSS for animations is mentioned as an optional feature for the form.']}, {'end': 1455.742, 'segs': [{'end': 1123.679, 'src': 'embed', 'start': 1088.427, 'weight': 0, 'content': [{'end': 1094.269, 'text': "so let's now go into our app.js and let's create a post route for the submission.", 'start': 1088.427, 'duration': 5.842}, {'end': 1101.013, 'text': "okay, so we'll say app.post and it's going to be to send.", 'start': 1094.269, 'duration': 6.744}, {'end': 1104.434, 'text': "We'll put an arrow function here.", 'start': 1102.553, 'duration': 1.881}, {'end': 1108.555, 'text': 'And this needs a request and a response.', 'start': 1104.454, 'duration': 4.101}, {'end': 1116.317, 'text': "And then just to test it out, let's say console.log.", 'start': 1109.715, 'duration': 6.602}, {'end': 1121.678, 'text': "And let's actually, let's get the form field.", 'start': 1119.058, 'duration': 2.62}, {'end': 1123.679, 'text': "So we'll say request.body.", 'start': 1121.778, 'duration': 1.901}], 'summary': 'In app.js, a post route is created for submission, using app.post to send data and logging form field with request.body.', 'duration': 35.252, 'max_score': 1088.427, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1088427.jpg'}, {'end': 1205.963, 'src': 'embed', 'start': 1175.368, 'weight': 1, 'content': [{'end': 1179.871, 'text': 'And that should include all of these fields because we need to know what the user put in here.', 'start': 1175.368, 'duration': 4.503}, {'end': 1183.813, 'text': "So let's create a variable called output.", 'start': 1180.551, 'duration': 3.262}, {'end': 1185.894, 'text': "And we're going to set that.", 'start': 1184.993, 'duration': 0.901}, {'end': 1188.495, 'text': "I'm actually going to use an ES6 template string.", 'start': 1185.914, 'duration': 2.581}, {'end': 1189.936, 'text': "So I'm going to use backticks here.", 'start': 1188.535, 'duration': 1.401}, {'end': 1193.617, 'text': 'Take note that these are backticks, not single quotes.', 'start': 1190.396, 'duration': 3.221}, {'end': 1195.118, 'text': 'All right.', 'start': 1194.818, 'duration': 0.3}, {'end': 1197.759, 'text': "And then what we'll do is just create our HTML.", 'start': 1195.238, 'duration': 2.521}, {'end': 1205.963, 'text': "So let's put a paragraph and we're going to say you have a new contact request.", 'start': 1198.82, 'duration': 7.143}], 'summary': "Creating a variable 'output' using an es6 template string to generate html for a new contact request.", 'duration': 30.595, 'max_score': 1175.368, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1175368.jpg'}, {'end': 1261.071, 'src': 'embed', 'start': 1236.531, 'weight': 3, 'content': [{'end': 1244.518, 'text': "Now, in a template string, if you guys don't know, if you want to include a variable, it needs to be in money sign and then curly braces.", 'start': 1236.531, 'duration': 7.987}, {'end': 1246.359, 'text': 'So we want to get the name.', 'start': 1245.178, 'duration': 1.181}, {'end': 1251.864, 'text': "Now, remember, we can get the info with request.body, and we just want the name, so we'll say .name.", 'start': 1246.419, 'duration': 5.445}, {'end': 1257.988, 'text': "All right, and then we're going to go ahead and just put this in a couple more times.", 'start': 1252.044, 'duration': 5.944}, {'end': 1261.071, 'text': 'This is going to be the company.', 'start': 1258.549, 'duration': 2.522}], 'summary': 'Using template strings, obtain variables from request.body for name and company.', 'duration': 24.54, 'max_score': 1236.531, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1236531.jpg'}, {'end': 1383.954, 'src': 'heatmap', 'start': 1298.533, 'weight': 2, 'content': [{'end': 1305.495, 'text': "And then we'll put our variable, we'll say request.body.message.", 'start': 1298.533, 'duration': 6.962}, {'end': 1309.376, 'text': "And actually, let's put that in a paragraph.", 'start': 1307.295, 'duration': 2.081}, {'end': 1312.556, 'text': 'All right.', 'start': 1312.236, 'duration': 0.32}, {'end': 1314.777, 'text': "So that's our output.", 'start': 1313.837, 'duration': 0.94}, {'end': 1321.541, 'text': "Now for NodeMailer, we can just go, let's see, let me just open up the NodeMailer site.", 'start': 1315.358, 'duration': 6.183}, {'end': 1323.743, 'text': 'And this is basically all we need.', 'start': 1322.142, 'duration': 1.601}, {'end': 1326.524, 'text': "Now we don't need this create test account thing right here.", 'start': 1323.783, 'duration': 2.741}, {'end': 1328.305, 'text': "We don't need to wrap our stuff in that.", 'start': 1326.564, 'duration': 1.741}, {'end': 1330.426, 'text': "We just want everything that's inside of there.", 'start': 1328.365, 'duration': 2.061}, {'end': 1333.508, 'text': 'So this from here to here.', 'start': 1330.526, 'duration': 2.982}, {'end': 1335.209, 'text': "And we're going to copy.", 'start': 1334.329, 'duration': 0.88}, {'end': 1336.27, 'text': 'All right.', 'start': 1335.949, 'duration': 0.321}, {'end': 1340.152, 'text': "And then let's go ahead and put that stuff in right under the output.", 'start': 1336.41, 'duration': 3.742}, {'end': 1344.98, 'text': "Okay, so we'll just do that.", 'start': 1343.7, 'duration': 1.28}, {'end': 1352.603, 'text': 'All right.', 'start': 1345, 'duration': 7.603}, {'end': 1361.125, 'text': "and then, let's see, we have let transporter equals, node mailer dot create transport, and this is where we put our credentials for our server.", 'start': 1352.603, 'duration': 8.522}, {'end': 1371.749, 'text': "So, like I said, I'm using my Traverse Media account, so my host is gonna be mail dot Traverse Media dot com.", 'start': 1361.766, 'duration': 9.983}, {'end': 1375.67, 'text': 'The port is 587.', 'start': 1372.549, 'duration': 3.121}, {'end': 1379.432, 'text': "Secure, I'm not using SSL, so that's going to stay false.", 'start': 1375.67, 'duration': 3.762}, {'end': 1383.954, 'text': "And then for the user, that's going to be the full email address.", 'start': 1379.572, 'duration': 4.382}], 'summary': 'Setting up nodemailer with transporter credentials for sending emails.', 'duration': 62.592, 'max_score': 1298.533, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1298533.jpg'}, {'end': 1429.651, 'src': 'heatmap', 'start': 1399.295, 'weight': 0.712, 'content': [{'end': 1408.262, 'text': "right and then for the password should also be in quotes is 123 abc and i'm deleting this account right after.", 'start': 1399.295, 'duration': 8.967}, {'end': 1413.106, 'text': "so don't bother trying and down here we have our mail options.", 'start': 1408.262, 'duration': 4.844}, {'end': 1415.888, 'text': 'so the from who do we want this from?', 'start': 1413.106, 'duration': 2.782}, {'end': 1417.509, 'text': "so let's go ahead and put in.", 'start': 1415.888, 'duration': 1.621}, {'end': 1420.071, 'text': "i'll just put in my name.", 'start': 1417.509, 'duration': 2.562}, {'end': 1429.651, 'text': "actually, let's put in, Let's say node mailer contact.", 'start': 1420.071, 'duration': 9.58}], 'summary': "Password: '123 abc'. deleting account. from: 'node mailer contact'.", 'duration': 30.356, 'max_score': 1399.295, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1399295.jpg'}], 'start': 1088.427, 'title': 'Node.js post route and node mailer configuration', 'summary': 'Covers implementing a post route for form submission, testing with console.log, and creating an output string in the email body using es6 template string. it also introduces using template strings, configuring nodemailer, setting up nodemailer, and specifying mail server credentials.', 'chapters': [{'end': 1235.711, 'start': 1088.427, 'title': 'Implementing post route and node mailer', 'summary': 'Covers implementing a post route for form submission in app.js, testing the submission with console.log, and creating an output string in the body of the email using es6 template string.', 'duration': 147.284, 'highlights': ['Implementing a post route for form submission in app.js and testing it with console.log. Creation of post route, testing form submission, and use of console.log for testing.', 'Creation of an output string in the body of the email using ES6 template string. Utilizing ES6 template string to create an output string for the email body.']}, {'end': 1455.742, 'start': 1236.531, 'title': 'Nodemailer template string and configuration', 'summary': 'Introduces how to use template strings and configure nodemailer, including using variables, setting up nodemailer, and specifying credentials for the mail server.', 'duration': 219.211, 'highlights': ["Setting up NodeMailer configuration with host, port, and credentials The chapter explains how to set up NodeMailer configuration by specifying the host as mail.traveremedia.com, port as 587, and providing the user's email address and password.", 'Using template strings to include variables in the email content It demonstrates using template strings to include variables such as name, company, email, phone, and message in the email content, retrieved from request.body.', "Specifying recipients and sender's information in NodeMailer configuration The chapter covers specifying the sender's information as 'NodeMailer Contact' along with the sender's email address, and setting the recipient's email address, allowing multiple recipients."]}], 'duration': 367.315, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1088427.jpg', 'highlights': ['Creation of a post route for form submission and testing with console.log', 'Creation of an output string in the email body using ES6 template string', 'Setting up NodeMailer configuration with host, port, and credentials', 'Using template strings to include variables in the email content', "Specifying recipients and sender's information in NodeMailer configuration"]}, {'end': 1792.815, 'segs': [{'end': 1546.329, 'src': 'heatmap', 'start': 1471.317, 'weight': 2, 'content': [{'end': 1475.419, 'text': 'The HTML is going to be the output string that we created up here.', 'start': 1471.317, 'duration': 4.102}, {'end': 1481.422, 'text': "Okay, so we're going to just replace this with the output variable like that.", 'start': 1476.02, 'duration': 5.402}, {'end': 1483.343, 'text': 'All right.', 'start': 1481.442, 'duration': 1.901}, {'end': 1486.845, 'text': 'And if you want to create one for plain text, you can do that as well.', 'start': 1484.024, 'duration': 2.821}, {'end': 1488.006, 'text': "But I'm not going to go through that.", 'start': 1486.885, 'duration': 1.121}, {'end': 1491.521, 'text': "so let's see, send mail.", 'start': 1490.217, 'duration': 1.304}, {'end': 1493.065, 'text': "it's this is this is fine.", 'start': 1491.521, 'duration': 1.544}, {'end': 1495.01, 'text': "let's get rid of the comments here.", 'start': 1493.065, 'duration': 1.945}, {'end': 1496.374, 'text': "we don't need that.", 'start': 1495.01, 'duration': 1.364}, {'end': 1502.347, 'text': "this is basically If there's an error, if something goes wrong, it's going to show us in the console.", 'start': 1496.374, 'duration': 5.973}, {'end': 1505.448, 'text': "If there's not, then it's just going to say message sent.", 'start': 1502.787, 'duration': 2.661}, {'end': 1510.77, 'text': 'But then we have to figure out what we want to do once the form is submitted.', 'start': 1506.388, 'duration': 4.382}, {'end': 1513.411, 'text': 'So we can redirect or whatever.', 'start': 1511.331, 'duration': 2.08}, {'end': 1517.753, 'text': "What we're going to do is we're going to re-render the contact form with a message.", 'start': 1513.492, 'duration': 4.261}, {'end': 1522.015, 'text': 'Remember, we have this message right here, this MSG.', 'start': 1518.314, 'duration': 3.701}, {'end': 1524.837, 'text': "So we can pass something in that'll display there.", 'start': 1522.095, 'duration': 2.742}, {'end': 1527.258, 'text': "So let's say res.render.", 'start': 1524.977, 'duration': 2.281}, {'end': 1531.26, 'text': 'dot, not dot parentheses,', 'start': 1528.218, 'duration': 3.042}, {'end': 1546.329, 'text': "and we want to render contact and then we just want to pass in an object with a msg value and we'll just say email has been sent, just like that,", 'start': 1531.26, 'duration': 15.069}], 'summary': 'Creating output strings in html and plain text, handling form submission and rendering contact form with a message.', 'duration': 56.112, 'max_score': 1471.317, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1471317.jpg'}, {'end': 1692.419, 'src': 'embed', 'start': 1651.27, 'weight': 4, 'content': [{'end': 1655.253, 'text': "okay, because it's rejecting us, because we're actually doing it from our local host.", 'start': 1651.27, 'duration': 3.983}, {'end': 1658.255, 'text': "we're not doing it from the actual domain.", 'start': 1655.253, 'duration': 3.002}, {'end': 1662.097, 'text': 'so we need to set that and that should fix this error down here.', 'start': 1658.255, 'duration': 3.842}, {'end': 1667.12, 'text': "so let's save, let's go back over here and let's try it again.", 'start': 1662.097, 'duration': 5.023}, {'end': 1682.91, 'text': 'Hello from node app submit.', 'start': 1678.686, 'duration': 4.224}, {'end': 1685.552, 'text': 'Cross our fingers.', 'start': 1684.591, 'duration': 0.961}, {'end': 1692.419, 'text': 'And email has been sent.', 'start': 1690.917, 'duration': 1.502}], 'summary': 'Setting the correct domain fixed the error, email sent successfully.', 'duration': 41.149, 'max_score': 1651.27, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1651270.jpg'}, {'end': 1758.54, 'src': 'embed', 'start': 1730.863, 'weight': 0, 'content': [{'end': 1734.886, 'text': "it's coming from test at traversimedia.com.", 'start': 1730.863, 'duration': 4.023}, {'end': 1737.488, 'text': 'if we click on it, you have a new contact request.', 'start': 1734.886, 'duration': 2.602}, {'end': 1743.111, 'text': 'John Doe, for the name, the company, the email, the phone and hello from Node app.', 'start': 1738.268, 'duration': 4.843}, {'end': 1749.715, 'text': 'So we are now sending an email from our contact form through our Node.js app.', 'start': 1743.211, 'duration': 6.504}, {'end': 1751.676, 'text': "And it didn't even go into the spam.", 'start': 1750.175, 'duration': 1.501}, {'end': 1756.078, 'text': "Even though it's from our local host and all that stuff, it didn't even go into spam.", 'start': 1751.756, 'duration': 4.322}, {'end': 1758.54, 'text': "So that's it, guys.", 'start': 1757.279, 'duration': 1.261}], 'summary': 'New contact request received from john doe via node.js app, successfully delivered without going into spam.', 'duration': 27.677, 'max_score': 1730.863, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1730863.jpg'}, {'end': 1792.815, 'src': 'embed', 'start': 1775.697, 'weight': 6, 'content': [{'end': 1779.941, 'text': 'the goal is to have a place where people can go to help each other out for programming issues,', 'start': 1775.697, 'duration': 4.244}, {'end': 1784.066, 'text': 'as well as just a place to discuss new ideas and get feedback.', 'start': 1779.941, 'duration': 4.125}, {'end': 1785.227, 'text': 'i also check in daily.', 'start': 1784.066, 'duration': 1.161}, {'end': 1791.934, 'text': "there's a channel to request videos on youtube and much more, so if you want to check it out, just go to discord.gg.", 'start': 1785.227, 'duration': 6.707}, {'end': 1792.815, 'text': 'traversy media.', 'start': 1791.934, 'duration': 0.881}], 'summary': 'Create a platform for programming help, idea discussion, and daily check-ins on discord.gg traversy media.', 'duration': 17.118, 'max_score': 1775.697, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1775697.jpg'}], 'start': 1456.603, 'title': 'Sending email in node.js', 'summary': 'Covers the process of sending emails and rendering a contact form in node.js, including handling form submission and confirming successful email delivery, resulting in no spam markings.', 'chapters': [{'end': 1546.329, 'start': 1456.603, 'title': 'Node contact request', 'summary': "Demonstrates the process of sending an email and rendering a contact form in node.js, including the creation of an output string and handling form submission, with the message 'email has been sent' being displayed upon successful submission.", 'duration': 89.726, 'highlights': ['The chapter demonstrates the process of sending an email and rendering a contact form in Node.js.', "The output string is created and used to replace the HTML, with the message 'email has been sent' being displayed upon successful form submission.", "The handling of form submission includes re-rendering the contact form with a message, such as 'email has been sent.'", 'The console displays an error message if something goes wrong during the process.']}, {'end': 1792.815, 'start': 1546.329, 'title': 'Sending email from node.js app', 'summary': 'Demonstrates the process of sending an email from a node.js app, covering the use of smtp server, handling local host errors, and confirming successful email delivery, resulting in the successful transmission of an email from the app without it being marked as spam.', 'duration': 246.486, 'highlights': ['The email is successfully sent from the Node.js app, and it does not go into the spam folder, despite being sent from the localhost.', 'The process involves setting up an SMTP server and handling the rejection error caused by sending the email from the local host.', 'The chapter ends with an invitation to join a public discord server for programming discussion and support.']}], 'duration': 336.212, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/nF9g1825mwk/pics/nF9g1825mwk1456603.jpg', 'highlights': ['The email is successfully sent from the Node.js app, and it does not go into the spam folder, despite being sent from the localhost.', 'The chapter demonstrates the process of sending an email and rendering a contact form in Node.js.', "The output string is created and used to replace the HTML, with the message 'email has been sent' being displayed upon successful form submission.", "The handling of form submission includes re-rendering the contact form with a message, such as 'email has been sent.'", 'The process involves setting up an SMTP server and handling the rejection error caused by sending the email from the local host.', 'The console displays an error message if something goes wrong during the process.', 'The chapter ends with an invitation to join a public discord server for programming discussion and support.']}], 'highlights': ['The application will allow form submission to a specific email address, leveraging Firebase as the backend.', 'InMotion Hosting is recommended for email setup, with specific parameters like SMTP port and server name provided for configuration.', "The process of setting up a public folder in Node.js and Express involves creating a folder called 'public' to store assets like CSS files, images, and client-side JavaScript.", 'Creation of a post route for form submission and testing with console.log', 'The email is successfully sent from the Node.js app, and it does not go into the spam folder, despite being sent from the localhost.']}