How to support multiple toAddress CC BCC and attachments in hybris email?

Scenario

We want to send email to multiple addresses, also want to support the email attachments. Unfortunately, it's not happening in OOTB action.

Background

Hybris OOTB EmailService which is responsible to send email is supporting every field like attachments, BCC, etc. But EmailGenerationService is not populating those fields into EmailMessageModel. So good news is we only need to override generation service to feed all require data to EmailMessageModel

Solution

We have to define our custom attributes in BusinessProcess itemType to stores the values and access it in the later process. Also, we have to override generate method of DefaultEmailGenerationService which responsible to generate EmailMessageModel. Let's see it step by step.



1) Define custom attribute in BusinessProcessModel
To do so, you have to define attributes like below in your *-items.xml file. Now build your server(ant clean all), which will generate BusinessProcessModel with defined attributes.
Since we already have OOTB EmailAttachment itemType, we can use it for emailAttachments attribute. We just need to define 1..n relation between BusinessProcess and EmailAttachment. For toAddresses, ccAddresses and bccAddresses we can use String collection (if you are not going to store big).
<!-- 1..n relation between BusinessProcess and EmailAttachment -->
<relations>
    <relation code="BusinessProcess2AttachmentsRel" autocreate="true"
        generate="true" localized="false">
        <description>This relation links email message with specific business
            process.</description>
        <sourceElement qualifier="process" type="BusinessProcess"
            cardinality="one" />
        <targetElement qualifier="emailAttachments" type="EmailAttachment"
            cardinality="many" collectiontype="list" />
    </relation>
</relations>


<itemtype code="BusinessProcess" autocreate="false" generate="false">
    <attributes>
        <attribute qualifier="toAddresses" type="StringCollection">
            <persistence type="property" />
            <description>Attribute contains toAddresses that is used in this
                        process.</description>
        </attribute>
        <attribute qualifier="ccAddresses" type="StringCollection">
            <persistence type="property" />
            <description>Attribute contains ccAddresses that is used in this
                        process.</description>
        </attribute>
        <attribute qualifier="es" type="StringCollection">
            <persistence type="property" />
            <description>Attribute contains bccAddresses that is used in this
                        process.</description>
        </attribute>
    </attributes>
</itemtype>

2) Override DefaultEmailGenerationService
OOTB EmailMessageModel already has all attributes which we want to set(toAddresses, ccAddresses, etc.). Just that we need to feed the actual value by overriding generate method of DefaultEmailGenerationService.
public class ExtendedDefaultEmailGenerationService extends DefaultEmailGenerationService
{

    //...

    //...

    @Override
    public EmailMessageModel generate(BusinessProcessModel businessProcessModel, final EmailPageModel emailPageModel)
    {
        //Let's first call OOTB generate method to generate emailMessageModel
        EmailMessageModel emailMessageModel = super.generate(businessProcessModel, emailPageModel);

        // Now, we retrieve values of our fileds from businessProcessModel and set them to the emailMessageModel
        List<EmailAddressModel> toAddresses = createEmailAddressForEmail(businessProcessModel.getToAddresses());
        List<EmailAddressModel> ccAddresses = createEmailAddressForEmail(businessProcessModel.getCcAddresses());
        List<EmailAddressModel> bccAddresses = createEmailAddressForEmail(businessProcessModel.getBccAddresses());
        List<EmailAttachmentModel> emailAttachments = businessProcessModel.getEmailAttachments();

        if (CollectionUtils.isNotEmpty(toAddresses))
        {
            emailMessageModel.setToAddresses(toAddresses);
        }

        if (CollectionUtils.isNotEmpty(ccAddresses))
        {
            emailMessageModel.setCcAddresses(ccAddresses);
        }

        if (CollectionUtils.isNotEmpty(bccAddresses))
        {
            emailMessageModel.setBccAddresses(bccAddresses);
        }

        if (CollectionUtils.isNotEmpty(emailAttachments))
        {
            emailMessageModel.setAttachments(emailAttachments);
        }
        getModelService().save(emailMessageModel);      
    }

    private List<EmailAddressModel> createEmailAddressForEmail(List<String> emails)
    {
        final List<EmailAddressModel> emailAddressModelList = new ArrayList<EmailAddressModel>();
        if (CollectionUtils.isNotEmpty(emails))
        {
            for (String email : emails)
            {
                final EmailAddressModel emailAddressModel = getEmailService().getOrCreateEmailAddressForEmail(email,
                        email.split("@")[0]);
                emailAddressModelList.add(emailAddressModel);
            }
        }
        return null;
    }
}

3) Point emailGenerationService alias to our class
<alias alias="emailGenerationService" name="extendedDefaultEmailGenerationService"/>
<bean id="extendedDefaultEmailGenerationService" class="com.myproject.core.email.impl.ExtendedDefaultEmailGenerationService"
    parent="defaultEmailGenerationService"/>



4) Cerate businessProcessModel and set the values
Create businessProcessModel instance, set all attributes and start the process to send the email with attachments and other fields.
public void processEmail(List<String> toAddresses, List<String> ccAddresses, List<String> bccAddresses, List<EmailAttachmentModel> emails)
    {

        BusinessProcessModel businessProcessModel = getBusinessProcessService().createProcess("myProcess-"+ System.currentTimeMillis(), "processDefination");

        //... set site, lang, currency etc.
        businessProcessModel.setToAddresses(toAddresses);
        businessProcessModel.setCcAddresses(ccAddresses);
        businessProcessModel.setBccAddresses(bccAddresses);
        businessProcessModel.setEmailAttachments(emailAttachments);

        getModelService().save(businessProcessModel);
        getBusinessProcessService().startProcess(businessProcessModel);
    }


 

How to change fromEmail Address of an email in Hybris?




Author Image

Ankitkumar Patel

Sr. SAP Hybris consultant, having 15+ years experience in SAP Commerce Cloud (Hybris), SAP Spartacus. Extensive experience in SAP Hybris development, third-party integrations, project architecture and design... Read more

Comments

  1. Will this change the TO email addresses of every mail that is flowing out.?

    ReplyDelete

Post a Comment

Popular posts from this blog

Hybris flexible search query examples

How to remove or update all data records in Hybris?

How to Install temporary Hybris license?