Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Send Email -Workflow

Avatar

Level 10

Hello,

I would like to send email picking the template from AEM, and also dynamically adding values to the template using the workflow code. I would like to construct the "TO" list in an email dynamically, picking it up from a group of users(group A), and would like to insert a line, "URL" dynamically in the email template .txt file.

Please let me know.

Regards,

Nicole

1 Accepted Solution

Avatar

Correct answer by
Employee

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

View solution in original post

24 Replies

Avatar

Level 10

Are you asking if this use case is out of the box functionality or if it is possible? 

Avatar

Level 10

Justin, 

I wonder if this has been missed out in Documentation , but if one needs to send out email from AEM, on start up -Djava.net.preferIPv4Stack=true needs to be added.

Wish it was known earlier, Would be helpful for others trying to crack this issue. Thanks for help and patience , 

Avatar

Level 10

No Scott, I am trying to create a workflow step mocking the Send Email functionality, Since not all my requirements might be met by OOTB component. 

Avatar

Level 10

If OOTB does not address your needs -- then yes - you are correct - a custom workflow step is the way to go. Remember that a custom workflow step is just like any other OSGi bundle which is Java. So there is not much you cannot accomplish. If you want to get CQ users for you custom workflow step -- you can use the CQ com.day.cq.security.UserManager. API. To learn how to work with this API, see http://scottsdigitalcommunity.blogspot.ca/2013/07/using-ajax-requests-to-display-adobe-cq.html

Avatar

Level 10

Scott, 

I tried using message gateway service to send out an email, in my custom workflow process step, but keep getting the error, a NPE, i have keyed in smtp port and username etc in CQ mail service configuration in system console. I see people posting issues on the same, please help me with this.

Code:

@Reference
private MessageGatewayService messageGatewayService;

     ArrayList<InternetAddress> emailRecipients = new ArrayList<InternetAddress>();

public void execute(WorkItem item, WorkflowSession session,

    MetaDataMap metaData) throws WorkflowException {

HtmlEmail email = new HtmlEmail();

      emailRecipients.add(new InternetAddress("email") );
      email.setTo( emailRecipients );
      email.setSubject( "This is subject");
      email.setHtmlMsg( "Email testing");

Error:

messageGatewayService : com.day.cq.mailer.impl.CqMailingService@c14701
messageGateway : null
Fatal error while sending email in workflowjava.lang.NullPointerException

Avatar

Level 2

You are getting null pointer exception. Refer services :

@Reference
private MessageGateway<HtmlEmail> messageGateway;

@Reference
private MessageGatewayService messageGatewayService;

and then :

messageGateway = messageGatewayService.getGateway(HtmlEmail.class);

messageGateway.send(email);

Avatar

Employee

I don't see the code where you actually send the email.

The correct way to do this in a workflow process is to have

@Reference(policy = ReferencePolicy.DYNAMIC) private MailService mailService;

And then in the body of the execute() method (or some other method called from execute) do:

HtmlEmail email = //build the email if (mailService != null) { mailService.send(email); } else { logger.warn("Mail Service is not available. Check log for configuration issues."); } 

Rolling your own mail service is going to end up duplicating configuration as you need to configure the CQ MailService to get default notifications working in the first place.

Regards,

Justin

Avatar

Level 10

What about customizing the email service -- use your own email service in your own process step- always works nicely. 

I wrote an article on this a while back. I used the Java Mail API and wrapped that API within an OSGi. You can do that invoke it from your process step. It sent email messages from CQ without any issues at all. 

See: http://scottsdigitalcommunity.blogspot.ca/2012/07/creating-custom-cq-email-services.html

In the mean time -- i am going to dig in our bug base and see if there are issues with this other service. 
HTH

Avatar

Level 10

Thank you will revert back with inputs, i wanted to use HTMLEmail. Please let me know if you find anything. I know this was working in 5.4 , and now in AEM 5.6 , there seems to be issues

Avatar

Level 10

Thanks Justin, I agree with you referred to an online link http://blogs.adobe.com/learningwem/2011/11/27/cq5-4-workflow-process-to-send-an-email-using-messageg....

Now i get the below error with the code implemented. Please could you guide me along right path.

@Reference(policy = ReferencePolicy.DYNAMIC)
private MailService mailService;

ArrayList<InternetAddress> emailRecipients = new ArrayList<InternetAddress>();

public void execute(WorkItem item, WorkflowSession session,

    MetaDataMap metaData) throws WorkflowException {         

 HtmlEmail email = new HtmlEmail();

         emailRecipients.add(new InternetAddress("test@gmail.com") );

        email.setTo( emailRecipients );
        email.setSubject( "This is subject");
        email.setHtmlMsg( "Email testing is on..");

        mailService.send( email );

        System.out.println("Done");

}

 

Error: (at line  mailService.send( email );)

Caused by: java.lang.ClassCastException: org.apache.commons.mail.HtmlEmail cannot be cast to org.apache.commons.mail.Email

 

IMO , i read the api and see, would using messageGateway.send(htmlEmail) be a right thing to do?

     
voidsendEmail(org.apache.commons.mail.Email email) 
          Deprecated. since 5.4 use MessageGateway.send(Object) instead}

