I would like to clarify something that, the email is not sent until the Apex transaction is committed.
Here are two links related to this situation:-
http://help.salesforce.com/HTViewSolution?id=000006765
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_forcecom_email_outbound.htm
Here is code for forcefully sendEmail to Logged In User.
trigger triggerOnContact on Contact (before insert, after insert) {
Map<String,Contact> existingContactMap= new Map<String,Contact>(); //creating Map of contact with email you, because you can use other field while sending email
Map<String,String> emailMsg = new Map<String,String>();
if(trigger.isBefore){
Set<String> emailSet =new Set<String>();
for(Contact contactObj : trigger.new){
if(String.isNotBlank(contactObj.Email)) emailSet.add(contactObj.Email);
}
For(List<Contact> contacts : [SELECT Name, Email From Contact WHERE Email in: emailSet ]){
for(Contact contactObj : contacts){
if(!existingContactMap.containsKey(contactObj.Email)){
existingContactMap.put(contactObj.Email,contactObj);
emailMsg.put(contactObj.Email,contactObj.Name);
}
}
}
List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
for(Contact contactObj : trigger.new){
if(String.isNotBlank(contactObj.Email)){
if(!existingContactMap.containsKey(contactObj.Email)){
contactObj.IsContactExistWithEmail__c=true;//for deleting records
mails.add(sendErrorEmail(contactObj.Email,existingContactMap, emailMsg));
// contactObj.addError('The Email \''+ contactObj.Email + '\' is already available in the Contact.');
}
}
}
if(mails.size()>0)
Messaging.sendEmail(mails);
} else{
List<Contact> contactToDelete = new List<Contact>();
for(Contact contactObj : trigger.new){
if(contactObj.IsContactExistWithEmail__c)
contactToDelete.add(new Contact(id=contactObj.id));
}
if(contactToDelete.size()>0)
delete contactToDelete;
}
/**
* method is used to creating Emails
**/
private Messaging.SingleEmailMessage sendErrorEmail(String email,Map existingContactMap1, Map emailMsg1){
List toAddresses = new List{UserInfo.getUserEmail()} ; //getting Login user's Email
System.debug(toAddresses);
//Sending Mail
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage() ;
// Assign the addresses for the To and CC lists to the mail object
mail.setToAddresses(toAddresses);
//Email subject to be changed
mail.setSubject('Contact already exist with Email');
//Body of email
mail.setHtmlBody('Hi ' + emailMsg1.get(email)
+',\nBelow Email is does not exist in Contact records.\nEmail:'+email
+'\n so we Deleted the record.');
return mail;
}
}
See Case IsClosed Trigger Bug?
This is not a bug. Currently the setting of this value is not done
until the save which comes after the before trigger in the event
timeline.
There are two workarounds available for you I believe:
1) Execute your logic in an after trigger. This occurs after the save
and thus the value should be set. 2) Query CaseStatus with the value
provided by the user for the status to determine if it is flagged as a
closed status.
Which one you take would depend on whether you need to modify the
object in any way since this is allowed in before triggers but not in
after triggers.
Sounds like the easiest approach may be to use an after trigger instead.
Best Answer
Use
String.containsNone()
to check whether a string contains any prohibited characters, orString.containsOnly()
to check that it only contains a specific set of characters. That said, be aware that email addresses are a good deal more flexible than you might think, and special characters aren't necessarily invalid.Regular expressions are generally not a good fit for validating email addresses, which is surprisingly tricky. There's a lot of edge cases that are perfectly valid but that your regex in the comments will not match. Your regex, for example, won't match
john.smith+stuff@gmail.com
, which is not only valid but common, orwebmaster@company.cloud
. (There are now a lot of TLDs, not all of which are 2-4 characters long).For more on why parsing and validating email addresses is really hard, and most validation is too strict or just plain wrong, see for example this article, or read the relevant RFCs 822, 2821, 2822, 3696.