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);
}
Will this change the TO email addresses of every mail that is flowing out.?
ReplyDelete