Avatar

Employee

Can you post your bundle's MANIFEST.MF file?

Avatar

Level 10

Updated: Sure, I could send the xml under OSGI-INF under scr-plugin-generated folder, I have also attached the MANIFEST.MF file contents Please let me know if anything else is needed from me. I also see the bundle being part of references in the services tab for Message Gateway and Message Gateway interface. 

<?xml version="1.0" encoding="UTF-8"?><components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
    <scr:component immediate="true" name="com.test.workflow.email.EmailWorkflow">
        <implementation class="com.test.workflow.email.EmailWorkflow"/>
        <service servicefactory="false">
            <provide interface="com.day.cq.workflow.exec.WorkflowProcess"/>
        </service>
        <property name="service.description" value="Test Email workflow process implementation."/>
        <property name="service.vendor" value="Adobe"/>
        <property name="process.label" value="Test Email Workflow Process"/>
        <property name="service.pid" value="com.test.workflow.email.EmailWorkflow"/>
        <reference name="messageGateway" interface="com.day.cq.mailer.MessageGateway" cardinality="1..1" policy="static" bind="bindMessageGateway" unbind="unbindMessageGateway"/>
        <reference name="messageGatewayService" interface="com.day.cq.mailer.MessageGatewayService" cardinality="1..1" policy="static" bind="bindMessageGatewayService" unbind="unbindMessageGatewayService"/>
        <reference name="mailService" interface="com.day.cq.mailer.MailService" cardinality="1..1" policy="dynamic" bind="bindMailService" unbind="unbindMailService"/>
    </scr:component>
</components>

MANIFEST.MF

Manifest-Version: 1.0
Bnd-LastModified: 1379652279235
Build-Jdk: 1.7.0_21
Built-By: XXX
Bundle-Category: cq5
Bundle-ClassPath: .,commons-email-1.3.jar
Bundle-Description: Workflow to send email
Bundle-ManifestVersion: 2
Bundle-Name: EmailProcess
Bundle-SymbolicName: com.test.workflow.email
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Embed-Dependency: commons-email
Embedded-Artifacts: commons-email-1.3.jar;g="org.apache.commons";a="comm
 ons-email";v="1.3"
Export-Package: com.test.workflow.email;uses:="com.day.cq.workflow.metada
 ta,com.day.cq.mailer,javax.mail.internet,com.day.cq.workflow,javax.mail
 ,com.day.cq.workflow.exec,org.osgi.service.component";version="1.0.0",c
 om.test.email.constants;version="1.0.0"
Implementation-Title: Custom Email Workflow
Implementation-Vendor: Test
Implementation-Version: 1.0.1
Import-Package: com.day.cq.mailer,com.day.cq.workflow,com.day.cq.workflo
 w.exec,com.day.cq.workflow.metadata,javax.activation,javax.mail;version
 ="[1.4,2)",javax.mail.internet;version="[1.4,2)",javax.mail.util;versio
 n="[1.4,2)",javax.naming,org.osgi.service.component;version="[1.0,2)"
Service-Component: OSGI-INF/com.test.workflow.email.EmailWorkflow.xml
Tool: Bnd-1.50.0

Avatar

Correct answer by
Employee

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

Avatar

Employee

I was looking for the MANIFEST.MF file from the bundle.

Let's try something else... are you using <Embed-Dependency> in your pom.xml file?

Avatar

Level 10

justin_at_adobe wrote...

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

 

