Expand my Community achievements bar.

SOLVED

AEM 6.5 : workflow notification

Avatar

Level 2

Hello,

What is the best way to send notifications to an author upon executing a workflow ?

I am trying to give the author insights regarding the progress of the execution but he is not required to participate in the workflow.

I simply wish to notify the author from inside his session.

Thanks,

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @manal-ghanim 

 

You can write a custom workflow Process and invoke the process within the page activation workflow.

I have written almost similar to the same functionality here which might be helpful for you:

 

@Component(service = WorkflowProcess.class, property = {"process.label=Send Page Replication Workflow Completed Email Process"})
public class SendPageReplicationWorkflowCompleteNotificationProcess implements WorkflowProcess {

/**
* The Log.
*/
protected final Logger log = LoggerFactory.getLogger(this.getClass());

private static final String REPLICATION_STATUS_EMAIL_TEMPLATE_PATH = "etc/notification/email/project/page-replication-status-email.txt";

@Reference(policy = ReferencePolicy.STATIC)
private MessageGatewayService messageGatewayService;

@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
log.debug("**** :: execute :: start :: *****");

try (ResourceResolver resourceResolver = workflowSession.adaptTo(ResourceResolver.class)) {
if (this.messageGatewayService != null && this.messageGatewayService.getGateway(HtmlEmail.class) != null) {
ArrayList<InternetAddress> emailRecipients = getEmailRecipients(resourceResolver, workItem);
if (emailRecipients != null && !emailRecipients.isEmpty()) {
final String template = loadTemplateProfile(resourceResolver, FileSystem.SEPARATOR + REPLICATION_STATUS_EMAIL_TEMPLATE_PATH);
if (StringUtils.isNotBlank(template)) {
Map<String, String> valuesMap = new HashMap<>();
String hostPrefix = getHostPrefix(resourceResolver);
valuesMap.put("host.prefix", hostPrefix);
valuesMap.put("Time", Calendar.getInstance().getTime().toString());
valuesMap.put("Step", workItem.getNode().getTitle());
valuesMap.put("Workflow", workItem.getWorkflow().getWorkflowModel().getTitle());
valuesMap.put("Content", workItem.getWorkflowData().getPayload().toString());
StrSubstitutor strSubstitutor = new StrSubstitutor(valuesMap);
HtmlEmail email = createEmail(template, strSubstitutor);
email.setTo(emailRecipients);
this.messageGatewayService.getGateway(HtmlEmail.class).send(email);
log.debug("Email was sent.");
} else {
log.warn("Email Template is empty.");
}
} else {
log.warn("Did not send email. No recipient addresses available.");
}
} else {
log.warn("Cannot send email, mail service unavailable. Please configure Gateway in OSGi Console");
}

} catch (Exception e) {
log.error("***** :: execute :: exception --> {0}", e);
}

log.debug("**** :: execute :: end :: *****");
}

private ArrayList<InternetAddress> getEmailRecipients(ResourceResolver resourceResolver, WorkItem workItem) {
String recipients = StringUtils.EMPTY;
String userId = StringUtils.EMPTY;
ArrayList<InternetAddress> emailRecipients = null;
try {
final UserManager manager = resourceResolver.adaptTo(UserManager.class);
if (null != manager) {
final Authorizable authorizable = manager.getAuthorizable(workItem.getWorkflow().getInitiator());
recipients = PropertiesUtil.toString(authorizable.getProperty("profile/email"), StringUtils.EMPTY);
userId = authorizable.getID();
}
List<String> recipientList = Arrays.asList(recipients.split(","));
emailRecipients = new ArrayList<>();
for (String recipient : recipientList) {
if (!StringUtils.isEmpty(recipient)) {
emailRecipients.add(new InternetAddress(recipient));
}
}
} catch (Exception e) {
log.warn("Cannot get email id of user {}", userId);
}
return emailRecipients;
}

private String loadTemplateProfile(ResourceResolver resolver, String templatePath) throws RepositoryException {
if (templatePath.startsWith(FileSystem.SEPARATOR)) {
final Session session = resolver.adaptTo(Session.class);
if (null != session) {
final Node content = session.getNode(templatePath + FileSystem.SEPARATOR + JcrConstants.JCR_CONTENT);
InputStream inputStream = content.getProperty(JcrConstants.JCR_DATA).getBinary().getStream();
try (InputStreamReader r = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
StringWriter w = new StringWriter();
IOUtils.copy(r, w);
return w.toString();
} catch (Exception e) {
log.error("Error while loading mail template {}:{}", templatePath, e);
}
}
}
return null;
}

