1

I was implementing a website where the user inputs details. There is also an option for the user to attach images/pdf (less than 5MB) in the form. I wanted to store the entire image in my MongoDB as well as send the image to my mail account using node nodemailer.

Everything else is working that is I am able to send the mail with the details inputted by the user, but can't save image in my database or send it to a mail account.

The below is the code I have implemented

server.js:-

const express = require("express");
const multer = require('multer');
const path = require('path');
const app = express ();
app.set("view engine", "ejs");
const mongoose= require("mongoose");
const router = express.Router();
const nodemailer = require('nodemailer');
const smtpTransport = require('nodemailer-smtp-transport');

const User=require("./models/User");

// Multer image start
const storage = multer.diskStorage({
    destination: function(req, file, cb) {
      cb(null, './public/uploads/');
    },
    filename: function(req, file, cb) {
      cb(null, new Date().toISOString().replace(/:/g, '-') + file.originalname); //replace is used to save in computer readable format
    }
  });

const upload = multer({
    storage: storage,
    limits: {
      fileSize: 1024 * 1024 * 5
    }
});

mongoose.connect("mongodb://localhost/emergen");
var bodyParser = require('body-parser');

//Middleware
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));


var uploadFile = upload.single('image');
app.post('/send', uploadFile, (req, res) => {

    var name = req.body.name;
    var email = req.body.email;
    var phone = req.body.phone;
    var message = req.body.message;
    var image = req.file.originalname;
    var newUser= {name:name,email:email,phone:phone,message:message,image:image};

    User.create(newUser,function(err,newCreatedUser){
        if(err){
            console.log(err);
        }
        else{
            console.log(newCreatedUser);
        }
    })

    // Mailer implementation
    var output = `
      <p>You have a new Contact Request from Emergen Website</p>
      <h3>Contact Details</h3>
      <ul>  
        <li>Name: ${req.body.name}</li>
        <li>Email: ${req.body.email}</li>
        <li>Phone: ${req.body.phone}</li>
        <li>Phone: ${req.file.path}</li>
      </ul>
      <h3>Message</h3>
      <p>${req.body.message}</p>
    `;
    // <h3>Attachment</h3>  Attachments if need to be added above in output
    // <p>${req.body.attachment}</p>

    var transporter = nodemailer.createTransport(smtpTransport({
        service: 'gmail',
        host: 'smtp.gmail.com',
        auth: {
          user: 'JackRogers@gmail.com',
          pass: '******'
        }, tls:{
            rejectUnauthorized:false  // remove when uploading on server
          }
      }));

      var mailOptions = {
        from: 'qwerty@gmail.com',
        to: 'asd@gmail.com',
        subject: 'New Enquiry for Emergen',
        text: 'That was easy!',
        html: output
      };

      transporter.sendMail(mailOptions, function(error, info){
        if (error) {
          console.log(error);
        } else {
          console.log('Email sent: ' + info.response);
        }
        res.redirect('/contact-us');
      }); 
});

My model, User.js:-

    const mongoose=require("mongoose");

    const UserSchema= new mongoose.Schema({
        name:String,
        email:String,
        phone:Number,
        message:String,
        image: { data: Buffer, contentType: String }
    });

module.exports= mongoose.model("User",UserSchema);

my form, contact-us.ejs:-

<form class="text-center border border-light p-5" method="POST" action="send" enctype="multipart/form-data">

                                <p class="h4 mb-4">Contact us</p>

                                <!-- Name -->
                                <input type="text" id="FormName" class="form-control mb-4" placeholder="Name" name="name" required>

                                <!-- Email -->
                                <input type="email" id="FormEmail" class="form-control mb-4" placeholder="E-mail" name="email" required>

                                <input type="text" id="FormContact" class="form-control mb-4" placeholder="Contact No" name="phone" required>

                                <!-- Message -->
                                <div class="form-group">
                                    <textarea class="form-control rounded-0" id="exampleFormControlTextarea2" rows="5" placeholder="Message" name="message" required></textarea>
                                </div>
                                <!-- Attachment -->
                                <div class="form-group">
                                    <label for="name">Document Upload:</label>
                                    <input type="file" class="form-control" id="image" name="image" >
                                </div>                            
                                <!-- Send button -->
                                <button class="btn btn-info btn-block" type="submit">Send</button>

                            </form>

Please help me.Stuck on it for a while now

SemperFi
  • 2,358
  • 6
  • 31
  • 51

1 Answers1

1

one way to do this is:

  1. upload image to your server directory or some file hosting site.
  2. get url of image from your local server or file hosting server.
  3. saved that address in your database.
  4. use that address as image src.
Faizan Ul Haq
  • 454
  • 2
  • 7
  • 23
  • I am uploading the image in a directory called uploads. That part is working. How do i use the address stored in the database to send the image on the fly via mail/nodemailer – SemperFi Oct 22 '18 at 21:28
  • are you on local server ? – Faizan Ul Haq Oct 22 '18 at 21:29
  • with local development you can, attach file as attachment with email. to be displayed as image being part of email(HTM) you must have url of image that can accessed using internet. this can't be done when image is on your local machine. – Faizan Ul Haq Oct 23 '18 at 20:53
  • @MuhammadFaizanUlHaq, could you please elaborate on "very bad practice"? Thanks – ddsultan Feb 03 '22 at 17:24
  • @ddsultan please refer to this discussion https://stackoverflow.com/questions/3748/storing-images-in-db-yea-or-nay#:~:text=The%20problem%20with%20storing%20only,unwittingly%20has%20an%20integrity%20error. – Faizan Ul Haq Feb 03 '22 at 21:40
  • @MuhammadFaizanUlHaq, thanks for the link, but the reference contradicts with your answer: "Saving image in database is considered very bad practice." – ddsultan Feb 04 '22 at 17:19
  • 1
    @ddsultan yes it depends on the use case, this answer is 2 years old so was my knowledge at that time. i will edit the answer now. – Faizan Ul Haq Feb 04 '22 at 19:10