8

I have created a picklist with selectOptions as Org-wide email address as below

VF Code

<apex:selectList value="{!emailFromAddress}" size="1" multiselect="false">
              <apex:selectOptions value="{!OrgWideEmailAddress}"></apex:selectOptions>
</apex:selectList>

Controller Code

public List<selectoption> getOrgWideEmailAddress(){
        List<SelectOption> lstEmailIds = new List<SelectOption>();

        // Use Organization Wide Address 
       for(OrgWideEmailAddress owa : [select id, Address from OrgWideEmailAddress]) {
           lstEmailIds.add(new SelectOption(owa.id,owa.address)); 
       }
       return lstEmailIds;
    }

The selected email Address Id is used to set as OrgWideEmailId for an email as below

Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
mail.setOrgWideEmailAddressId(emailFromAddress);

But when i select a Non verified email address then email sending fails. Hence i want a way to filter & get only verified email address to show in Picklist options.

Tia.

6

I don't think it is accessible by any API, although you can consider the following workaround: you could store all the verified OrgWideEmailAddress in some custom setting or label to use it as a cache and populate your picklist from there. Then, when something new appears in the OrgWideEmailAddress collection, try to send a test email only for the new one (that is not present in your cache collection) like this (not fully tested so take it as pseudo code):

for (OrgWideEmailAddress addr : [SELECT id, DisplayName, Address 
        FROM OrgWideEmailAddress where Address NOT IN : myCachedCollection]) {

    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setOrgWideEmailAddressId(addr.id);
    mail.setPlainTextBody('test');
    mail.setToAddresses(new List<string> { 'test@test.com' });

    try {
         Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }catch(EmailException e){
        // IF MESSAGE CONTAINS "UNVERIFIED_SENDER_ADDRESS":
            // UPS! NOT VERIFIED YET
            continue;
    }

    //ADD EMAIL TO CACHE HERE
}

If it is verified, add it to your cached OrgWideEmailAddress collcetion.

If it is not verified, the System.EmailException with UNVERIFIED_SENDER_ADDRESS message will be thrown, letting you know that it shouldnt be used yet.

You can also handle removing OrgWideEmailAddress with some trigger or even up here. Good luck!

  • @bart..your statement - "Then, when something new appears in the OrgWideEmailAddress collection, try to send a test email only for the new one". When is this supposed to be done according to you? A Batch or a trigger can be written on OrgWideEmailAddress ??? – snehakem Feb 24 '15 at 5:12
  • I guess trigger would be the most accurate place but for the sake of simplicity (and redundancy for sure) you can even perform the comparison while populating picklist from your APEX controller. – Bart Juriewicz Feb 24 '15 at 8:16
  • i am not asking about the comparison. I am asking when will that OrgWideEmailAddress will go to new object as record and when the send test email will be done? It will be available for comparison only when verified address are stored in new object. – snehakem Feb 24 '15 at 8:58
  • 1
    Yep, my mistake. Trigger should be used when some orgWideEmailAddress record is deleted, to sync it with cached label/custom setting. You should check for orgWideEmail verification each time you populate the picklist, inside your controller. Of course most of the time the cache and orgWideEmails collection will be the same so there will be no need for sending test email; therefore the overhead should be perfectly acceptable. That's a pity there's no just a simple property like active=yes/no anyway. – Bart Juriewicz Feb 24 '15 at 9:11
4

Bart's solution is a well-crafted one and probably the best for your situation. I had a similar need to query only verified addresses but my criteria were a bit more flexible so I was able to take a simpler approach. I catch the exception and if it was due to an unverified address I resend with a default company OrgWideEmailAddress that we use for more generic operations. Obviously a less personal approach but at least this way the email goes out. Remember that if using sendEmail() to send to a list you can set the optional all-or-none flag to false (default is true) to achieve partial success. You can then analyze the returned email results to handle any individual exceptions.

  • took the same approach... Pretty ridiculous that its just not stored on the OrgWideEmailAddress obj – NSjonas Jul 14 '17 at 19:45
  • I'm running into a scenario where the email isn't sending but I'm also not getting an "UNVERIFIED_SENDER_ADDRESS" error – NSjonas Nov 12 '19 at 19:41
0

Here's a snippet that outlines one way to implement the solution suggested by gofestive.

You would specify a DEFAULT_ORG_WIDE_ID to use as a fallback if the dynamically selected ORG WIDE email address is invalid.

public static void sendFromOrgWide(Messaging.SingleEmailMessage mail, String userEmail) {
    // look for matching ORG wide email
    try {
        Id emailId = [SELECT Id FROM OrgWideEmailAddress WHERE Address = :userEmail].Id;
        mail.setOrgWideEmailAddressId(emailId);
    } catch (Exception e) {
        //doesn't exist, fallback
        mail.setOrgWideEmailAddressId(DEFAULT_ORG_WIDE_ID);
        mail.setReplyTo(userEmail);
    }

    //attempt to send
    try { 
        Messaging.sendEmail(new List<Messaging.Email>{mail});
    } catch (EmailException e) {
        //unverified. fallback
        if (e.getMessage().contains('UNVERIFIED_SENDER_ADDRESS')) {
            mail.setOrgWideEmailAddressId(DEFAULT_ORG_WIDE_ID);
            mail.setReplyTo(userEmail);
            Messaging.sendEmail(new List<Messaging.Email>{mail});
        } else {
            throw e;
        }
    }
}

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.