Answers.Body: <p>Upgrading to the latest versions will likely resolve any issues with the default implementation. There was a bug in the timing of our javascript that was resolved in <a href="https://github.com/barrelstrength/sprout-forms/blob/v3/CHANGELOG.md#31320---2023-03-17" rel="nofollow noreferrer">3.13.20</a>.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-05T12:31:14.953Z
Answers.LastActivityDate: 2023-11-05T12:31:14.953Z
Answers.UserDisplayName: Ben Parizek
Body: <p>I'm using Sprout Forms V3 on Craft 3. I'm trying to handle the submit within a controller.
  This choice is made to add a custom logic, to implement a Google reCAPTCHA (as the official Sprout's plugin isn't working).</p>
  <p>This is the JS part:</p>
  <pre><code>grecaptcha.ready(function() {
      // Verify reCAPTCHA
      grecaptcha.execute(recaptchaSiteKey, { action: 'contactForm' }).then(function(token) {
          // Send the token to the server for verification
          var data = {
              token: token,
              action: 'contactForm',
              formData: $form.serialize()
          };
          data[csrfTokenName] = csrfTokenValue;
          fetch('/actions/utilities-module/captcha', {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify(data),
          })
          .then(data =&gt; {
              console.log(data);
              if (data === true) {
                  console.log('success');
              } else {
                  console.log('error');
              }
          });
      });
  });
  </code></pre>
  <p>and the controller part:</p>
  <pre><code>public function actionIndex()
  {
      // Check CSRF
      $this-&gt;requirePostRequest();
  
      // Call cURL to POST request
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL,&quot;https://www.google.com/recaptcha/api/siteverify&quot;);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
          'secret' =&gt; getenv('GOOGLE_RECAPTCHA_SECRET_KEY'),
          'response' =&gt; Craft::$app-&gt;getRequest()-&gt;getParam('token')
      )));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $response = curl_exec($ch);
      curl_close($ch);
      $response = json_decode($response, true);
  
      // Verify the response 
      if ($response[&quot;success&quot;] &amp;&amp; $response[&quot;action&quot;] == 'contactForm' &amp;&amp; $response[&quot;score&quot;] &gt;= 0.9) {
  
          // Process the form
          $formData = Craft::$app-&gt;getRequest()-&gt;getParam('formData');
          $response = Craft::$app-&gt;runAction('sprout-forms/entries/save-entry', [
              'handle' =&gt; 'contact',
              'submission' =&gt; $formData
          ]);
  
          if (!$response['success']) {
              return $this-&gt;asJson(false);
          }
  
          return $this-&gt;asJson(true);
  
      } else {
          return $this-&gt;asJson(false);
      }
  }
  </code></pre>
  <p>The issue here is that it's always failing. Looks like the <code>Craft::$app-&gt;runAction()</code> is missing something to process.</p>
  <p>Any idea what's wrong?</p>
  
Tags: <plugin-sproutforms><controller><plugin-recaptcha><sprout>
Title: How to run Sprout Forms action from a controller to implement Google reCAPTCHA?
ThreadText: # How to run Sprout Forms action from a controller to implement Google reCAPTCHA?
  
  (Asked by: username_0 on 2023-08-18)
  
  I'm using Sprout Forms V3 on Craft 3. I'm trying to handle the submit within a controller.
  This choice is made to add a custom logic, to implement a Google reCAPTCHA (as the official Sprout's plugin isn't working).
  
  This is the JS part:
  
  ```
  grecaptcha.ready(function() {
      // Verify reCAPTCHA
      grecaptcha.execute(recaptchaSiteKey, { action: 'contactForm' }).then(function(token) {
          // Send the token to the server for verification
          var data = {
              token: token,
              action: 'contactForm',
              formData: $form.serialize()
          };
          data[csrfTokenName] = csrfTokenValue;
          fetch('/actions/utilities-module/captcha', {
              method: 'POST',
              headers: {
                  'Content-Type': 'application/json',
              },
              body: JSON.stringify(data),
          })
          .then(data => {
              console.log(data);
              if (data === true) {
                  console.log('success');
              } else {
                  console.log('error');
              }
          });
      });
  });
  
  ```
  
  and the controller part:
  
  ```
  public function actionIndex()
  {
      // Check CSRF
      $this->requirePostRequest();
  
      // Call cURL to POST request
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
          'secret' => getenv('GOOGLE_RECAPTCHA_SECRET_KEY'),
          'response' => Craft::$app->getRequest()->getParam('token')
      )));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $response = curl_exec($ch);
      curl_close($ch);
      $response = json_decode($response, true);
  
      // Verify the response 
      if ($response["success"] && $response["action"] == 'contactForm' && $response["score"] >= 0.9) {
  
          // Process the form
          $formData = Craft::$app->getRequest()->getParam('formData');
          $response = Craft::$app->runAction('sprout-forms/entries/save-entry', [
              'handle' => 'contact',
              'submission' => $formData
          ]);
  
          if (!$response['success']) {
              return $this->asJson(false);
          }
  
          return $this->asJson(true);
  
      } else {
          return $this->asJson(false);
      }
  }
  
  ```
  
  The issue here is that it's always failing. Looks like the `Craft::$app->runAction()` is missing something to process.
  
  Any idea what's wrong?
  
  **Tags:** plugin-sproutforms, controller, plugin-recaptcha, sprout
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-11-05. Score: 2
  
  Upgrading to the latest versions will likely resolve any issues with the default implementation. There was a bug in the timing of our javascript that was resolved in [3.13.20](https://github.com/barrelstrength/sprout-forms/blob/v3/CHANGELOG.md#31320---2023-03-17).
  
  
  ---
  
  