Google Forms
Email checker for Google Forms. Verify submitted emails with Apps Script integration.
Integreer EmailVerify met Google Forms om automatisch e-mailadressen te verifiëren wanneer reacties worden ingediend.
Integratiemethoden
| Methode | Beste voor | Complexiteit |
|---|---|---|
| Apps Script | Geautomatiseerde verificatie | Laag |
| Sheets-add-on | Handmatige verificatie | Laag |
| Zapier | No-code workflow | Laag |
Methode 1: Google Apps Script
Maak een geautomatiseerde verificatieworkflow met Google Apps Script.
Stap 1: Apps Script-project maken
- Open uw Google Form
- Klik op het ⋮ menu → Script-editor
- Dit opent de Apps Script-editor
Stap 2: Verificatiecode toevoegen
Vervang de standaardcode door:
// Configuration
const CONFIG = {
API_KEY: 'YOUR_EMAILVERIFY_API_KEY',
EMAIL_FIELD_INDEX: 1, // Adjust based on your form (0-indexed)
BLOCK_DISPOSABLE: true,
NOTIFY_ON_INVALID: true,
NOTIFICATION_EMAIL: 'admin@uwbedrijf.com',
};
/**
* Trigger function - runs when form is submitted
*/
function onFormSubmit(e) {
const response = e.response;
const email = getEmailFromResponse(response);
if (!email) {
Logger.log('No email found in response');
return;
}
// Verify email
const result = verifyEmail(email);
// Store result
storeVerificationResult(response, result);
// Handle invalid emails
if (!result.isValid) {
handleInvalidEmail(response, email, result);
}
}
/**
* Extract email from form response
*/
function getEmailFromResponse(response) {
const itemResponses = response.getItemResponses();
// Try to find email field by type
for (const itemResponse of itemResponses) {
const item = itemResponse.getItem();
const itemType = item.getType();
// Check if it's an email validation text item
if (itemType === FormApp.ItemType.TEXT) {
const textItem = item.asTextItem();
const validation = textItem.getValidation();
// If validation requires email format
if (validation) {
return itemResponse.getResponse();
}
}
}
// Fallback: use configured index
if (CONFIG.EMAIL_FIELD_INDEX < itemResponses.length) {
return itemResponses[CONFIG.EMAIL_FIELD_INDEX].getResponse();
}
return null;
}
/**
* Call EmailVerify API to verify email
*/
function verifyEmail(email) {
const url = 'https://api.emailverify.ai/v1/verify';
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + CONFIG.API_KEY,
},
payload: JSON.stringify({ email: email }),
muteHttpExceptions: true,
};
try {
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());
const isValid = data.status === 'valid' &&
!(CONFIG.BLOCK_DISPOSABLE && data.result?.disposable);
return {
email: email,
status: data.status,
score: data.score,
isDisposable: data.result?.disposable || false,
isRole: data.result?.role || false,
isValid: isValid,
raw: data,
};
} catch (error) {
Logger.log('Verification error: ' + error.message);
return {
email: email,
status: 'error',
isValid: true, // Allow on error
error: error.message,
};
}
}
/**
* Store verification result in linked spreadsheet
*/
function storeVerificationResult(response, result) {
const form = FormApp.getActiveForm();
const destinationId = form.getDestinationId();
if (!destinationId) {
Logger.log('No linked spreadsheet found');
return;
}
const spreadsheet = SpreadsheetApp.openById(destinationId);
const sheet = spreadsheet.getSheets()[0];
// Find the response row
const responseRow = findResponseRow(sheet, response);
if (responseRow === -1) {
Logger.log('Could not find response row');
return;
}
// Add verification columns if they don't exist
ensureVerificationColumns(sheet);
// Get column indices
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const statusCol = headers.indexOf('Email Status') + 1;
const scoreCol = headers.indexOf('Email Score') + 1;
const disposableCol = headers.indexOf('Is Disposable') + 1;
// Update row
if (statusCol > 0) {
sheet.getRange(responseRow, statusCol).setValue(result.status);
}
if (scoreCol > 0 && result.score !== undefined) {
sheet.getRange(responseRow, scoreCol).setValue(result.score);
}
if (disposableCol > 0) {
sheet.getRange(responseRow, disposableCol).setValue(result.isDisposable ? 'Yes' : 'No');
}
// Apply conditional formatting
if (result.status === 'invalid' || result.isDisposable) {
sheet.getRange(responseRow, 1, 1, sheet.getLastColumn())
.setBackground('#ffcccb');
}
}
/**
* Find the row number for a response
*/
function findResponseRow(sheet, response) {
const timestamp = response.getTimestamp();
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
const rowTimestamp = data[i][0];
if (rowTimestamp instanceof Date &&
Math.abs(rowTimestamp.getTime() - timestamp.getTime()) < 5000) {
return i + 1; // 1-indexed
}
}
return -1;
}
/**
* Add verification columns to spreadsheet
*/
function ensureVerificationColumns(sheet) {
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const columnsToAdd = ['Email Status', 'Email Score', 'Is Disposable'];
for (const column of columnsToAdd) {
if (!headers.includes(column)) {
const newCol = sheet.getLastColumn() + 1;
sheet.getRange(1, newCol).setValue(column);
}
}
}
/**
* Handle invalid email submissions
*/
function handleInvalidEmail(response, email, result) {
if (!CONFIG.NOTIFY_ON_INVALID) {
return;
}
const form = FormApp.getActiveForm();
const formTitle = form.getTitle();
const subject = `[${formTitle}] Ongeldige e-mailinzending`;
const body = `
Een ongeldige e-mail is ingediend via uw formulier.
Formulier: ${formTitle}
E-mail: ${email}
Status: ${result.status}
${result.isDisposable ? 'Opmerking: Wegwerp-e-mail gedetecteerd' : ''}
Score: ${result.score || 'N/A'}
Tijdstempel: ${response.getTimestamp()}
`.trim();
MailApp.sendEmail({
to: CONFIG.NOTIFICATION_EMAIL,
subject: subject,
body: body,
});
}
/**
* Set up form submit trigger
* Run this function once to install the trigger
*/
function installTrigger() {
const form = FormApp.getActiveForm();
// Remove existing triggers
const triggers = ScriptApp.getUserTriggers(form);
for (const trigger of triggers) {
if (trigger.getHandlerFunction() === 'onFormSubmit') {
ScriptApp.deleteTrigger(trigger);
}
}
// Install new trigger
ScriptApp.newTrigger('onFormSubmit')
.forForm(form)
.onFormSubmit()
.create();
Logger.log('Trigger installed successfully');
}
/**
* Test verification (run manually)
*/
function testVerification() {
const result = verifyEmail('test@example.com');
Logger.log(JSON.stringify(result, null, 2));
}Stap 3: Trigger installeren
- Selecteer in de Apps Script-editor
installTriggeruit het functie-dropdown - Klik op Run
- Verleen de vereiste machtigingen wanneer gevraagd
Stap 4: Integratie testen
- Dien een testreactie in bij uw formulier
- Controleer de gekoppelde spreadsheet voor verificatieresultaten
- Bekijk Apps Script-logs: Executions in de linkerzijbalk
Methode 2: Spreadsheet-add-on
Verifieer e-mails rechtstreeks in Google Sheets met een aangepaste zijbalk.
Add-on-code maken
// Code.gs
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('EmailVerify')
.addItem('Verify Selected Emails', 'verifySelected')
.addItem('Verify All Emails', 'verifyAll')
.addItem('Settings', 'showSettings')
.addToUi();
}
function verifySelected() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getActiveRange();
const values = range.getValues();
const results = [];
for (let i = 0; i < values.length; i++) {
const email = values[i][0];
if (!email || !isValidEmailFormat(email)) {
results.push(['Invalid format']);
continue;
}
const result = verifyEmail(email);
results.push([result.status + (result.isDisposable ? ' (disposable)' : '')]);
}
// Write results to next column
const startCol = range.getColumn() + range.getNumColumns();
sheet.getRange(range.getRow(), startCol, results.length, 1).setValues(results);
}
function verifyAll() {
const sheet = SpreadsheetApp.getActiveSheet();
const ui = SpreadsheetApp.getUi();
// Ask for email column
const response = ui.prompt(
'Verify All Emails',
'Enter the column letter containing emails (e.g., B):',
ui.ButtonSet.OK_CANCEL
);
if (response.getSelectedButton() !== ui.Button.OK) {
return;
}
const column = response.getResponseText().toUpperCase();
const colIndex = column.charCodeAt(0) - 64; // A=1, B=2, etc.
const lastRow = sheet.getLastRow();
const emailRange = sheet.getRange(2, colIndex, lastRow - 1, 1);
const emails = emailRange.getValues().flat().filter(e => e);
ui.alert(`Starting verification of ${emails.length} emails...`);
// Verify in batches
const batchSize = 50;
let processed = 0;
for (let i = 0; i < emails.length; i += batchSize) {
const batch = emails.slice(i, i + batchSize);
for (let j = 0; j < batch.length; j++) {
const email = batch[j];
const rowIndex = i + j + 2; // +2 for header and 0-index
if (!isValidEmailFormat(email)) {
sheet.getRange(rowIndex, colIndex + 1).setValue('Invalid format');
continue;
}
const result = verifyEmail(email);
// Write status
sheet.getRange(rowIndex, colIndex + 1).setValue(result.status);
// Write score
if (result.score !== undefined) {
sheet.getRange(rowIndex, colIndex + 2).setValue(result.score);
}
// Highlight invalid
if (result.status === 'invalid' || result.isDisposable) {
sheet.getRange(rowIndex, 1, 1, sheet.getLastColumn()).setBackground('#ffcccb');
}
}
processed += batch.length;
SpreadsheetApp.flush();
// Avoid rate limits
if (i + batchSize < emails.length) {
Utilities.sleep(1000);
}
}
ui.alert(`Verification complete! Processed ${processed} emails.`);
}
function isValidEmailFormat(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function showSettings() {
const html = HtmlService.createHtmlOutputFromFile('Settings')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(html, 'EmailVerify Settings');
}
function saveSettings(apiKey) {
PropertiesService.getUserProperties().setProperty('EMAILVERIFY_API_KEY', apiKey);
return { success: true };
}
function getApiKey() {
return PropertiesService.getUserProperties().getProperty('EMAILVERIFY_API_KEY') || '';
}Instellingen HTML
<!-- Settings.html -->
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"] {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
button {
background-color: #4285f4;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #357abd;
}
.success {
color: #28a745;
margin-top: 10px;
}
</style>
</head>
<body>
<div class="form-group">
<label for="apiKey">EmailVerify API Key</label>
<input type="text" id="apiKey" placeholder="bv_live_xxx" />
</div>
<button onclick="saveSettings()">Instellingen opslaan</button>
<div id="message" class="success" style="display: none;"></div>
<script>
// Load existing settings
google.script.run.withSuccessHandler(function(apiKey) {
document.getElementById('apiKey').value = apiKey;
}).getApiKey();
function saveSettings() {
const apiKey = document.getElementById('apiKey').value;
google.script.run.withSuccessHandler(function(result) {
if (result.success) {
document.getElementById('message').textContent = 'Instellingen opgeslagen!';
document.getElementById('message').style.display = 'block';
setTimeout(function() {
google.script.host.close();
}, 1500);
}
}).saveSettings(apiKey);
}
</script>
</body>
</html>Methode 3: Zapier-integratie
Verbind Google Forms met EmailVerify via Zapier.
Zap-setup
- Trigger: Google Forms → New Response in Spreadsheet
- Actie 1: Webhooks by Zapier → POST naar EmailVerify
- Actie 2: Google Sheets → Update Spreadsheet Row
Webhook-configuratie
URL: https://api.emailverify.ai/v1/verify
Method: POST
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Data:
{
"email": "{{email_field_value}}"
}Rij bijwerken
Map het verificatieresultaat terug naar uw spreadsheet:
- Kolom: Email Status →
{{status}} - Kolom: Email Score →
{{score}} - Kolom: Is Disposable →
{{result__disposable}}
Bulk-verificatiescript
Voor het verifiëren van grote bestaande datasets:
/**
* Bulk verify emails from a column
* Processes in batches with progress tracking
*/
function bulkVerifyEmails() {
const sheet = SpreadsheetApp.getActiveSheet();
const ui = SpreadsheetApp.getUi();
// Configuration
const EMAIL_COL = 2; // Column B (1-indexed)
const STATUS_COL = 3; // Column C for status
const SCORE_COL = 4; // Column D for score
const START_ROW = 2; // Skip header
const BATCH_SIZE = 100;
const lastRow = sheet.getLastRow();
const totalEmails = lastRow - START_ROW + 1;
const proceed = ui.alert(
'Bulk Verification',
`This will verify ${totalEmails} emails. Continue?`,
ui.ButtonSet.YES_NO
);
if (proceed !== ui.Button.YES) {
return;
}
// Get all emails
const emailRange = sheet.getRange(START_ROW, EMAIL_COL, totalEmails, 1);
const emails = emailRange.getValues().flat();
// Get API key
const apiKey = PropertiesService.getUserProperties().getProperty('EMAILVERIFY_API_KEY');
if (!apiKey) {
ui.alert('Please configure your API key in Settings first.');
return;
}
// Process in batches
let processed = 0;
const stats = { valid: 0, invalid: 0, disposable: 0, errors: 0 };
for (let i = 0; i < emails.length; i++) {
const email = emails[i];
const row = START_ROW + i;
// Skip if already verified
const existingStatus = sheet.getRange(row, STATUS_COL).getValue();
if (existingStatus) {
processed++;
continue;
}
if (!email || !isValidEmailFormat(email)) {
sheet.getRange(row, STATUS_COL).setValue('invalid_format');
stats.errors++;
processed++;
continue;
}
// Verify
const result = verifyEmailWithKey(email, apiKey);
// Write results
sheet.getRange(row, STATUS_COL).setValue(result.status);
if (result.score !== undefined) {
sheet.getRange(row, SCORE_COL).setValue(result.score);
}
// Update stats
if (result.status === 'valid') stats.valid++;
else if (result.status === 'invalid') stats.invalid++;
if (result.isDisposable) stats.disposable++;
if (result.error) stats.errors++;
// Highlight invalid rows
if (result.status === 'invalid' || result.isDisposable) {
sheet.getRange(row, 1, 1, sheet.getLastColumn()).setBackground('#ffcccb');
}
processed++;
// Progress update every 50 emails
if (processed % 50 === 0) {
SpreadsheetApp.flush();
Logger.log(`Progress: ${processed}/${totalEmails}`);
}
// Rate limiting
Utilities.sleep(100);
}
// Final stats
const message = `
Verificatie voltooid!
Totaal: ${processed}
Geldig: ${stats.valid}
Ongeldig: ${stats.invalid}
Wegwerp: ${stats.disposable}
Fouten: ${stats.errors}
`.trim();
ui.alert('Resultaten', message, ui.ButtonSet.OK);
}
function verifyEmailWithKey(email, apiKey) {
const url = 'https://api.emailverify.ai/v1/verify';
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bearer ' + apiKey,
},
payload: JSON.stringify({ email: email }),
muteHttpExceptions: true,
};
try {
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());
return {
status: data.status,
score: data.score,
isDisposable: data.result?.disposable || false,
};
} catch (error) {
return {
status: 'error',
error: error.message,
};
}
}Voorwaardelijke e-mailnotificaties
Verstuur verschillende e-mails op basis van verificatieresultaten:
/**
* Send confirmation email only to verified addresses
*/
function sendConditionalConfirmation(e) {
const response = e.response;
const email = getEmailFromResponse(response);
if (!email) return;
// Verify email first
const result = verifyEmail(email);
if (!result.isValid) {
// Send admin notification instead
notifyAdminOfInvalidSubmission(response, email, result);
return;
}
// Send confirmation to valid email
const formTitle = FormApp.getActiveForm().getTitle();
MailApp.sendEmail({
to: email,
subject: `Bedankt voor uw inzending bij ${formTitle}`,
htmlBody: `
<h2>Bedankt!</h2>
<p>We hebben uw inzending ontvangen en nemen binnenkort contact met u op.</p>
<p>Met vriendelijke groet,<br>Het Team</p>
`,
});
}
function notifyAdminOfInvalidSubmission(response, email, result) {
const formTitle = FormApp.getActiveForm().getTitle();
MailApp.sendEmail({
to: CONFIG.NOTIFICATION_EMAIL,
subject: `[Waarschuwing] Ongeldige e-mailinzending - ${formTitle}`,
body: `
Een inzending met een ongeldig e-mailadres is ontvangen.
E-mail: ${email}
Status: ${result.status}
Wegwerp: ${result.isDisposable}
Bekijk de inzending in uw spreadsheet.
`,
});
}Best practices
1. Bewaar API-sleutel veilig
// Use Properties Service instead of hardcoding
const apiKey = PropertiesService.getScriptProperties().getProperty('API_KEY');2. Behandel rate limits
function verifyWithRetry(email, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const result = verifyEmail(email);
if (result.status !== 'error' || !result.error.includes('rate')) {
return result;
}
// Wait and retry
Utilities.sleep(2000 * (i + 1));
}
return { status: 'error', error: 'Max retries exceeded' };
}3. Graceful foutafhandeling
// Never block form submissions on API errors
if (result.error) {
Logger.log('Verification failed, allowing submission');
return; // Don't block the submission
}