Why do emails from my contact form bounce?

  • Thread starter Darkmisc
  • Start date
  • #1
Darkmisc
220
31
TL;DR Summary
When I click submit on my contact form, I get emails at the right address, but it's saying "Your message wasn't delivered to your-email@example.com because the domain example.com couldn't be found. Check for typos or unnecessary spaces and try again."
I have not specified your-email@example.com as my recipient address anywhere in my code.
Hi everyone

I'm making an email contact form that's supposed to send emails to my-email@gmail.com.

When I click submit, I'll get an email at my-email@gmail.com saying:
Your message wasn't delivered to your-email@example.com because the domain example.com couldn't be found. Check for typos or unnecessary spaces and try again.

That is, the email from the submission form is bouncing and it seems to think your-email@example.com was the intended address.
However, I can't find your-email@example.com anywhere in my code (I can't even find it where I originally got the code https://mailtrap.io/blog/react-contact-form/).

Does anyone know why it's doing this?


Thanks


email.js:
import React from 'react';
import axios from 'axios';

class Email extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      email: '',
      telephone: '',
      message: ''
    };
  }

  handleSubmit(e) {
    e.preventDefault();
    axios({
      method: "POST",
      url: "http://localhost:3003/send",
      data: {
        name: this.state.name,
        email: this.state.email,
        telephone: this.state.telephone,
        message: this.state.message
      }
    }).then((response) => {
      if (response.data.status === 'success') {
        alert("Message Sent.");
        this.resetForm();
      } else if (response.data.status === 'fail') {
        alert("Message failed to send.");
      }
    });
  }

  resetForm() {
    this.setState({ name: '', email: '', telephone: '', message: '' });
  }

  onNameChange(event) {
    this.setState({ name: event.target.value });
  }

  onEmailChange(event) {
    this.setState({ email: event.target.value });
  }

  onTelephoneChange(event) {
    this.setState({ telephone: event.target.value });
  }

  onMessageChange(event) {
    this.setState({ message: event.target.value });
  }

  render() {
    return (
      <div>
        <form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
          <div>
            <label htmlFor="name">Name</label>
            <input type="text" id="name" value={this.state.name} onChange={this.onNameChange.bind(this)} />
          </div>
          <div>
            <label htmlFor="email">Email address</label>
            <input type="email" id="email" value={this.state.email} onChange={this.onEmailChange.bind(this)} />
          </div>
          <div>
            <label htmlFor="telephone">Telephone number</label>
            <input type="tel" id="telephone" value={this.state.telephone} onChange={this.onTelephoneChange.bind(this)} />
          </div>
          <div>
            <label htmlFor="message">Message</label>
            <textarea rows="5" id="message" value={this.state.message} onChange={this.onMessageChange.bind(this)} />
          </div>
          <button type="submit">Submit</button>
        </form>
      </div>
    );
  }
}

export default Email;


index.js:
var express = require('express');
var router = express.Router();
var nodemailer = require('nodemailer');
var cors = require('cors');
const creds = require('./config');

var transport = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: 'my-email@gmail.com',
    pass: 'aaaa bbbb cccc dddd'
  }
};

var transporter = nodemailer.createTransport(transport);
transporter.verify((error, success) => {
  if (error) {
    console.log(error);
  } else {
    console.log('Server is ready to take messages');
  }
});

const app = express();

// Enable CORS
app.use(cors());

app.use(express.json());
app.use('/', router);

router.post('/send', (req, res, next) => {
  var name = req.body.name;
  var email = req.body.email;
  var telephone = req.body.telephone;
  var message = req.body.message;
  var content = `Name: ${name}\nEmail: ${email}\nTelephone: ${telephone}\nMessage: ${message}`; // Include telephone in the content

  var mail = {
    from: name,
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };

  transporter.sendMail(mail, (err, data) => {
    if (err) {
      console.log(err);
      res.json({
        status: 'fail'
      });
    } else {
      console.log('Email sent successfully');
      res.json({
        status: 'success'
      });
    }
  });
});

app.listen(3003);

config.js:
module.exports = {
    USER: 'my-email@gmail.com',
    PASS: 'aaaa bbbb cccc dddd'
}
 
Technology news on Phys.org
  • #2
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
 
  • Like
Likes Darkmisc
  • #3
There is an error in the code you copied. This:
index.js:
var mail = {
    from: name,
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
most likely should be this:
index.js:
var mail = {
    from: email,
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
or maybe:
index.js:
var mail = {
    from: '"' + name + '" <' + email + '>',
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
There is an example on the Nodemailer website front page.

Since you have no email in the From header, I would bet that one of the imported modules (or another program processing the mail afterward) fills in the missing email. (The domain example.com doesn't accept emails.)

Unrelated, this also should be changed:
index.js:
var transport = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: 'my-email@gmail.com',
    pass: 'aaaa bbbb cccc dddd'
  }
};
to:
index.js:
var transport = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: creds.USER,
    pass: creds.PASS
  }
};
 
  • Like
Likes Darkmisc
  • #4
Svein said:
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
This is the first contact form I've tried making. What does pinging mean?

