Form captures spam but not legitimate messages

This form was working when I first launched the site, however, it’s been a while since mail was getting through. I noticed spam messages were still getting through :exploding_head:

I recreated the form here, and this seems to work.

NOTE: The did not add i18n or a conditional redirection link to the recreated form. However, I can’t see why they are affecting the original form.

Form component which is currently not working
import React, { useContext } from "react"
import { GlobalContext } from "../../context/GlobalContext"
import { navigate } from "gatsby"

import { Form, Input, message } from "antd"
import { UserOutlined, MailOutlined } from "@ant-design/icons"

import { FormattedMessage, useIntl } from "react-intl"

const { TextArea } = Input

function encode(data) {
  return Object.keys(data)
    .map(key => encodeURIComponent(key) + `=` + encodeURIComponent(data[key]))
    .join(`&`)
}

const ContactForm = () => {
  const { lang } = useContext(GlobalContext)

  const intl = useIntl()

  const formName = `contact page v1` // Must update the form name if you add or remove fields from the form

  const handleSubmit = values => {
    if (values[`bot-field`] === undefined) {
      delete values[`bot-field`]
    }

    fetch(`/`, {
      method: `POST`,
      headers: { "Content-Type": `application/x-www-form-urlencoded` },
      body: encode({
        "form-name": formName,
        ...values,
      }),
    })
      .then(() => showSuccess(values))
      .catch(error => showError(error))
  }

  const sendConfirmation = intl.formatMessage({
    id: "contact.form.sendConfirmation",
    defaultMessage: "Your message has been sent.",
    description: "Message shown after successful submission of form",
  })

  function thanksLink() {
    if (lang === "en") {
      return `/en/thanks`
    } else if (lang === "de") {
      return `/de/merci`
    }
  }

  const showSuccess = values => {
    message.success(sendConfirmation, 3).then(() =>
      navigate(thanksLink(), {
        state: { values },
      })
    )
  }

  const showError = error => {
    message.error(
      <FormattedMessage
        id="contact.form.failedSendMessage"
        defaultMessage="There was an error sending your form. Please try another form of contact."
        desctiption="Contact form message after submitting if form failed"
      />
    )
    console.log(error)
  }

  const namePlaceholder = intl.formatMessage({
    id: "contact.form.placeholder.name",
    defaultMessage: "Name",
    description: "Contact form placeholder for name field",
  })
  const emailPlaceholder = intl.formatMessage({
    id: "contact.form.placeholder.email",
    defaultMessage: "Email",
    description: "Contact form placeholder for email field",
  })
  const messagePlaceholder = intl.formatMessage({
    id: "contact.form.placeholder.message",
    defaultMessage: "Message",
    description: "Contact form placeholder for message field",
  })

  return (
    <>
      {/*
      This defines how your form is setup for the Netlify bots.
      Users will not see or interact with this form.
      */}

      <form
        name={formName}
        data-netlify="true"
        data-netlify-honeypot="bot-field"
        hidden
      >
        <input type="text" name="name" />
        <input type="email" name="email" />
        <textarea name="message"></textarea>
      </form>

      <Form name="cf" method="post" onFinish={handleSubmit} layout="vertical">
        {/* This is the hidden field that the netlify-honeypot uses. */}
        <Form.Item
          label="Don't fill this out"
          className={`hidden`}
          style={{ display: `none` }}
          name="bot-field"
        >
          <Input type={`hidden`} />
        </Form.Item>

        <Form.Item aria-label="Name" name="name">
          <Input
            placeholder={namePlaceholder}
            prefix={<UserOutlined className="site-form-item-icon" />}
          />
        </Form.Item>

        <Form.Item
          aria-label="Email"
          rules={[
            {
              required: true,
              type: `email`,
              message: (
                <FormattedMessage
                  id="contact.form.required.email"
                  defaultMessage="Please enter your email"
                  description="validation error message for email field"
                />
              ),
            },
          ]}
          name="email"
        >
          <Input
            placeholder={emailPlaceholder}
            prefix={<MailOutlined className="site-form-item-icon" />}
          />
        </Form.Item>

        <Form.Item
          aria-label="Message"
          rules={[
            {
              required: true,
              message: (
                <FormattedMessage
                  id="contact.form.required.message"
                  defaultMessage="Please enter your message"
                  desctiption="validation error message for message field"
                />
              ),
            },
          ]}
          name="message"
        >
          <TextArea placeholder={messagePlaceholder} rows={5} />
        </Form.Item>

        <Form.Item>
          <button
            type="primary"
            htmltype="submit"
            disabled={false}
            className="inline rounded px-4 py-2 bg-apgreen hover:bg-apgreendark text-white tracking-wide transition duration-200"
          >
            <FormattedMessage
              id="contact.form.button"
              defaultMessage="Send"
              description="Contact form submit button text"
            />
          </button>
        </Form.Item>
      </Form>
    </>
  )
}