private HtmlEmail createEmail(String template, StrSubstitutor strSubstitutor) {
HtmlEmail email = new HtmlEmail();
try {
CountingInputStream in = new CountingInputStream(new ByteArrayInputStream(template.getBytes(StandardCharsets.UTF_8)));
InternetHeaders internetHeaders = new InternetHeaders(in);
Map<String, String[]> headers = new HashMap<>();
Enumeration<Header> e = internetHeaders.getAllHeaders();
while (e.hasMoreElements()) {
Header hdr = e.nextElement();
String name = hdr.getName();
log.debug("Header: {} = {}", name, hdr.getValue());
headers.put(name, internetHeaders.getHeader(name));
}
String templateBody = template.substring(in.getCount());
email.setCharset(String.valueOf(StandardCharsets.UTF_8));
String[] ret = headers.remove("subject");
String subject = (ret == null) ? StringUtils.EMPTY : ret[0];
if (!StringUtils.isEmpty(subject)) {
email.setSubject(strSubstitutor.replace(subject));
}
templateBody = strSubstitutor.replace(templateBody);
log.debug("Substituted mail body: {}", templateBody);
email.setMsg(templateBody);
IOUtils.closeQuietly(in);
} catch (Exception e) {
log.error("Create email: {}", e.getMessage());
}
return email;
}

private String getHostPrefix(ResourceResolver resolver) {
Externalizer externalizer = resolver.adaptTo(Externalizer.class);
String externalizerHost = externalizer.externalLink(resolver, "local", StringUtils.EMPTY);
if (externalizerHost != null && externalizerHost.endsWith(FileSystem.SEPARATOR)) {
return externalizerHost.substring(0, externalizerHost.length() - 1);
}
return externalizerHost;
}

/**
* Bind message gateway service.
*
* @param paramMessageGatewayService the param message gateway service
*/
protected void bindMessageGatewayService(MessageGatewayService paramMessageGatewayService) {
this.messageGatewayService = paramMessageGatewayService;
}

/**
* Unbind message gateway service.
*
* @param paramMessageGatewayService the param message gateway service
*/
protected void unbindMessageGatewayService(MessageGatewayService paramMessageGatewayService) {
if (this.messageGatewayService == paramMessageGatewayService)
this.messageGatewayService = null;
}

}

 

Hope this helps!

Thanks! 

View solution in original post

1 Reply

Avatar

Correct answer by
Community Advisor

Hi @manal-ghanim 

 

You can write a custom workflow Process and invoke the process within the page activation workflow.

I have written almost similar to the same functionality here which might be helpful for you:

 

@Component(service = WorkflowProcess.class, property = {"process.label=Send Page Replication Workflow Completed Email Process"})
public class SendPageReplicationWorkflowCompleteNotificationProcess implements WorkflowProcess {

/**
* The Log.
*/
protected final Logger log = LoggerFactory.getLogger(this.getClass());

private static final String REPLICATION_STATUS_EMAIL_TEMPLATE_PATH = "etc/notification/email/project/page-replication-status-email.txt";

@Reference(policy = ReferencePolicy.STATIC)
private MessageGatewayService messageGatewayService;

@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
log.debug("**** :: execute :: start :: *****");

try (ResourceResolver resourceResolver = workflowSession.adaptTo(ResourceResolver.class)) {
if (this.messageGatewayService != null && this.messageGatewayService.getGateway(HtmlEmail.class) != null) {
ArrayList<InternetAddress> emailRecipients = getEmailRecipients(resourceResolver, workItem);
if (emailRecipients != null && !emailRecipients.isEmpty()) {
final String template = loadTemplateProfile(resourceResolver, FileSystem.SEPARATOR + REPLICATION_STATUS_EMAIL_TEMPLATE_PATH);
if (StringUtils.isNotBlank(template)) {
Map<String, String> valuesMap = new HashMap<>();
String hostPrefix = getHostPrefix(resourceResolver);
valuesMap.put("host.prefix", hostPrefix);
valuesMap.put("Time", Calendar.getInstance().getTime().toString());
valuesMap.put("Step", workItem.getNode().getTitle());
valuesMap.put("Workflow", workItem.getWorkflow().getWorkflowModel().getTitle());
valuesMap.put("Content", workItem.getWorkflowData().getPayload().toString());
StrSubstitutor strSubstitutor = new StrSubstitutor(valuesMap);
HtmlEmail email = createEmail(template, strSubstitutor);
email.setTo(emailRecipients);
this.messageGatewayService.getGateway(HtmlEmail.class).send(email);
log.debug("Email was sent.");
} else {
log.warn("Email Template is empty.");
}
} else {
log.warn("Did not send email. No recipient addresses available.");
}
} else {
log.warn("Cannot send email, mail service unavailable. Please configure Gateway in OSGi Console");
}

} catch (Exception e) {
log.error("***** :: execute :: exception --> {0}", e);
}

log.debug("**** :: execute :: end :: *****");
}

