I am working on a web app that requires me to check if the users email are valid and exists. (I do the regex check) The question is what is best practice of verifying that an email exists?
Here are some options that I have though about:
send an email to the user and make them confirm the email address
do a VRFY SMTP - is this still used? should i bother looking into it?
any other good idea?
sending a verification email to the user verifies that the email is valid and that the user is the owner of the account
Doing a regex check on an email address can be frustrating for some users, depending upon the regex. In my case, I have several domains where all of the addresses are delivered to a single mailbox, so I can use the address to specify the sender (for filtering). Here are some valid (per RFC 2822) address patterns that I have had rejected by various websites:
foo#example.name
foo#example.info
foo+sitename#example.org
foo-sitename#example.com
I recommend that you skip your regex test and just send the verification email with a confirmation link -- anything else will leave your application brittle and subject to breakage as soon as someone comes up with a new DNS or SMTP extension.
PS: ICANN is expected to approve UNICODE domain names Real Soon Now. That will play merry hell with Regex patterns for email addresses.
Not an answer to your question, but I'd like to quote someone on reddit:
Validating an email address using nothing but a regular expression is like building a house using nothing but a power drill.
This is the only RFC-valid way to do it:
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\ xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\x ff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015 "]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\ xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80 -\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]* )*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\ \\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\ x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x8 0-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n \015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x 80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^ \x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040 \t]*)*)*#[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([ ^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\ \\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\ x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80- \xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015() ]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\ x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04 0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\ n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\ 015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?! [^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\ ]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\ x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01 5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>#,;:". \\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff] )|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^ ()<>#,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0 15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][ ^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\ n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>#,;:".\\\[\]\ x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(? :(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80- \xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:#[\040\t]* (?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015 ()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015() ]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0 40)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\ [^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\ xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]* )*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80 -\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x 80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t ]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\ \[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff]) *\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x 80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80 -\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015( )]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\ \x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*#[\040\t ]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0 15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015 ()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^( \040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]| \\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80 -\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015() ]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x 80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^ \x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040 \t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:". \\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff ])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\ \x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x 80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015 ()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\ \\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^ (\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000- \037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\ n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]| \([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\)) [^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff \n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*( ?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\ 000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\ xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*) *\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*#[\040\t]*(?:\([^\\\x80-\x ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80- \xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*) *(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\ ]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\] )[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80- \xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*( ?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80 -\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)< >#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x8 0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?: \([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()] *(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*) *\)[\040\t]*)*)*>)
So let's not.
Sending them an e-mail forcing them to press a confirmation link is the best option, as there's always the chance that their SPAM filter will block your mails. It's best to get that dealt with when their paying attention.
In Perl there is a nice module called Email::Valid which can check the email address for valid formation, and optionally check the email address's domain for an MX record.
function EmailValidation($email)
{
$email = htmlspecialchars(stripslashes(strip_tags($email))); //parse unnecessary characters to prevent exploits
if ( eregi ( '[a-z||0-9]#[a-z||0-9].[a-z]', $email ) )
{ //checks to make sure the email address is in a valid format
$domain = explode( "#", $email ); //get the domain name
if ( #fsockopen ($domain[1],80,$errno,$errstr,3))
{
//if the connection can be established, the email address is probably valid
return true;
} else
{
return false; //if a connection cannot be established return false
}
return false; //if email address is an invalid format return false
}
}
Related
Since programatically sending a text with Meteor from the user's own cell phone number seems to be problematic (see this), I'm thinking the way to do this could be to send the SMS / texts as an email.
I often do this manually from work when I text my wife from an email client; the "rub" is that the format for the addresses to use differ based on carrier. e.g., when I SMS my wife via email, I use and address like the following:
0871632810#txt.att.net
That obviously works for someone using att.net as their carrier. For other carriers, other naming schemes are used (which can be found here and here.
So my idea is, if I know the user's phone number and their email address, I can cobble together the correct SMS address to use as the "from" in an email. e.g., given the following:
Phone == 0871632810
Email == guinevere#att.net
...I could have a function like (pseudocode):
string getSMSAsEmailAddr(phone, email) {
var emailAsSMS;
if (email.contains('att.net') {
emailAsSMS = 'txt.att.net';
}
else if (email.contains('comcast.net') {
emailAsSMS = 'comcastpcs.textmsg';
}
. . .
return phone + '#' + emailAsSMS;
}
The problem is, can a person's carrier/valid SMS address always be determined by their email address? I'm thinking no - for example, what if a person has comcast but their email address is gmail, or something else altogether?
Is it necessary, in order to reliably build the needed SMS address, to know the user's carrier (both sender and receiver) and leave the email address out of the equation?
UPDATE
There is at least one for-pay service for returning carriers for a phone number, such as this API. There is also one called "CallFire" but both of these cost moolah ($$). I prefer a free option (yes, I'm a cheapskate).
I'm thinking the way to do this is something like:
var phoneNum = $('#phoneNumber').val(); // returns something like '0871632810'
var carrier = getCarrierForPhoneNumber(phoneNum);// returns something like 'att' or 'comcast' or whatever
var textAddrSuffix = getTextAddrSuffixForCarrierName(carrier); // returns (if carrier is 'att', as an example) something like '#txt.att.net'
var textAddrViaEmail = phoneNum + textAddrSuffix; // returns something like '0871632810#txt.att.net'
textAddrViaEmail can now be used as either the "to" or "from" email address.
No, but there is a library with a rather large database of them over at https://github.com/typpo/textbelt.
I have a problem with a Google MCC Script I have. It's set up to run every day in the early hours of the morning, do some processing, and email out a result, using Google Scripts' built in MailApp.sendEmail function.
The problem is that, while the email is sent successfully, I'm also recieving messages in the inbox of the email address which owns the MCC account along the lines of
Delivery to the following recipient failed permanently:
MCC_account#example.com
Technical details of permanent failure: The email account that you
tried to reach does not exist. Please try double-checking the
recipient's email address for typos or unnecessary spaces.
with the 'Original Message' appended below that indicating it is indeed the message the Script has sent. Here's my code:
function main() {
var accountSelector = MccApp.accounts();
var accountIterator = accountSelector.withIds('###-###-###').get();
if(accountIterator.hasNext()){
var account = accountIterator.next();
MccApp.select(account);
var data = getData();
sendEmail(data);
} else Logger.log("Error: no accounts found");
}
function sendEmail(data){
var name = 'name';
var bodytext = 'body';
MailApp.sendEmail({
to: 'receiver-inbox#example.com',
name: 'Google Adwords Scripts',
replyTo: 'do-not-reply#example.com',
subject: 'SUBJECT',
attachments: [{fileName: name, mimeType: 'text/csv', content: data}],
body: bodytext
});
}
So, to clarify, the MCC account is owned by one email address, the script doesn't reference that at all, but I'm recieving the email not only in the target mailbox but also a failed delivery message in the owner inbox.
Can anyone shed any light on what is happening here?
It is very likely that you are running another copy of the script that is sending these emails. Go to your Google Account settings here and revoke access to the other script.
If you have multiple Google accounts, do a scan for all the accounts.
Okay, apparently this is a known issue with AdWords Scripts:
https://groups.google.com/forum/#!topic/adwords-scripts/SJtNW_wuArI
I am using ruby's Net::IMAP object and I can retrieve a set of emails using either:
IMAP.all ..args..
Or
IMAP.find ..args..
But is there anyway of retrieving a specific email, preferably by the message-id header for example?
Is this possible or am I limited to all and find and trying to narrow the result set with better arguments?
I didn't understand what technology you're using with IMAP. However the IMAP Specification provides the ability to search by a variety of fields, including email headers. You can use the following IMAP command to retrieve the UID of an email with Message-Id <53513DD7.8090606#imap.local>:
0005 UID SEARCH HEADER Message-ID <53513DD7.8090606#imap.local>
This will then give you a response such as the following:
* SEARCH 1
0005 OK UID completed
In my case the email with Message-Id <53513DD7.8090606#imap.local> was the first one, so the SEARCH command returned a matching UID of 1.
You can then retrieve the message using a UID FETCH command, such as the following:
0006 UID FETCH 1 BODY[]
Naturally, if you know the UID in advance, you can skip the UID SEARCH step, but that depends on your application.
For anybody else who is looking at this, these keys will do the trick:
keys: ['HEADER', 'MESSAGE-ID', message_id]
Just to give a full ruby solution incase it's helpful to someone else.
Bear in mind that if the message is in a subfolder you'll need to manually search through each folder to find the message you are after.
search_message_id = "<message-id-you-want-to-search-for>"
email = "youremail-or-imap-login"
password = "yourpassword"
imap = Net::IMAP.new("imap.example.com", 993, ssl: true)
imap.login(email, password)
imap.select("Inbox")
imap.search(["HEADER", "Message-ID", search_message_id]).each do |message_id|
envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
puts "Id:\t#{envelope.message_id}"
puts "From:\t#{envelope.from[0].mailbox}##{envelope.from[0].host}"
puts "To:\t#{envelope.to[0].mailbox}##{envelope.to[0].host}"
puts "Subject:\t#{envelope.subject}"
end
imap.logout
imap.disconnect
You can change the above to search all sub-folders by doing:
folders = imap.list("", "*")
folders.each do |folder|
imap.select(folder.name)
imap.search # ...
end
I have a form sent by email that travels through different persons like this.
Person A --> Person B --> Person C
I want the person A to be informed when the form is treated by person C. So Person A needs to be in copy of the email sent by person B.
Because person A isn't always the same one, I think the best way to put him/her in copy is to use the "from" field of the email received by person B and to put it in copy.
But how can I find this address with infopath and how can I place it into my email data connection ?
I had this same question today myself and could not find much in the way of answers.
So... I did some work myself and came up with a few solutions.
First I don't believe there is any way to get/set the "From" address using the InfoPath OM. This means you will have to use one of the following options:
No Code:
You will be limited to providing a field on the form where "Person A" can put their email address and use this in the CC. for subsequent stages. That's kind of the only way and while it an extra burden to the user it does have the benefit of providing flexibility.
Code:
Write your own code to send the mail using Outlook Interop or System.Net.Mail and then you will be setting all of the addresses manually anyway.
If you are using AD or something else then you could always get the email address of the current use using System.DirectoryServices.AccountManagement.
Based on an assumption which I cannot find any documentation to back up. That InfoPath uses the account associated with the default store to send email using EmailSubmitConnection. You should be able to use Outlook Interop to find the address that InfoPath will use.
Here is a code sample:
using Outlook = Microsoft.Office.Interop.Outlook;
public string GetDefaultSenderAddress()
{
// This actually opens outlook in the same way as InfoPath does to send the message.
// which can be slow.
string DefaultAddress = string.Empty;
Outlook.Application OutlookApplication = new Outlook.Application();
string DefaultStoreId = OutlookApplication.Session.DefaultStore.StoreID;
foreach (Outlook.Account Account in OutlookApplication.Session.Accounts)
{
if (Account.DeliveryStore.StoreID == DefaultStoreId)
{
DefaultAddress = Account.SmtpAddress;
}
}
// Note you probably won't want to quit if you are about to send the email.
// However I have noticed that this doesn't seem to close Outlook anyway.
OutlookApplication.Quit();
return DefaultAddress;
}
You may have to provide a few more checks in case of different account types etc. But I believe it will work. (I tested it for my scenario and it does).
Note: Of course this opens an outlook instance which you will have to close as well. And it can be slow. Unless outlook is already open in which case it will be very quick. Anyhow when sending from InfoPath Outlook will have to be opened so if you do this just before sending then there should be no noticeable difference.
I would advise using a combination of the no code/with code options so provide a return address which is automatically complete to save the user time. But can be corrected if the user wishes to have the email returned to a different address of if there is a mistake.
Hope that you find that useful.
What I'm doing:
Trying to reduce spammers who wants to register in my site.
And I know that:
Dot is ignored in gmail and you can put dots in everywhere of the localpart of the email address but the first position and last before #.
Problem:
When a user register in the site with ex.ample#gmail.com, everthing is ok, but problem arise when he can register again with ex.am.pl.e#gmail.com etc in the site.
what I did was:
removing any dot in the local part of the email, but I realized that the user can't submit with his email address that he just entered.
What I want is that:
Is there a way to overcome this problem? 'cause with this situation a person can register so many times by changing the dot position in the email address.
I'm sure you found the solution by now, but for the sake of completeness...
Basically you'd need to store the local part as is, without stripping the dots out, and later strip the dots out from both application and registry upon comparison. Like:
$registered_emails[0]="e.xample#gmail.com"; //This is just to show how it was registered first time
$application_email="exam.ple#gmail.com"; //New application email
$discard=0; //flag for discarding application
if (preg_match("/#gmail.com$/i", $application_email)===1) {
$app_em=str_replace(".", "", $application_email);
foreach ($registered_emails as $reg_em)
if ($app_em==str_replace(".", "", $reg_em)) {
// "example#gmailcom"=="example#gmailcom"
$discard=1; // discard application
break;
}
//can't use an "else" clause here to break, as you need to loop through all registries
}
if ($discard==1)
echo "discard application";
else
array_push($registered_emails, $application_email); //register $application_email as is (exam.ple#gmail.com)
Probably it could be worth to filter out all gmail emails from the list before, or even storing all gmail emails aside; certainly not the most elegant solution, but probably the fastest one