export default ContactForm

I’m not really sure what to try next in order to troubleshoot this, so any help would be greatly appreciated!

Thanks!

New findings: I created a new branch to test the form. Stripped it back to a basic form, and gradually added in antd styling, i18n, conditionals etc.

Each time, I re-built the site, checked the preview, and it was working.

I ended up with exactly the same code, merged the branch (just in case), re-built, tested the form, and again the message is not coming through.

So confused.

Hey, I don’t want to be a pain with this… but super curious why this might happen and what I can do to fix it?

I just created a new branch, only added a title to the form, and changed the form name for separation in Netlify.

The form on the new branch works.
The form on the master branch does not.

that is so strange - and sorry we haven’t been able to really do anything with this yet!

I will try and get some :eyes: on this for you and see if we have any ideas.

1 Like

Hey, @perry any joy with this one? Thx :slight_smile:

hi malki, we haven’t given up yet! we’ve been a bit short staffed this week, but we’ll try and take a look as soon as we can. We haven’t forgotten!

1 Like

Hey, @perry I’m not sure how to approach this, the reason for the issue seems to be in the master branch somehow… but I need to have a working form, I’ve been fending off the client’s concerns about this for a month now :grimacing: so I think I need to find another solution, which will mean you can’t troubleshoot it.

Can you let me know what would be best for us both in this situation?

Cheers!

Hiya @Maiki and sorry to be so slow to get back to you!

What I notice when I test your “not working” form is that you POST to https://seilpark-interlaken.ch/

This would be fine, except that you have a redirect from / to /en that always occurs. POST’ing gets an HTTP 301 redirect, and is not retried by the browser.

Please POST to a URL that gets an HTTP 200 response - like Ropes Park Interlaken @ Outdoor instead and I bet things work better.

But let me know if not - we’ll be happy to try again in the troubleshooting!

Let me know if not!

Hey @fool that did the trick… so simple… ugh! I’m still not entirely sure why spam was getting through the same form, and why it works on the other branch, but I’m happy it’s working again!

Also, if you don’t mind the stupid question, how did you test the form to see the POST’ing gets an HTTP 301 redirect? Hoping, I can learn something here for future troubleshooting.

Are you able to remove all other forms in the “adventure-park” site except “contact v2”? I can’t see where to do that?

Thanks for the help!

I’d guess the spammers were POST’ing to the wrong (well, correct, but not what you had configured) URL. A lot of their “tools” seem to disregard conventions including required fields, so not a total surprise that there are some shortcuts that in this case led to their POSTs working “better” than the intended ones!

I saw the POST in the browser dev tools as I watched, and that the response status was 301. It’s pretty hard to spot, since your page reloads itself and thus clears the tools’ network tab when it does (which hides the “failed” POST), but I captured a HAR file (HAR Analyzer) which let me look at the whole journey more slowly, and see the problem.

Finally, yes, I can remove those forms for you. You can self serve via an undocumented API call if you’ll need to do it frequently but you weren’t missing anything in the UI or docs about how to do it on your own. Please confirm that I will be removing these forms and all of their submissions:

formTest v1
contact no i18n
contact page v1
cf
Contact Page
contact

Amazing, thanks for the knowledge! …and yes, confirmed for removal :slight_smile:

thx @fool

All done! Take care :slight_smile:

1 Like