private ArrayList<InternetAddress> getEmailRecipients(ResourceResolver resourceResolver, WorkItem workItem) {
String recipients = StringUtils.EMPTY;
String userId = StringUtils.EMPTY;
ArrayList<InternetAddress> emailRecipients = null;
try {
final UserManager manager = resourceResolver.adaptTo(UserManager.class);
if (null != manager) {
final Authorizable authorizable = manager.getAuthorizable(workItem.getWorkflow().getInitiator());
recipients = PropertiesUtil.toString(authorizable.getProperty("profile/email"), StringUtils.EMPTY);
userId = authorizable.getID();
}
List<String> recipientList = Arrays.asList(recipients.split(","));
emailRecipients = new ArrayList<>();
for (String recipient : recipientList) {
if (!StringUtils.isEmpty(recipient)) {
emailRecipients.add(new InternetAddress(recipient));
}
}
} catch (Exception e) {
log.warn("Cannot get email id of user {}", userId);
}
return emailRecipients;
}

private String loadTemplateProfile(ResourceResolver resolver, String templatePath) throws RepositoryException {
if (templatePath.startsWith(FileSystem.SEPARATOR)) {
final Session session = resolver.adaptTo(Session.class);
if (null != session) {
final Node content = session.getNode(templatePath + FileSystem.SEPARATOR + JcrConstants.JCR_CONTENT);
InputStream inputStream = content.getProperty(JcrConstants.JCR_DATA).getBinary().getStream();
try (InputStreamReader r = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
StringWriter w = new StringWriter();
IOUtils.copy(r, w);
return w.toString();
} catch (Exception e) {
log.error("Error while loading mail template {}:{}", templatePath, e);
}
}
}
return null;
}

private HtmlEmail createEmail(String template, StrSubstitutor strSubstitutor) {
HtmlEmail email = new HtmlEmail();
try {
CountingInputStream in = new CountingInputStream(new ByteArrayInputStream(template.getBytes(StandardCharsets.UTF_8)));
InternetHeaders internetHeaders = new InternetHeaders(in);
Map<String, String[]> headers = new HashMap<>();
Enumeration<Header> e = internetHeaders.getAllHeaders();
while (e.hasMoreElements()) {
Header hdr = e.nextElement();
String name = hdr.getName();
log.debug("Header: {} = {}", name, hdr.getValue());
headers.put(name, internetHeaders.getHeader(name));
}
String templateBody = template.substring(in.getCount());
email.setCharset(String.valueOf(StandardCharsets.UTF_8));
String[] ret = headers.remove("subject");
String subject = (ret == null) ? StringUtils.EMPTY : ret[0];
if (!StringUtils.isEmpty(subject)) {
email.setSubject(strSubstitutor.replace(subject));
}
templateBody = strSubstitutor.replace(templateBody);
log.debug("Substituted mail body: {}", templateBody);
email.setMsg(templateBody);
IOUtils.closeQuietly(in);
} catch (Exception e) {
log.error("Create email: {}", e.getMessage());
}
return email;
}

private String getHostPrefix(ResourceResolver resolver) {
Externalizer externalizer = resolver.adaptTo(Externalizer.class);
String externalizerHost = externalizer.externalLink(resolver, "local", StringUtils.EMPTY);
if (externalizerHost != null && externalizerHost.endsWith(FileSystem.SEPARATOR)) {
return externalizerHost.substring(0, externalizerHost.length() - 1);
}
return externalizerHost;
}

/**
* Bind message gateway service.
*
* @param paramMessageGatewayService the param message gateway service
*/
protected void bindMessageGatewayService(MessageGatewayService paramMessageGatewayService) {
this.messageGatewayService = paramMessageGatewayService;
}

/**
* Unbind message gateway service.
*
* @param paramMessageGatewayService the param message gateway service
*/
protected void unbindMessageGatewayService(MessageGatewayService paramMessageGatewayService) {
if (this.messageGatewayService == paramMessageGatewayService)
this.messageGatewayService = null;
}

}

 

Hope this helps!

Thanks!