Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,54 @@ Note: The keys of the `data` object should match with the fields that are set us

Article: https://devapt.com/formspree-alternative-formeasy

## Captcha validation

FormEasy supports multiple captcha providers to allow you to prevent unverified submissions by robots. Each provider is unique and requires a unique configuration. Please refer to the documentation below to enable a specific captcha provider.

### Google reCAPTCHA V2

1. Register a site and get your secret key, and site key: [https://www.google.com/recaptcha/admin/create](https://www.google.com/recaptcha/admin/create)

2. In your apps script file, inside function `doPost`, add the following configuration:

```js
function doPost(req) {
// ...
FormEasy.setRecaptcha('YOUR_SECRET_KEY'); // To validate reCAPTCHA
// ...
return FormEasy.action(req); // Mandatory to return action method
}
```

3. On your website, add the reCAPTCHA library at the end of the `<head>` tag:

```html
<head>
<!-- ... -->

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
```

4. Add reCAPTCHA input into your form:

```html
<div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
```

5. You should see `I am not a robot` box on your site. If you don't, please refer to [reCAPTCHA Docs](https://developers.google.com/recaptcha/docs/display) for debugging.

6. Inside your `fetch()` method, add a reCAPTCHA response from the input:

```js
const data = {
// ...
'g-recaptcha-response': document.getElementById('g-recaptcha-response').value,
};

// ...
```

## Video instructions

To see all the above instructions lively, check this demo video below.
Expand Down
50 changes: 49 additions & 1 deletion src/Code.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ let emailSubject = 'New submission using FormEasy';
let formHeading = 'Form submission - FormEasy';
let email = '';
let fields = [];
let captcha = null;

/**
* @param {String} name Name of the sheet to log the data
Expand Down Expand Up @@ -69,6 +70,15 @@ function setFields(...fieldsArr) {
}
}

/**
* Google reCAPTCHA V2 implementation
*
* @param {String} secretKey Private key of reCAPTCHA site
*/
function setRecaptcha(secretKey) {
captcha = { type: 'recaptcha_v2', data: { secretKey } };
}

/**
* @param {Object} req POST request object
* @return {Object} response to the POST request
Expand All @@ -89,6 +99,44 @@ function action(req) {
return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

if (captcha) {
switch (captcha.type) {
case 'recaptcha_v2':
const siteKey = jsonData['g-recaptcha-response'];

if (!siteKey) {
response = {
status: 'error',
message: 'reCAPTCHA verification under key \'g-recaptcha-response\' is required.',
};
return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

const captchaResponse = UrlFetchApp.fetch('https://www.google.com/recaptcha/api/siteverify', {
'method': 'post',
'payload': {
'response': siteKey,
'secret': captcha.data.secretKey
}
});

const captchaJson = JSON.parse(captchaResponse.getContentText());

if (!captchaJson.success) {
response = {
status: 'error',
message: 'Please tick the box to verify you are not a robot.',
};

return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

break;
default:
// Captcha not enabled
}
}

let logSheet;

const allSheets = SpreadsheetApp.getActiveSpreadsheet()
Expand Down Expand Up @@ -155,4 +203,4 @@ function action(req) {
};

return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}
}