I have been trying to set up nodemailer with my static site. I am having trouble getting require to work at the moment. I know I am doing something wrong - I just need another set of eyes to assist.
HTML:
<form name="betaForm" action="/betaForm" method="post">
<div class="form-group" >
<label for="contactName" style="float:left;">Contact Name</label>
<input type="test" name="contactName" value="" class="form-control" id="contactName" >
</div>
<div class="form-group">
<label for="practiceName" style="float:left;">Practice Name</label>
<input type="test" name="practiceName" value="" class="form-control" id="practiceName">
</div>
<div class="form-group">
<label for="phone1" style="float:left;">Phone</label>
<input type="test" name="phone1" value="" class="form-control" id="phone1">
</div>
<div class="form-group">
<label for="email1" style="float:left;">Email</label>
<input type="email" name="email1" value="" class="form-control" id="email1" >
</div>
<button type="submit" value="Send" class="btn btn-default">Submit</button>
</form>
SERVER.JS
var express=require('express');
var nodemailer = require("nodemailer");
var app = express();
app.get('/',function(req,res){
res.sendfile('www/index.html');
});
app.listen(3000,function(){
console.log("Express Started on Port 3000");
});
SENDMAIL.JS
var app = require('express');
var nodemailer = require('nodemailer');
app.get('/betaForm', routes.betaForm);
app.post('/betaForm', function (req, res) {
var mailOpts, smtpTrans;
//Setup Nodemailer transport, I chose gmail. Create an application-specific password to avoid problems.
smtpTrans = nodemailer.createTransport('SMTP', {
service: 'Gmail',
auth: {
user: "test#gmail.com",
pass: "password"
}
});
//Mail options
mailOpts = {
from: req.body.contactName + ' <' + req.body.email1 + '>', //grab form data from the request body object
to: 'test#gmail.com',
subject: ' beta contact form',
text: req.body.contactName,
};
smtpTrans.sendMail(mailOpts, function (error, response) {
//Email not sent
if (error) {
res.render('betaForm', { title: ' beta contact', msg: 'Error occured, message not sent.', err: true, page: 'contact' })
}
//Yay!! Email sent
else {
res.render('betaForm', { title: ' beta contact', msg: 'Message sent! Thank you.', err: false, page: 'contact' })
}
});
});
ROUTES.JS
var exports = module.exports = {};
exports.betaForm = function(req, res){
res.render('betaForm', { title: 'beta contact form', page: '/#beta' })
};
Sorry I'm not allowed to write comments.
Do you use the bodyparser?
Related
So I've been trying to figure out for hours, how to pass an error from a POST route in Express to an EJS template. I'm building a blog app and I want to prevent the redirect to the root route and instead display an error if the title input or text area are empty. Can this be done server-side or do I have to track the inputs on the client-side?
Here is my Compose template:
<form action="/compose" method="POST">
<div class="form-group">
<label for="postTitle">Title</label>
<input type="text" name="postTitle" class="form-control" id="postTitle" autocomplete="off">
<label for="postBody">Post</label>
<textarea name="postBody" class="form-control" autocomplete="off" rows="8"></textarea>
</div>
<button type="submit" name="button" class="btn btn-primary">Publish</button>
</form>
Here's my GET and POST routes:
compose_get: (req, res) => res.render("compose"),
compose_post: (req, res) => {
const postTitle = req.body.postTitle;
const postBody = req.body.postBody;
let postDate = new Date();
const post = new Posts({
date: postDate,
title: postTitle,
content: postBody
});
post.save(err => {
if (!err) {
res.redirect("/");
}
});
}
I want to make it so if a user says a specific thing, the socket.io responds with something.
ex.
Input: !hi
Output: hello!
If there's a way to do this, I would like to know how, thanks!
I tried making something so if a user just presses the send button, it sends "Please type something", it can only be seen by the user typing the space.
var spaced = ' ';
if (spaced) {
socket.emit('message', {
username: 'System',
text: 'Please Type Something',
timestamp: moment().valueOf()
});
}
server.js:
var PORT = process.env.PORT || 3000;
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var moment = require('moment');
var connectedUsers = {};
app.use(express.static(__dirname + '/public'));
io.on('connection', function(socket) {
/*var socketId = socket.id;
var clientIp = socket.request.connection.remoteAddress;
console.log('A user is connected. - IP: ' + clientIp + " | ID: " + socketId);*/
console.log('A user is connected.')
socket.on('disconnect', function() {
var userData = connectedUsers[socket.id];
if (typeof userData !== 'undefined') {
socket.leave(connectedUsers[socket.id]);
io.to(userData.room).emit('message', {
username: 'System',
text: userData.username + ' has left!',
timestamp: moment().valueOf()
});
delete connectedUsers[socket.id];
}
});
socket.on('joinRoom', function(req, callback) {
if (req.room.replace(/\s/g, "").length > 0 && req.username.replace(/\s/g, "").length > 0) {
var nameTaken = false;
Object.keys(connectedUsers).forEach(function(socketId) {
var userInfo = connectedUsers[socketId];
if (userInfo.username.toUpperCase() === req.username.toUpperCase()) {
nameTaken = true;
}
});
if (nameTaken) {
callback({
nameAvailable: false,
error: 'This username is taken, please choose another one.'
});
} else {
connectedUsers[socket.id] = req;
socket.join(req.room);
socket.broadcast.to(req.room).emit('message', {
username: 'System',
text: req.username + ' has joined!',
timestamp: moment().valueOf()
});
callback({
nameAvailable: true
});
}
} else {
callback({
nameAvailable: false,
error: 'Please complete the forum.'
});
}
});
socket.on('message', function(message) {
message.timestamp = moment().valueOf();
io.to(connectedUsers[socket.id].room).emit('message', message);
});
socket.emit('message', {
username: 'System',
text: 'Ask someone to join this chat room to start talking.',
timestamp: moment().valueOf()
});
});
http.listen(PORT, function() {
console.log('Server started on port ' + PORT);
});
The body in my index.html:
<body>
<div class="container">
<div id="login-area">
<div class="row">
<div class="large-7 medium-7 small-12 columns small-centered">
<form id="login-form">
<h2>Twintails🎀 Bot Chatroom</h2>
<p id="error-msg"></p>
<input
type="text"
name="username"
placeholder="Enter your username"
/>
<input
type="text"
name="room"
placeholder="Enter a chat room name"
/>
<input type="submit" value="Join Chat" />
</form>
</div>
</div>
</div>
<div class="row" id="message-area">
<div class="large-8 columns small-centered">
<h2>Twintails🎀 Bot Chatroom</h2>
<div class="chat-wrap">
<div class="top">
<h5 class="room-title"></h5>
</div>
<div id="messages"></div>
<form id="message-form">
<div class="input-group">
<input
type="text"
placeholder="Type message here"
class="input-group-field"
name="message"
/>
<div class="input-group-button">
<input type="submit" value="Send" />
</div>
</div>
</form>
</div>
</div>
</div>
<footer>
<p>
Add the
<a href="https://twintails-bot-dashboard.glitch.me/" target="_blank"
>Twintails🎀 bot!</a
>
</p>
<p>
Use the 'Mod' room to talk to mods!
</p>
</footer>
</div>
<script src="/js/jquery.js"></script>
<script src="/js/socket.io-1.7.3.min.js"></script>
<script src="/js/moment.min.js"></script>
<script src="/js/app.js"></script>
<script src="/js/foundation.min.js"></script>
<script type="text/javascript">
$(document).foundation();
</script>
</body>
If what you're talking about is when the server receives a specific typed message, you want to send a specific response directly back to the user who typed that message, you can just do something like this:
// this is your existing server-side handler which the `if` statement added to it
socket.on('message', function(message) {
if (message.text === '!hi') {
socket.emit('message', {
username: 'System',
text: 'hello!',
timestamp: moment().valueOf()
});
} else {
message.timestamp = moment().valueOf();
io.to(connectedUsers[socket.id].room).emit('message', message);
}
});
Why not just use a simple if statement?
if (mySocketData === "!hi") {
socket.emit('Hello!');
}
New to Socket.IO, not sure if this helps, sorry!
Error:
TypeError: Cannot destructure property 'firstName' of 'req.body.warranty' as it is undefined.
I tried to handle MulterError by this documentation https://www.npmjs.com/package/multer, but
faced a problem.
Console.log(req.body) gives { }, while form enctype is equal to 'multipart/form-data'. If I change it to the 'application/x-www-form-urlencoded' req.body is normal, but files do not upload to the server.
Multer Usage
var storage = multer.diskStorage({
destination:"./public/uploads/",
filename:(req,file,cb)=>{
cb(null,file.fieldname+"-"+Date.now()+path.extname(file.originalname));
}
});
var upload = multer({
storage: storage,
limits:{fileSize: 10000000}
}).fields([{
name: 'purchasePhoto', maxCount: 1
}, {
name: 'defectPhoto', maxCount: 1
}]);
Post route from the warranty page with a form enctype="multipart/form-data"
router.post("/warranty", function(req, res){
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
req.flash('error', 'Multer Error');
return res.redirect('/pages/warranty#flash');
} else if (err) {
console.log('error');
}
});
var { firstName, lastName, streetAdress, city, state, zip, country, email, phoneNumber, product, bikeShop, assembledBy, issue} = req.body.warranty;
var newWarranry = { purchasePhoto: purchasePhoto, defectPhoto: defectPhoto, firstName: firstName, lastName: lastName, streetAdress: streetAdress, city: city, state: state, zip: zip, country: country, email: email, phoneNumber: phoneNumber, product: product, bikeShop: bikeShop, assembledBy: assembledBy, issue: issue};
if ( !firstName || !lastName || !streetAdress || !city || !state || !zip || !country || !email || !phoneNumber || !product || !bikeShop || !assembledBy ) {
req.flash('error', 'Please enter all of the fields with "*"');
return res.redirect('/pages/warranty#flash');
} else{
Warranty.create(newWarranry, function(err, newWarranry){
if(err){
console.log(err);
}else{
console.log(newWarranry);
req.flash('success', 'Thank you! The form was submitted successfully.');
return res.redirect('/pages/warranty#flash');
}
});
}
});
Warranty page form with a action="warranty" method="post" and enctype="multipart/form-data". All inputs with a name="warranty[...]"
<form action="warranty" method="post" enctype="multipart/form-data">
<b>Warranty Claim Form</b>
<h6>Rider Info</h6>
<div class="row">
<div>
<input type="" name="warranty[firstName]" placeholder="First Name*">
</div>
<div>
<input type="" name="warranty[lastName]" placeholder="Last Name*">
</div>
<div>
<input type="" name="warranty[streetAdress]" placeholder="Street Adress*">
</div>
<div>
<input type="" name="warranty[streetAdressLine]" placeholder="Street Adress Line 2">
</div>
<div>
<input name="warranty[city]" placeholder="City*">
</div>
<div>
<input type="" name="warranty[state]" placeholder="State/Province*">
</div>
<div>
<input type="" name="warranty[zip]" placeholder="ZIP/Postal code*">
</div>
<div>
<input type="" name="warranty[country]" placeholder="Country*">
</div>
<div>
<input type="" name="warranty[email]" placeholder="Email*">
</div>
<div>
<input type="" name="warranty[phoneNumber]" placeholder="Phone Number*">
</div>
</div>
<h6>Product Details</h6>
<div class="row">
<div>
<input name="warranty[product]" placeholder="Product (Ex. Titan II Frame)*">
</div>
<div>
<input type="" name="warranty[color]" placeholder="Color (Ex. Black)">
</div>
<div>
<input type="" name="warranty[size]" placeholder="Size (Ex. 20.5in / 175mm)">
</div>
<div>
<input type="" name="warranty[serialNumber]" placeholder="Serial number or date code (bikes, frames, forks, bars, cranks only)">
</div>
</div>
<h6>PURCHASE & ASSEMBLY DETAILS</h6>
<div class="row">
<div >
<input name="warranty[bikeShop]" placeholder="Bike Shop or online retailer*">
</div>
<div>
<input type="" name="warranty[modelYear]" placeholder="Model year (Ex.2015)">
</div>
<div >
<input type="" name="warranty[assembledBy]" placeholder="Assembled by myself/ bike shop">
</div>
</div>
<h6>PRODUCT ISSUE/DEFECT INFORMATION</h6>
<div class="row">
<div>
<textarea name="warranty[issue]"></textarea>
</div>
</div>
<h6>UPLOAD PROOF OF PURCHASE OR RECEIPT (SCAN OR MOBILE PHOTO)</h6>
<div>
<input type="file" name="purchasePhoto" id="fileOne">
<label for="fileOne">
<span>Upload file</span>
</label>
</div>
<h6>UPLOAD PRODUCT IMAGES, INCLUDING IMAGES OF DEFECTS</h6>
<div class="form-group">
<input type="file" name="defectPhoto" id="fileTwo">
<label for="fileTwo">
<span>Upload file</span>
</label>
</div>
<div>
<button type="submit"><p>Submit</p></button>
</div>
</form>
Move your code up into the multer callack
router.post("/warranty", function(req, res) {
upload(req, res, function(err) {
if (err) {
req.flash("error", "Multer Error");
return res.redirect("/pages/warranty#flash");
}
var {
firstName,
lastName,
streetAdress,
city,
state,
zip,
country,
email,
phoneNumber,
product,
bikeShop,
assembledBy,
issue
} = req.body.warranty;
var newWarranry = {
purchasePhoto: purchasePhoto,
defectPhoto: defectPhoto,
firstName: firstName,
lastName: lastName,
streetAdress: streetAdress,
city: city,
state: state,
zip: zip,
country: country,
email: email,
phoneNumber: phoneNumber,
product: product,
bikeShop: bikeShop,
assembledBy: assembledBy,
issue: issue
};
if (
!firstName ||
!lastName ||
!streetAdress ||
!city ||
!state ||
!zip ||
!country ||
!email ||
!phoneNumber ||
!product ||
!bikeShop ||
!assembledBy
) {
req.flash("error", 'Please enter all of the fields with "*"');
return res.redirect("/pages/warranty#flash");
} else {
Warranty.create(newWarranry, function(err, newWarranry) {
if (err) {
console.log(err);
} else {
console.log(newWarranry);
req.flash(
"success",
"Thank you! The form was submitted successfully."
);
return res.redirect("/pages/warranty#flash");
}
});
}
});
});
The problem is not with the way we send data, rather the multer library is unable to parse out the mutiple files from the form.
use multer.array method and it should work as expecteed, I tried out the same example you gave it seems to be working as expected.
Inside app.js, use app.use(upload.array()), where upload is an instance of multer.
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
let bodyParser = require('body-parser');
//******* require multer library ******
var multer = require('multer');
var upload = multer();
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// ***** this line important
app.use(upload.array());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
This will resolve the issue!!
My problem was that I used
app.use(bodyParser.urlencoded({extended: true}));
But I had to use
app.use(bodyParser.urlencoded({extended: false}));
as this is my first question on StackOverflow, I do hope I provide you with enough details to the problem in order to fix it. If you need any further info, don't hesitate to ask.
In short, I'm trying to create a simple signup page for a newsletter that adds subscribers to Mailchimp.
In the terminal/command-line I get this message:
{
type: 'http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/',
title: 'Invalid Resource',
status: 400,
detail: "The resource submitted could not be validated. For field-specific details, see the 'errors' array.",
instance: '4d92a5b7-20fb-4f1c-be19-fbcd6548e745',
errors: [
{
field: '',
message: 'Required fields were not provided: email_address'
}
]
}
My HTML-body looks like this:
`
<img class="mb-4" src="images/logo.png" alt="" width="172" height="172">
<h1 class="h3 mb-3 font-weight-normal">Signup to our Newsletter</h1>
<input type="text" name="fName" class="form-control top" placeholder="First Name" required autofocus>
<input type="text" name="lName" class="form-control middle" placeholder="Last Name" required>
<input type="email" name="email" class="form-control bottom" placeholder="Email" required>
<button class="btn btn-lg btn-primary btn-block btn-sign-up" type="submit">Sign me up!</button>
<p class="mt-5 mb-3 text-muted">© PB Plus 2017-2020</p>
`
This is the 'POST' part of my Javascript:
app.post("/", function(req, res) {
const firstName = req.body.fName;
const lastName = req.body.lName;
const mail = req.body.email;
const data = {
members: [{
email_adress: mail,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}]
};
var jsonData = JSON.stringify(data);
const url = "https://us4.api.mailchimp.com/3.0/lists/fae76eccaf";
const options = {
method: "POST",
auth: "xavier1:6cbb8e0a03109b3b2ef74adc0127f986-us4"
}
const request = https.request(url, options, function(response) {
if (response.statusCode === 200) {
res.sendFile(__dirname + "/succes.html");
} else {
res.sendFile(__dirname + "/failure.html");
}
response.on("data", function(data) {
console.log(JSON.parse(data));
})
})
request.write(jsonData);
request.end();
})
If anyone knows what I did wrong, please let me know! Thanks in advance.
Well, After spending many hours figuring out what's wrong, I typed email_adress instead of email_address. Problem solved.
In my application, i have a html form to add user. Once user is added they will get mail using sendmail() function in javascript. Everything works fine and mail is sending as my standard. But i want to add the user name in the content of my email message.
example:
DEAR {USERNAME}
(follwed by my message)
HTML form is:
<form id="frmAddUser" method="post" action="/add_value" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="focusedInput">First Name</label>
<div class="controls">
<input class="input-xlarge focused" name="txtFirstName" type="text" id="txtFirstName" tabindex="2">
</div>
</div>
<div class="control-group">
<label class="control-label" for="focusedInput">Last Name</label>
<div class="controls">
<input class="input-xlarge focused" name="txtLastName" type="text" id="txtLastName" tabindex="3">
</div>
</div>
<div class="form-actions">
<input id="btnSubmit" class="btn btn-primary" value="Add User" onclick="return validateControls(this.form);" type="submit" />
<input id="btnCancel" class="btn" value="Clear" onclick="document.getElementById('tsubmit').style.display='none'; document.getElementById('loadeux').style.display=''; return true;" type="submit" />
</div>
</form>
And my js is like this:
exports.InsertData = function (req, res) {
var timestamp = new Date();
console.log(timestamp);
obj._id = req.body.txtLoginId,
obj.name = { f: req.body.txtFirstName, l: req.body.txtLastName },
obj.email = req.body.txtEmailID,
obj.MobileNo = req.body.txtmobile,
obj.Phone_Ext = req.body.txtphone,
obj.status = req.body.ddSfk,
obj.isAdmin = req.body.ddlAdmin,
obj.pwd = generatePassword(8),
obj.ispwdChange = "False",
obj.stamps = {
ins: timestamp,
Ins_Ip: ipAddress()
},
qry.insert(obj.schUserData, obj, function (err, result) {
if (err)
return;
sendMail(result.email, DbConfig.mailConfig.subject,'Dear{{{user}}}, Welcome to Bigtree Entertainment Pvt Ltd, Your Login details are below: your user name is: {{{user}}} and Password is: '+ result.pwd)
});
res.redirect('/Group');
}
///*----------- User Send Mail ---------------*/
function sendMail(toMailId, subject, body) {
for (var i = 0; i < 1; i++) {
email.send({
ssl: true,
host: DbConfig.mailConfig.host, // smtp server hostname
port: DbConfig.mailConfig.port, // smtp server port
domain: DbConfig.mailConfig.domain, // domain used by client to identify itself to server
to: toMailId,
from: DbConfig.mailConfig.from,
subject: subject,
reply_to: DbConfig.mailConfig.reply_to,
body: body,
authentication: DbConfig.mailConfig.authentication, // auth login is supported; anything else is no auth
username: DbConfig.mailConfig.username, // username
password: DbConfig.mailConfig.password, // password
debug: DbConfig.mailConfig.debug // log level per message
},
function (err, result) {
if (err) { console.log(err); }
});
}
}
My Json is:
{
"mongodbUrl":"mongodb://sfk:sfk#192.168.3.115:27017/BMS",
"mailConfig" :{
"host": "smtp.gmail.com",
"port": 465,
"domain": "[127.0.0.1]",
"from":"example#gmail.com" ,
"subject":"Please Use this Onetime password to create your own password",
"reply_to": "example#gmail.com",
"authentication": "login",
"username": "example#gmail.com",
"password": "paswd",
"debug": true
}
}