HNG
HNG

Reputation: 333

Contact Form 7 Recaptcha 3 headless site

I am building a wordpress headless site (frontend using Nuxt.js) and am trying to use recaptcha v3 in contact form 7 . I have already setup the integration using the built in cf7 integration.

But, the problem is contact form 7 is marking all of my emails as spam. Therefore I installed Flamingo plugin just to see the error log. Apparently the error log says reCAPTCHA response token is empty. Which makes sense because the recaptcha is setup in WordPress while since my frontend is decoupled, it doesn't get the token.

I have read about using vue-recaptcha but that means setting up a new recaptcha that is entirely separate from the recaptcha I setup in WordPress. I can't find a way to link the recaptcha for WordPress and my frontend together.

Any advice would be very much appreciated, thanks!

A post that I found similar to mine: https://www.reddit.com/r/Wordpress/comments/o48hd1/contact_form_7_plugin_endpoint_for_recaptcha/ , but no clear answers.

I am successful in implementing recaptcha at the frontend right now but I have no idea how to make use of the recaptcha token from WordPress for the backend and frontend to work together. The recaptcha certainly cannot be only at the frontend because else people would be able to use Postman to spam my endpoint. This is how I did it:

async function verifyCaptcha() {
      try {
        // @ts-ignore
        recaptchaToken.value = await context.$recaptcha.execute();

    const response = await axios.post(
      `/captcha-api/siteverify?secret=${process.env.SECRET_KEY}&response=${recaptchaToken.value}`
    );

      // console.log(response)

    return response;
  } catch (error) {
    return error;
  }
}

async function onSubmit(e: any) {
  const recaptchaResponse = await verifyCaptcha();

  // Display error message if verification was not successful
  if (!recaptchaResponse.data.success) {
    // @ts-ignore
    context.$recaptcha.reset()
    return;
  }

  // If verification was successful, send the message
  await submit(e);
}

Upvotes: 0

Views: 1812

Answers (1)

HNG
HNG

Reputation: 333

I have found the solution. We simply need to pass some specific recaptcha 3 responses required by contact form 7 back to contact form 7.

    const token = await context.$recaptcha.execute('login')
    // console.log('ReCaptcha token:', token)

    const emailBody = {
      "your-name" : form.name,
      "email" : form.email,
      "enquiry" : form.enquiry,
      "message" : form.message,

      //recaptcha responses to pass back to CF7
      "_wpcf7_recaptcha_response" : token,
      "wpcf7_recaptcha_response" : token,
      "recaptcha_response" : token,
      "recaptcha" : token,
      "token" : token
    }

    const body = new FormData()
    for (const field in emailBody) {
      // @ts-ignore
      body.append(field, emailBody[field])
    }

    const headers = {
      'Content-Type': 'multipart/form-data',
    }
    const response = await axios.post('https://yourdomain.com/wp-json/contact-form-7/v1/contact-forms/{id}/feedback', body, { headers: headers})
    // Use responseData to check its status to do some logic
    const responseData = response.data


onMounted(async () => {
   await context.$recaptcha.init()
})
onBeforeUnmount(() => {
   context.$recaptcha.destroy()
})

Upvotes: 2

Related Questions