Checking if an email is valid in Google Apps Script
Asked Answered
T

4

8

I'm using the built-in api for scripting against Google Spreadsheets to send some booking confirmations, and currently my script breaks if someone has filled in an invalid email. I'd like it to just save some data to a list of guests that haven't been notified, and then proceed with looping through the bookings.

This is my current code (simplified):

// The variables email, subject and msg are populated.
// I've tested that using Browser.msgBox(), and the correct column values are
// found and used

// The script breaks here, if an incorrect email address has been filled in
MailApp.sendEmail(email, subject, msg)

According to the documentation the only two methods on the MailApp class are to send emails and check the daily quota - nothing about checking for valid email addresses - so I don't really know what criteria must be fulfilled for the class to accept the request, and thus can't write a validation routine.

Tiki answered 24/10, 2010 at 16:19 Comment(4)
How about using a simple e-mail validation regex? \b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\bExudation
@Ravi: I could do something like that, but since the API call breaks on an invalid address, I would very much like to know exactly what criterion the email has to fulfill, and be able to verify that on beforehand...Tiki
Hmm..so does sendEmail throw some specific exception if its an invalid e-mail?Exudation
This Wiki page seems to address this question quite exhaustively. If sendMail fails on any of the 'legally' allowed formats then that should be reported as a feature request. EDIT: You could also do a try-catch around it and store the email address that caused an error.Revet
C
6

Stay calm, catch and log the exception and carry on:

try {
  // do stuff, including send email
  MailApp.sendEmail(email, subject, msg)
} catch(e) {
  Logger.log("Error with email (" + email + "). " + e);
}
Cassareep answered 18/5, 2012 at 2:5 Comment(6)
This problem is now way old - all the emails I needed to send with that application have already been sent. But if I have to do this again, this is definitely how I'll do it.Tiki
I think you can't specify the Type of Exception to catch in JavaScriptColettacolette
What kind of exception does this cause? If you send too many emails to invalid emails, you'll be banned.Lehmann
Problem with this is that other exceptions like Service invoked too many times for one day: email. get classified as a bad formatted email address.Lehmann
Here are some of the exceptions I caught: Failed to send email: no recipient and Invalid email: abc@abc Also, to avoid quota overload, you can use MailApp.getRemainingDailyQuota()Obsequious
Sometimes the script hangs on Logger.log — any ideas why?Prefabricate
V
14

If you need to validate email addresses beforehand, create a blank spreadsheet in your drive. Then, run the function below, changing the testSheet variable to point to the spreadsheet you created. The function will do a simple regex test to catch malformed addresses, then check if the address is actually valid by attempting to temporarily add it as a viewer on the spreadsheet. If the address can be added, it must be valid.

function validateEmail(email) {
  var re = /\S+@\S+\.\S+/;
  if (!re.test(email)) {
    return false;
  } else {
    var testSheet = SpreadsheetApp.openById(arbitrarySpreadsheetInYourDrive);
    try {
      testSheet.addViewer(email);
    } catch(e) {
      return false;
    }
    testSheet.removeViewer(email);
    return true;
  }
}

regex from How to validate email address in JavaScript?

Verrazano answered 5/10, 2017 at 15:37 Comment(2)
I was thinking of using a similar solution, but I was using the drive service DriveApp instead of the spreadsheet service SpreadhseetApp and using DriveApp service resulted in a notification email being sent to the viewer. However, after looking at this answer, I found out that the SpreadsheetApp does not send the email notification. Good answer!Unpeg
You could also create a temporary Spreadsheet, then trash it, rather than leaving a Spreadsheet in Drive just for this purpose.Parenteau
C
6

Stay calm, catch and log the exception and carry on:

try {
  // do stuff, including send email
  MailApp.sendEmail(email, subject, msg)
} catch(e) {
  Logger.log("Error with email (" + email + "). " + e);
}
Cassareep answered 18/5, 2012 at 2:5 Comment(6)
This problem is now way old - all the emails I needed to send with that application have already been sent. But if I have to do this again, this is definitely how I'll do it.Tiki
I think you can't specify the Type of Exception to catch in JavaScriptColettacolette
What kind of exception does this cause? If you send too many emails to invalid emails, you'll be banned.Lehmann
Problem with this is that other exceptions like Service invoked too many times for one day: email. get classified as a bad formatted email address.Lehmann
Here are some of the exceptions I caught: Failed to send email: no recipient and Invalid email: abc@abc Also, to avoid quota overload, you can use MailApp.getRemainingDailyQuota()Obsequious
Sometimes the script hangs on Logger.log — any ideas why?Prefabricate
E
0

On the otherhand, avoid Checking email in script and get rid of loses quota or try-catch etc. I used that I got a valid email when user attempt to send an email, by signing him in an email and got that email:

private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
    try {
        GoogleSignInAccount account = completedTask.getResult(ApiException.class);

       String s = account.getEmail(); // here is the valid email.
                       
    } catch (ApiException e) {
        // The ApiException status code indicates the detailed failure reason.
        // Please refer to the GoogleSignInStatusCodes class reference for more information.
        Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
       
    }
}

Full procedure Here.

Eldrida answered 18/12, 2020 at 19:11 Comment(0)
U
0

This answer is much later than this question was asked, but I piggy-backed off of remitnotpaucity's answer based on a comment in his answer. It does basically the same thing, adding the email to the spreadsheet and catching the error, however in my case it creates a new spreadsheet, attempts to add the user, and then after attempting to add the user, deletes the spreadsheet. In both cases, that the email is a valid email or not, it deletes the newly created spreadsheet.

Some things to note:

  1. I am not as familiar with regular expressions, so I only check to see if the @ symbol is within the email read into the function, and do not check for whitespaces.
  2. I believe that even if it passes the first if-statement, even if it's not a valid email, an error will still be thrown and caught because Google will still catch that it's not a valid email, making the first if-statement redundant
  3. If you are trying to validate an email outside your company, I'm unsure how it would react, so be fore-warned about that
  4. This validation method takes a few seconds because you are creating and then deleting an email all within a single function, so it takes a fair bit longer than remitnotpaucity's
  5. Most importantly, if you are able to, I would use an API. I believe that this one would work perfectly fine and should be free, it just may take some extra elbow-grease to get to work with GAS.
function validateEmail(email){
    let ss = SpreadsheetApp.openByUrl(SpreadsheetApp.create('Email Validation Spreadsheet', 1, 1).getUrl())
    if(!new RegExp('[@]').test(email)){
      return false
    } else{
      try{
        ss.addViewer(email)
      } catch(e){
        setTrashed()
        return false
      }
      setTrashed()
      return true
    }
    function setTrashed(){
      DriveApp.getFilesByName('Email Validation Spreadsheet').next().setTrashed(true)
    }
  }
Underbid answered 11/2, 2023 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.