I've tested it with https://www.gmass.co/smtp-test and the test email came through.
 
  • #5
jack action said:
There is an error in the code you copied. This:
index.js:
var mail = {
    from: name,
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
most likely should be this:
index.js:
var mail = {
    from: email,
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
or maybe:
index.js:
var mail = {
    from: '"' + name + '" <' + email + '>',
    to: 'my-email@gmail.com',
    subject: 'New Message from Contact Form',
    text: content
  };
There is an example on the Nodemailer website front page.

Since you have no email in the From header, I would bet that one of the imported modules (or another program processing the mail afterward) fills in the missing email. (The domain example.com doesn't accept emails.)

Unrelated, this also should be changed:
index.js:
var transport = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: 'my-email@gmail.com',
    pass: 'aaaa bbbb cccc dddd'
  }
};
to:
index.js:
var transport = {
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: creds.USER,
    pass: creds.PASS
  }
};
I've replaced the "from" field with email and "' + name + '" <' + email + '>', and neither work.

I also tried hardcoding the "from" field. Oddly enough, it just uses whatever I enter into the form.


I think the example from Nodemailer is the same as what's in the code, except for the highlighted lines (I kept the settings for gmail instead of using ethereal).

transporter.sendMail:
  transporter.sendMail(mail, (err, data) => {
    if (err) {
      res.json({
        status: 'fail'
      })
    } else {
      res.json({
       status: 'success'
      
      })
      
    }
  })
 
  • #6
Another thing, in your render() function, all your inputs should have a name attribute with the value you set for your id attributes.

https://react.dev/reference/react-dom/components/input#reading-the-input-values-when-submitting-a-form said:
Give a name to every <input>, for example <input name="firstName" defaultValue="Taylor" />. The name you specified will be used as a key in the form data, for example { firstName: "Taylor" }.
 
  • Like
Likes Darkmisc
  • #7
Darkmisc said:
This is the first contact form I've tried making. What does pinging mean?
Do you know how to open a Command Prompt on your computer?

Do so, and then type ping example.com:

Bad ping:
1716258628583.png

Good ping:
1716258849404.png
 
  • Like
Likes Darkmisc
  • #8
DaveC426913 said:
Do you know how to open a Command Prompt on your computer?

Do so, and then type ping example.com:

Bad ping:
View attachment 345645
Good ping:
View attachment 345647
I get this for example.com
example ping:
Pinging example.com [93.184.215.14] with 32 bytes of data:
Reply from 93.184.215.14: bytes=32 time=167ms TTL=53
Reply from 93.184.215.14: bytes=32 time=168ms TTL=53
Reply from 93.184.215.14: bytes=32 time=168ms TTL=53
Reply from 93.184.215.14: bytes=32 time=167ms TTL=53

Ping statistics for 93.184.215.14:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 167ms, Maximum = 168ms, Average = 167ms

And this for gmail.com

gmail ping:
Pinging gmail.com [142.250.70.229] with 32 bytes of data:
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=7ms TTL=60
Reply from 142.250.70.229: bytes=32 time=9ms TTL=60

Ping statistics for 142.250.70.229:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 7ms, Maximum = 9ms, Average = 7ms
 
  • #9
jack action said:
Another thing, in your render() function, all your inputs should have a name attribute with the value you set for your id attributes.
This is not necessary, the OP is not using form.data (although it would of course be possible to rewrite the code to use that, and then they wouldn't need to have event handlers for each of the <input>s).
Svein said:
Have you tried "ping example.com"? You may not have the applicable DNS. Or does your program need to know how to access DNS?
This is not going to help: the only external domain that the server script accesses is smtp.gmail.com and it is clear that something is getting through to the SMTP service because the OP's gmail inbox contains an error report.

In my experience the best way of debugging is to insert debugging code so you can see what is actually going on (I believe I have given similar advice to the OP before).

The first step should have been to insert the indicated line below:
index.js:
  transporter.sendMail(mail, (err, data) => {
    if (err) {
      console.log(err);
      res.json({
        status: 'fail'
      });
    } else {
      console.log('Email sent successfully');
      // Inserted to show what is going on:
      console.log(data);
      res.json({
        status: 'success'
      });
    }
  });
});
 
  • #10
pbuk said:
The first step should have been to insert the indicated line below:

And if that didn't help, visit the Nodemailer page to find the following options:
index.js:
// var transport = {
// Don't use var, it's 2024.
// https://medium.com/@codingsam/awesome-javascript-no-more-var-working-title-999428999994
const transport = {
  // Debugging (see https://www.nodemailer.com/smtp/).
  logger: true,
  debug: true,
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: 'my-email@gmail.com',
    pass: 'aaaa bbbb cccc dddd'
  }
};

If you want to become a programmer you need to learn how to work with all the methods and tools that programmers use, including debugging and documentation.

Patching together code from tutorials (in this case it looks like some very old tutorials) and then posting here so that we have to debug your code and read the documentation will not help you in the long run.
 
  • #11
pbuk said:
If you want to become a programmer you need to learn how to work with all the methods and tools that programmers use, including debugging and documentation.
I strongly agree!
 
Back
Top