Justin,

I totally get it when you say don't embed commons-email, i must say that the workflow executes just perfect, thanks, but am wondering if i should manually install a jar- commons-email in felix console and have it being imported by the bundle?

I was wondering if i was to install the commons-email jar in felix or not, if i am doing something right?.

Regards,

Avatar

Level 10

Yes, <Embed-Dependency>commons-email</Embed-Dependency>

Also i see when i click on the custom workflow bundle, it refers to Message GatewayService and not Message Gateway . Will attach entire code as well.

     
Used Services

 

MANIFEST.MF

Manifest-Version: 1.0
Bnd-LastModified: 1379652279235
Build-Jdk: 1.7.0_21
Built-By: XXX
Bundle-Category: cq5
Bundle-ClassPath: .,commons-email-1.3.jar
Bundle-Description: Workflow to send email
Bundle-ManifestVersion: 2
Bundle-Name: EmailProcess
Bundle-SymbolicName: com.test.workflow.email
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Embed-Dependency: commons-email
Embedded-Artifacts: commons-email-1.3.jar;g="org.apache.commons";a="comm
 ons-email";v="1.3"
Export-Package: com.test.workflow.email;uses:="com.day.cq.workflow.metada
 ta,com.day.cq.mailer,javax.mail.internet,com.day.cq.workflow,javax.mail
 ,com.day.cq.workflow.exec,org.osgi.service.component";version="1.0.0",c
 om.test.email.constants;version="1.0.0"
Implementation-Title: Custom Email Workflow
Implementation-Vendor: Test
Implementation-Version: 1.0.1
Import-Package: com.day.cq.mailer,com.day.cq.workflow,com.day.cq.workflo
 w.exec,com.day.cq.workflow.metadata,javax.activation,javax.mail;version
 ="[1.4,2)",javax.mail.internet;version="[1.4,2)",javax.mail.util;versio
 n="[1.4,2)",javax.naming,org.osgi.service.component;version="[1.0,2)"
Service-Component: OSGI-INF/com.test.workflow.email.EmailWorkflow.xml
Tool: Bnd-1.50.0

 

Code - Tried with HtmlEmail and Email:

public class EmailWorkflow  implements WorkflowProcess{

    
    

ArrayList<InternetAddress> emailRecipients = new ArrayList<InternetAddress>();

 

@Reference
private MessageGatewayService messageGatewayService;

 

public void execute(WorkItem item, WorkflowSession session,
    MetaDataMap metaData) throws WorkflowException {
    java.util.Properties props = new java.util.Properties();
    MessageGateway<Email> messageGateway;

    Email email = new SimpleEmail();

    try {

        emailRecipients.add(new InternetAddress("test@gmail.com") );
        email.setTo( emailRecipients );
        email.setSubject( "This is subject");
        email.setMsg( "Email testing is on..");

        //Check the logs to see that messageGatewayService is not null
        System.out.println("messageGatewayService : " + messageGatewayService);

       messageGateway = messageGatewayService.getGateway(Email.class);

        //Check the logs to see that messageGateway is not null
        System.out.println("messageGateway : " + messageGateway);

        messageGateway.send( (Email)email );

        System.out.println("Done");

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    } catch (EmailException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}  
}

Avatar

Level 10

justin_at_adobe wrote...

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

 

Thanks a lot Justin, It solved the Issue, Appreciate it . I am trying to send the email,and i set port 587 with the properties as attached and i see, the following error.In my java code i add a line

props.put("mail.smtp.starttls.enable","true");

But I am wondering how i could send out an email with having the property value set since most of the properties are being picked up from the config. If the value is set the below error vanishes. I tried with port 465 for smtp.gmail.com and it didn't work, hence tried with 587.Please let me know your inputs on the same.

530 5.7.0 Must issue a STARTTLS command first. m1sm3483898igj.10 - gsmtp
com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.0 Must issue a STARTTLS command first. m1sm3483898igj.10 - gsmtp

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:1388)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:959)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:583)
    at javax.mail.Transport.send0(Transport.java:169)
    at javax.mail.Transport.send(Transport.java:98)
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1388)
    at org.apache.commons.mail.Email.send(Email.java:1423)
    at com.day.cq.mailer.impl.DefaultMailService.send(DefaultMailService.java:235)
    at com.day.cq.mailer.impl.DefaultMailService.send(DefaultMailService.java:37)
    at com.test.workflow.email.EmailWorkflow.execute(EmailWorkflow.java:91)
    at com.day.cq.workflow.compatibility.CQWorkflowProcessRunner.execute(CQWorkflowProcessRunner.java:93)
    at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:208)
    at com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.java:139)
    at org.apache.sling.event.jobs.JobUtil$1.run(JobUtil.java:272)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
