I'm writing a Trigger to assign an Account to a new Contact based on the email domain. I have two formula fields that strip everything but the domain (i.e. acme.com) so that I can match from the Contact to the Account.

So far I have the code below, but can't figure out how to get the Account Id that I find so that I can update the contact. I'm sure I'm not using the List correctly, but haven't been able to solve. Thanks in advance!

trigger AssociateContact on Contact (before insert) {
    List<String> contactEmaildomains = new List<String>();
    for(Contact contact:Trigger.new){

    List<Account> accounts = [
            Id, Website_Domain_Name__c 
            Website_Domain_Name__c IN :contactEmaildomains

    Set<String> accountWebsitedomains = new Set<String>();
    for(Account account:accounts){

    for(Contact contact:Trigger.new){
            contact.Account.Id = ??????(Need Account Id);
  • There are some good answers for your coding below, but I just wanted to give you a small related piece of advice. Don't forget that lots of people use free public email providers (gmail.com, yahoo.com, etc.), and you may not want to put all the people from one email service in the same account. At my org, we have a massive list of 'generic' email domains that we check against, and if the domain matches one of these we make sure to not lump the contact into an account with other users on the same email service.
    – OBerm
    Mar 27, 2015 at 18:21
  • Thanks Dupe_jockey, I may start with the solutions below and see how the system handles it - but this was definitely on my mind.
    – McD
    Mar 27, 2015 at 18:30
  • 1
    No problem. Let me know if you want the list of generic domains - it comes in handy for lots of things. As a B2B company, we automatically prioritize leads with email addresses on non-generic domains, since they are more likely to be potential business prospects.
    – OBerm
    Mar 27, 2015 at 18:49
  • @Dupe_jockey I actually would like the list of generic domains if you don't mind sharing. I have a similar requirement that I'm working out a solution for and would appreciate the leg up on assembling that list! Mar 27, 2015 at 18:59

4 Answers 4


What you want is a Map.

Map<String, Id> domains = new Map<String, Id>();
for(Contact record: Trigger.new) {
    domains.put(record.Email_Domain_Name__c, null);
for(Account record: [SELECT Website_Domain_Name__c FROM Account WHERE Website_Domain_Name__c IN :domains.keySet()]) {
    domains.put(record.Website_Domain_Name__c, record.Id);
for(Contact record: Trigger.new) {
    if(domains.get(record.Email_Domain_Name__c) != null) {
        record.AccountId = domains.get(record.Email_Domain_Name__c);
    } // you can figure out an else here, if you want
  • Thanks sfdcfox, that worked perfectly! If I did want to exclude things like gmail.com, yahoo.com, etc would I just add those to the if statement in the last piece?
    – McD
    Mar 27, 2015 at 18:31
  • 1
    You could do that, or remove them from the map before you query, either by hard-coding them, or perhaps using a custom settings object. See the Help topics and developer's guide for more info.
    – sfdcfox
    Mar 27, 2015 at 18:51
  • I created a custom metadata type called Public Email Provider (with a custom field of Email Domain) in my org for this and used github.com/mailcheck/mailcheck/wiki/List-of-Popular-Domains to populate it. Dec 25, 2016 at 4:18

I would suggest using a Map<String, Account> to store the domain name, actual Account record pairs. Then in your last for(Contact contact:Trigger.new){ loop, you can do:

    contact.Accountid = {DomainToAccountMap}.get(contact.Email_Domain.Name__c).id;

I didn't test this syntactically, but that should do what you're looking for.


You'll want to create a Map for this, using the Account Domain as the key. After querying for the accounts in question, you'll want to do something like this:

Map<String,Account> domainAccountMap = new Map<String,Account>();

for(Account a : accounts){
for(Contact c : trigger.new){
        c.AccountId = domainAccountMap.get(c.Email_Domain_Name__c).Id;

You can then use an else condition for contacts whose domain is not found in the Map.


The line of code where you are trying to populate the Account Email domain names in a Set, should be replaced with a Map. Hence using this your later half of the code changes to, as shown below.

Map<String, Id> websiteDomainAccountIdMap = new Map<String, Id>();
for(Account account :[SELECT Id, 
                      FROM Account
                      WHERE Website_Domain_Name__c IN :contactEmaildomains]){
    websiteDomainAccountIdMap.put(account.Website_Domain_Name__c, account.Id);

for(Contact contact :Trigger.new){
        contact.Account = websiteDomainAccountIdMap.get(contact.Email_Domain_Name__c);

This should fix your code!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .