1

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){
        contactEmaildomains.add(contact.Email_Domain_Name__c);
    }

    List<Account> accounts = [
        SELECT 
            Id, Website_Domain_Name__c 
        FROM 
            Account
        WHERE 
            Website_Domain_Name__c IN :contactEmaildomains
    ];

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

    for(Contact contact:Trigger.new){
        if(accountWebsitedomains.contains(contact.Email_Domain_Name__c)){
            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 '15 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 '15 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 '15 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! – Todd Sprinkel Mar 27 '15 at 18:59
2

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
}
|improve this answer|||||
  • 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 '15 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 '15 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. – Rob Alexander Dec 25 '16 at 4:18
1

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:

if({DomainToAccountMap}.contains(contact.Email_Domain_Name__c)){
    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.

|improve this answer|||||
1

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){
    domainAccountMap.put(a.Website_Domain_Name__c,a);
}
for(Contact c : trigger.new){
    if(domainAccountMap.containsKey(c.Email_Domain_Name__c){
        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.

|improve this answer|||||
1

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, 
                             Website_Domain_Name__c 
                      FROM Account
                      WHERE Website_Domain_Name__c IN :contactEmaildomains]){
    websiteDomainAccountIdMap.put(account.Website_Domain_Name__c, account.Id);
}

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

This should fix your code!

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.