QUIT

 

Regards,

Avatar

Level 10

justin_at_adobe wrote...

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

 

By installing commons-mail in felix console i mean org.apache.commons.mail , Please let me know where i am wrong. I have posted bundle's Manifest.MF file. I still see the "org.apache.commons.mail". If i am not supposed to have this jar, org.apache.commons.mail in felix console, and if it is already available, i wonder why my bundle cries out for dependency org.apache.commons.mail as attached in snapshot. I am new to email workflow, would need your kind help.

In my pom.xml i have only exported the packages where my workflow code is, yet i see the commons.email

Manifest-Version: 1.0
Bnd-LastModified: 1380229199097
Build-Jdk: 1.7.0_21
Built-By: admin
Bundle-Category: cq5
Bundle-Description: Workflow to send email
Bundle-ManifestVersion: 2
Bundle-Name: EmailProcess
Bundle-SymbolicName: com.test.workflow.email
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Export-Package: com.test.workflow.email;uses:="javax.jcr,com.day.cq.colla
 b.commons,org.apache.sling.jcr.api,javax.mail.internet,org.apache.commo
 ns.mail,com.day.cq.search,org.apache.sling.api.resource,com.day.cq.work
 flow.metadata,com.day.cq.mailer,com.day.cq.workflow,com.day.cq.search.r
 esult,com.day.cq.workflow.exec,com.day.cq.commons";version="1.0.0",com.
 test.email.constants;version="1.0.0"
Implementation-Title: Custom Email Workflow
Implementation-Vendor: Test
Implementation-Version: 1.0.1
Import-Package: com.day.cq.collab.commons,com.day.cq.commons,com.day.cq.
 mailer,com.day.cq.search,com.day.cq.search.result,com.day.cq.workflow,c
 om.day.cq.workflow.exec,com.day.cq.workflow.metadata,javax.jcr;version=
 "[2.0,3)",javax.mail.internet;version="[1.4,2)",org.apache.commons.mail
 ;version="[1.3,2)",org.apache.sling.api.resource;version="[2.2,3)",org.
 apache.sling.jcr.api;version="[2.1,3)"
Service-Component: OSGI-INF/com.test.workflow.email.EmailWorkflow.xml
Tool: Bnd-1.50.0

 

In felix console, without manually installing org.apache.commons.mail, it just cries out for dependency

com.day.cq.collab.commons from com.day.cq.collab.cq-collab-commons (154)
com.day.cq.commons from com.day.cq.cq-commons (178)
com.day.cq.mailer from com.day.cq.cq-mailer (193)
com.day.cq.search from com.day.cq.cq-search (200)
com.day.cq.search.result from com.day.cq.cq-search (200)
com.day.cq.workflow from com.day.cq.workflow.cq-workflow-api (211)
com.day.cq.workflow.exec from com.day.cq.workflow.cq-workflow-api (211)
com.day.cq.workflow.metadata from com.day.cq.workflow.cq-workflow-api (211)
javax.jcr,version=[2.0,3) from org.apache.sling.jcr.jcr-wrapper (71)
javax.mail.internet,version=[1.4,2) from com.day.commons.osgi.wrapper.mail (101)
org.apache.commons.mail,version=[1.3,2) -- Cannot be resolved

Avatar

Employee

NitroHazeDev wrote...

justin_at_adobe wrote...

The problem is that you are embedding commons-email. Don't do this. Your bundle needs to import org.apache.commons. 

 

Justin,

I totally get it when you say don't embed commons-email, i must say that the workflow executes just perfect, thanks, but am wondering if i should manually install a jar- commons-email in felix console and have it being imported by the bundle?

I was wondering if i was to install the commons-email jar in felix or not, if i am doing something right?.

Regards,

 

There's already a bundle of commons-email deploy as it is a dependency of the CQ Mail service. So there's no reason to deploy another one.