Google Forms
Email checker for Google Forms. Verify submitted emails with Apps Script integration.
Google Forms に EmailVerify を統合し、回答が送信されたときに自動的にメールアドレスを検証しましょう。
連携方法
| 方法 | 最適な用途 | 複雑さ |
|---|---|---|
| Apps Script | 自動検証 | 低 |
| Sheets アドオン | 手動検証 | 低 |
| Zapier | ノーコードワークフロー | 低 |
方法 1:Google Apps Script
Google Apps Script を使用して自動検証ワークフローを作成します。
ステップ 1:Apps Script プロジェクトを作成
- Google Form を開く
- ⋮ メニュー → スクリプト エディタ をクリック
- Apps Script エディタが開きます
ステップ 2:検証コードを追加
デフォルトのコードを以下に置き換えます:
// 設定
const CONFIG = {
API_KEY: 'YOUR_EMAILVERIFY_API_KEY',
EMAIL_FIELD_INDEX: 1, // フォームに応じて調整(0 始まり)
BLOCK_DISPOSABLE: true,
NOTIFY_ON_INVALID: true,
NOTIFICATION_EMAIL: 'admin@yourcompany.com',
};
/**
* トリガー関数 - フォーム送信時に実行
*/
function onFormSubmit(e) {
const response = e.response;
const email = getEmailFromResponse(response);
if (!email) {
Logger.log('回答にメールが見つかりません');
return;
}
// メールを検証
const result = verifyEmail(email);
// 結果を保存
storeVerificationResult(response, result);
// 無効なメールを処理
if (!result.isValid) {
handleInvalidEmail(response, email, result);
}
}
/**
* フォーム回答からメールを抽出
*/
function getEmailFromResponse(response) {
const itemResponses = response.getItemResponses();
// メールフィールドをタイプで検索
for (const itemResponse of itemResponses) {
const item = itemResponse.getItem();
const itemType = item.getType();
// メール検証のテキストアイテムかチェック
if (itemType === FormApp.ItemType.TEXT) {
const textItem = item.asTextItem();
const validation = textItem.getValidation();
// メール形式が必須の場合
if (validation) {
return itemResponse.getResponse();
}
}
}
// フォールバック:設定されたインデックスを使用
if (CONFIG.EMAIL_FIELD_INDEX < itemResponses.length) {
return itemResponses[CONFIG.EMAIL_FIELD_INDEX].getResponse();
}
return null;
}
/**
* EmailVerify API を呼び出してメールを検証
*/
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('検証エラー: ' + error.message);
return {
email: email,
status: 'error',
isValid: true, // エラー時は許可
error: error.message,
};
}
}
/**
* 検証結果をリンクされたスプレッドシートに保存
*/
function storeVerificationResult(response, result) {
const form = FormApp.getActiveForm();
const destinationId = form.getDestinationId();
if (!destinationId) {
Logger.log('リンクされたスプレッドシートがありません');
return;
}
const spreadsheet = SpreadsheetApp.openById(destinationId);
const sheet = spreadsheet.getSheets()[0];
// 回答の行を見つける
const responseRow = findResponseRow(sheet, response);
if (responseRow === -1) {
Logger.log('回答の行が見つかりません');
return;
}
// 検証列を追加(存在しない場合)
ensureVerificationColumns(sheet);
// 列インデックスを取得
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const statusCol = headers.indexOf('メールステータス') + 1;
const scoreCol = headers.indexOf('メールスコア') + 1;
const disposableCol = headers.indexOf('使い捨て') + 1;
// 行を更新
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 ? 'はい' : 'いいえ');
}
// 条件付き書式を適用
if (result.status === 'invalid' || result.isDisposable) {
sheet.getRange(responseRow, 1, 1, sheet.getLastColumn())
.setBackground('#ffcccb');
}
}
/**
* 回答の行番号を見つける
*/
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 始まり
}
}
return -1;
}
/**
* スプレッドシートに検証列を追加
*/
function ensureVerificationColumns(sheet) {
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const columnsToAdd = ['メールステータス', 'メールスコア', '使い捨て'];
for (const column of columnsToAdd) {
if (!headers.includes(column)) {
const newCol = sheet.getLastColumn() + 1;
sheet.getRange(1, newCol).setValue(column);
}
}
}
/**
* 無効なメール送信を処理
*/
function handleInvalidEmail(response, email, result) {
if (!CONFIG.NOTIFY_ON_INVALID) {
return;
}
const form = FormApp.getActiveForm();
const formTitle = form.getTitle();
const subject = `[${formTitle}] 無効なメール送信`;
const body = `
フォームに無効なメールが送信されました。
フォーム: ${formTitle}
メール: ${email}
ステータス: ${result.status}
${result.isDisposable ? '注意: 使い捨てメールを検出' : ''}
スコア: ${result.score || 'N/A'}
タイムスタンプ: ${response.getTimestamp()}
`.trim();
MailApp.sendEmail({
to: CONFIG.NOTIFICATION_EMAIL,
subject: subject,
body: body,
});
}
/**
* フォーム送信トリガーをセットアップ
* トリガーをインストールするにはこの関数を一度実行
*/
function installTrigger() {
const form = FormApp.getActiveForm();
// 既存のトリガーを削除
const triggers = ScriptApp.getUserTriggers(form);
for (const trigger of triggers) {
if (trigger.getHandlerFunction() === 'onFormSubmit') {
ScriptApp.deleteTrigger(trigger);
}
}
// 新しいトリガーをインストール
ScriptApp.newTrigger('onFormSubmit')
.forForm(form)
.onFormSubmit()
.create();
Logger.log('トリガーが正常にインストールされました');
}
/**
* 検証テスト(手動実行)
*/
function testVerification() {
const result = verifyEmail('test@example.com');
Logger.log(JSON.stringify(result, null, 2));
}ステップ 3:トリガーをインストール
- Apps Script エディタで、関数ドロップダウンから
installTriggerを選択 - 実行 をクリック
- プロンプトが表示されたら必要な権限を付与
ステップ 4:連携をテスト
- フォームにテスト回答を送信
- リンクされたスプレッドシートで検証結果を確認
- Apps Script ログを確認:左サイドバーの 実行
方法 2:スプレッドシートアドオン
カスタムサイドバーで Google Sheets からメールを直接検証します。
アドオンコードの作成
// Code.gs
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('EmailVerify')
.addItem('選択したメールを検証', 'verifySelected')
.addItem('すべてのメールを検証', 'verifyAll')
.addItem('設定', '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(['無効な形式']);
continue;
}
const result = verifyEmail(email);
results.push([result.status + (result.isDisposable ? ' (使い捨て)' : '')]);
}
// 結果を次の列に書き込む
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();
// メール列を尋ねる
const response = ui.prompt(
'すべてのメールを検証',
'メールが含まれる列の文字を入力してください(例: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, など
const lastRow = sheet.getLastRow();
const emailRange = sheet.getRange(2, colIndex, lastRow - 1, 1);
const emails = emailRange.getValues().flat().filter(e => e);
ui.alert(`${emails.length} 件のメールの検証を開始します...`);
// バッチで検証
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('無効な形式');
continue;
}
const result = verifyEmail(email);
// ステータスを書き込む
sheet.getRange(rowIndex, colIndex + 1).setValue(result.status);
// スコアを書き込む
if (result.score !== undefined) {
sheet.getRange(rowIndex, colIndex + 2).setValue(result.score);
}
// 無効なものをハイライト
if (result.status === 'invalid' || result.isDisposable) {
sheet.getRange(rowIndex, 1, 1, sheet.getLastColumn()).setBackground('#ffcccb');
}
}
processed += batch.length;
SpreadsheetApp.flush();
// レート制限を避ける
if (i + batchSize < emails.length) {
Utilities.sleep(1000);
}
}
ui.alert(`検証完了!${processed} 件のメールを処理しました。`);
}
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 設定');
}
function saveSettings(apiKey) {
PropertiesService.getUserProperties().setProperty('EMAILVERIFY_API_KEY', apiKey);
return { success: true };
}
function getApiKey() {
return PropertiesService.getUserProperties().getProperty('EMAILVERIFY_API_KEY') || '';
}設定 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 キー</label>
<input type="text" id="apiKey" placeholder="bv_live_xxx" />
</div>
<button onclick="saveSettings()">設定を保存</button>
<div id="message" class="success" style="display: none;"></div>
<script>
// 既存の設定を読み込む
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 = '設定を保存しました!';
document.getElementById('message').style.display = 'block';
setTimeout(function() {
google.script.host.close();
}, 1500);
}
}).saveSettings(apiKey);
}
</script>
</body>
</html>方法 3:Zapier 連携
Zapier を使用して Google Forms を EmailVerify に接続します。
Zap のセットアップ
- トリガー:Google Forms → New Response in Spreadsheet
- アクション 1:Webhooks by Zapier → POST to EmailVerify
- アクション 2:Google Sheets → Update Spreadsheet Row
Webhook の設定
URL: https://api.emailverify.ai/v1/verify
Method: POST
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Data:
{
"email": "{{email_field_value}}"
}行の更新
検証結果をスプレッドシートにマッピング:
- 列:メールステータス →
{{status}} - 列:メールスコア →
{{score}} - 列:使い捨て →
{{result__disposable}}
ベストプラクティス
1. API キーを安全に保管
// ハードコードの代わりに Properties Service を使用
const apiKey = PropertiesService.getScriptProperties().getProperty('API_KEY');2. レート制限を処理
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;
}
// 待機して再試行
Utilities.sleep(2000 * (i + 1));
}
return { status: 'error', error: 'Max retries exceeded' };
}3. 適切なエラーハンドリング
// API エラー時はフォーム送信をブロックしない
if (result.error) {
Logger.log('検証に失敗、送信を許可');
return; // 送信をブロックしない
}