/* https://app.emailable.com/api https://emailable.com/docs/api/#widget Test Addresses: deliverable@example.com state will be deliverable undeliverable@example.com state will be undeliverable risky@example.com state will be risky unknown@example.com state will be unknown role@example.com role will be true free@example.com free will be true accept-all@example.com accept_all will be true disposable@example.com disposable will be true slow@example.com returns a 249 status code state: deliverable, undeliverable, risky, unknown */ /* config = { key: 'emailable key', selector: 'css selector for email field(s)', defaultMessage: 'This email address appears not to be deliverable. Would you like to use it anyway?' hasJqueryValidation: whether or not the field has jQuery validation applied. This avoids using up credits to check syntactically invalid email addresses, } */ function emailable(config){ var ignoredEmails = []; var key = config.key; var selector = config.selector || 'email'; var defaultMessage = config.defaultMessage || 'This email address appears not to be deliverable. Would you like to use it anyway?'; var hasJqueryValidation = config.hasJqueryValidation || false; function testEmail(e) { if (!hasJqueryValidation || $(e.target).valid() == true) { $.post( 'https://api.emailable.com/v1/verify', { email: $(e.target).val(), api_key: key }, handleEmailableResponse(e.target) ); } }; function handleEmailableResponse(target){ return function(data) { if (isIgnored(data.email)) return; if (isDeliverable(data)) return; if (isEmailPossibleTypo(data)) { sendLuceeError('Emailable Possible Typo', JSON.stringify(data)); if (isEmailConfirmedTypo(data)) { correctTypo(data,target); } else { addEmailToIgnoreList(data.email); } } else if (isEmailConfirmedIntended(data)) { addEmailToIgnoreList(data.email); } else { highlightRejectedEmail(target); } } } function isIgnored(email){ return ignoredEmails.includes(email); } function isDeliverable(data){ return !(data.state && data.state != 'deliverable'); } function isEmailPossibleTypo(data){ return data.did_you_mean !== null && data.did_you_mean != ''; } function isEmailConfirmedTypo(data){ var TypoMessage = 'You entered: "' + data.email + '". Did you mean "' + data.did_you_mean + '"?'; return confirm(TypoMessage); } function correctTypo(data, target){ $(target).val(data.did_you_mean); } function isEmailConfirmedIntended(data){ sendLuceeError('Emailable Undeliverable Address', JSON.stringify(data)); return confirm(defaultMessage); } function addEmailToIgnoreList(email){ ignoredEmails.push(email); } function highlightRejectedEmail(target){ $(target).select(); } $(selector).change(testEmail); }function sendLuceeError(subject, data){ var parameters = { method: 'sendCurrentStateDebugEmail', subject: subject, url: window.location.href, data: data}; $.post('/cfscripts/svcs/errors.cfc', parameters); } var strFormSelector = '#frmHtmx'; var jQValidateConfig = { errorPlacement: function(error, element) { if (element.attr("type") == "radio") { error.insertBefore(element); } else if (element.attr("type") == "checkbox") { error.insertAfter($(element).next()); } else if (element.attr('name') == 'nYearsAttendedCongress') { error.appendTo($('#nYearsAttendedCongressError')); } else { error.insertAfter(element); } } } $(function(){ var config = { key: 'live_42922a3b326c26e0d7f9', selector: '#strEmail', hasJqueryValidation: true }; emailable(config); })