cancel
Showing results for 
Search instead for 
Did you mean: 

Sending email in an Action

mangar
Star Contributor
Star Contributor
I am trying to send an email when a document is added to alfresco but the email address is NOT a user of alfresco.  I have made a custom action and it is triggered fine. However, when I try and send it through regular old java mail I get this error:

javax.mail.NoSuchProvidorException: smtp

here is the relevant code:
InternetAddress[] toAddrs = new InternetAddress[1];
toAddrs[0] = new InternetAddress(email);
Properties props = System.getProperties();
props.put("mail.smtp.host", "smtp.localhost");
Session session = Session.getDefaultInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("AlfrescoEmail"));
msg.setRecipients(Message.RecipientType.TO,toAddrs);
msg.setText(userName+" has added a document. Enjoy.");
Transport.send(msg);

this code works fine outside of Alfresco.

The internet said that this happens when two different instances of javamail exist.  I assume that Alfresco has one.  Does anyone know how to send a custom email through alfresco? I cannot find an example anywhere. I found plenty of examples of how to setup Alfresco to mail stuff, but not on how to actually send a mail.

Thanks for any help.
5 REPLIES 5

zbennett
Champ in-the-making
Champ in-the-making
I've been working on adapting an example from http://wiki.alfresco.com/wiki/3.3_JavaScript_API#Actions_API, but I'm having issues with my implementation.  My JavaScript and my error log are below.

JS:
// create mail action
var mail = actions.create("mail");
mail.parameters.to = "not@telling.com";
mail.parameters.subject = "Alfresco: discussion has been updated";
mail.parameters.from = "not@telling.com";
mail.parameters.template = search.findNode("path", ['workspace','SpacesStore','/Data Dictionary/Email Templates/notify_user_of_discussion_email.ftl']);

//mail.parameters.template = root.childByNamePath("Company Home/Data Dictionary/Email Templates/Notify Email Templates/notify_user_of_discussion_email.ftl");
//mail.parameters.text = "some text, in case template is not found";

// execute action against a document   
mail.execute(document);

Log:
10:19:41,637 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 08080407 Failed to execute script 'workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752': 08080406 Failed to send email to:not@telling.com
org.alfresco.scripts.ScriptException: 08080407 Failed to execute script 'workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752': 08080406 Failed to send email to:not@telling.com
   at org.alfresco.repo.jscript.RhinoScriptProcessor.execute(RhinoScriptProcessor.java:233)
   at org.alfresco.repo.processor.ScriptServiceImpl.executeScript(ScriptServiceImpl.java:181)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:135)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy220.executeScript(Unknown Source)
   at org.alfresco.repo.action.executer.ScriptActionExecuter.executeImpl(ScriptActionExecuter.java:163)
   at org.alfresco.repo.action.executer.ActionExecuterAbstractBase.execute(ActionExecuterAbstractBase.java:133)
   at org.alfresco.repo.action.ActionServiceImpl.directActionExecution(ActionServiceImpl.java:726)
   at org.alfresco.repo.action.executer.CompositeActionExecuter.executeImpl(CompositeActionExecuter.java:66)
   at org.alfresco.repo.action.executer.ActionExecuterAbstractBase.execute(ActionExecuterAbstractBase.java:133)
   at org.alfresco.repo.action.ActionServiceImpl.directActionExecution(ActionServiceImpl.java:726)
   at org.alfresco.repo.action.ActionServiceImpl.executeActionImpl(ActionServiceImpl.java:658)
   at org.alfresco.repo.action.ActionServiceImpl.executeAction(ActionServiceImpl.java:526)
   at sun.reflect.GeneratedMethodAccessor601.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:135)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy36.executeAction(Unknown Source)
   at org.alfresco.repo.rule.RuleServiceImpl.executeRule(RuleServiceImpl.java:1118)
   at org.alfresco.repo.rule.RuleServiceImpl.executePendingRule(RuleServiceImpl.java:1086)
   at org.alfresco.repo.rule.RuleServiceImpl.executePendingRulesImpl(RuleServiceImpl.java:1057)
   at org.alfresco.repo.rule.RuleServiceImpl.executePendingRules(RuleServiceImpl.java:1030)
   at org.alfresco.repo.rule.RuleTransactionListener.beforeCommit(RuleTransactionListener.java:57)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:738)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.doBeforeCommit(AlfrescoTransactionSupport.java:718)
   at org.alfresco.repo.transaction.AlfrescoTransactionSupport$TransactionSynchronizationImpl.beforeCommit(AlfrescoTransactionSupport.java:674)
   at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:927)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:737)
   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
   at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
   at org.alfresco.util.transaction.SpringAwareUserTransaction.commit(SpringAwareUserTransaction.java:472)
   at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:343)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:417)
   at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:434)
   at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:298)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:319)
   at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:177)
   at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:116)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
   at java.lang.Thread.run(Thread.java:619)
Caused by: org.alfresco.error.AlfrescoRuntimeException: 08080406 Failed to send email to:not@telling.com
   at org.alfresco.repo.action.executer.MailActionExecuter.executeImpl(MailActionExecuter.java:466)
   at org.alfresco.repo.action.executer.ActionExecuterAbstractBase.execute(ActionExecuterAbstractBase.java:133)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.alfresco.repo.management.subsystems.SubsystemProxyFactory$1.invoke(SubsystemProxyFactory.java:65)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy221.execute(Unknown Source)
   at org.alfresco.repo.action.ActionServiceImpl.directActionExecution(ActionServiceImpl.java:726)
   at org.alfresco.repo.action.ActionServiceImpl.executeActionImpl(ActionServiceImpl.java:658)
   at org.alfresco.repo.action.ActionServiceImpl.executeAction(ActionServiceImpl.java:526)
   at org.alfresco.repo.action.ActionServiceImpl.executeAction(ActionServiceImpl.java:512)
   at org.alfresco.repo.action.ActionServiceImpl.executeAction(ActionServiceImpl.java:735)
   at sun.reflect.GeneratedMethodAccessor638.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:135)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy36.executeAction(Unknown Source)
   at org.alfresco.repo.jscript.ScriptAction.executeImpl(ScriptAction.java:159)
   at org.alfresco.repo.jscript.ScriptAction.execute(ScriptAction.java:148)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:155)
   at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:243)
   at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:66)
   at org.mozilla.javascript.gen.c35._c0(workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752:15)
   at org.mozilla.javascript.gen.c35.call(workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752)
   at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:393)
   at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:2834)
   at org.mozilla.javascript.gen.c35.call(workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752)
   at org.mozilla.javascript.gen.c35.exec(workspace://SpacesStore/1e7e6759-d077-4401-bb04-a23c97004752)
   at org.alfresco.repo.jscript.RhinoScriptProcessor.executeScriptImpl(RhinoScriptProcessor.java:453)
   at org.alfresco.repo.jscript.RhinoScriptProcessor.execute(RhinoScriptProcessor.java:229)
   … 76 more
Caused by: org.springframework.mail.MailPreparationException: Could not prepare mail; nested exception is org.alfresco.service.cmr.repository.TemplateException: 08080405
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:368)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
   at org.alfresco.repo.action.executer.MailActionExecuter.executeImpl(MailActionExecuter.java:439)
   … 123 more
Caused by: org.alfresco.service.cmr.repository.TemplateException: 08080405
   at org.alfresco.repo.processor.TemplateServiceImpl.processTemplate(TemplateServiceImpl.java:183)
   at org.alfresco.repo.processor.TemplateServiceImpl.processTemplate(TemplateServiceImpl.java:194)
   at org.alfresco.repo.action.executer.MailActionExecuter$1.prepare(MailActionExecuter.java:397)
   at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:353)
   … 125 more
Caused by: java.lang.NullPointerException
   at org.alfresco.repo.template.ClassPathRepoTemplateLoader$RepoTemplateSource.lastModified(ClassPathRepoTemplateLoader.java:283)
   at org.alfresco.repo.template.ClassPathRepoTemplateLoader.getLastModified(ClassPathRepoTemplateLoader.java:99)
   at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:306)
   at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:235)
   at freemarker.template.Configuration.getTemplate(Configuration.java:487)
   at freemarker.template.Configuration.getTemplate(Configuration.java:452)
   at org.alfresco.repo.template.FreeMarkerProcessor.process(FreeMarkerProcessor.java:190)
   at org.alfresco.repo.processor.TemplateServiceImpl.processTemplate(TemplateServiceImpl.java:175)
   … 128 more


Enjoy the code!  Please let me know if you run into the same error and/or you know of a way to fix it…

*Edit: removed references to my email address to keep spammers, spiders, and bots away!

zbennett
Champ in-the-making
Champ in-the-making
I found my problem!  I was using search.findNode to locate my template because "root" was undefined, but my search was returning null.  I checked the JavaScript ScriptNode API and it looks like the definition of mail.parameters.template was outdated.

Here is my updated and working code:
// create mail action
var mail = actions.create("mail");
mail.parameters.to = "not@telling.com";
mail.parameters.subject = "Alfresco: discussion has been updated";
mail.parameters.from = "not@telling.com";
mail.parameters.template = companyhome.childByNamePath("Data Dictionary/Email Templates/Notify Email Templates/notify_user_of_discussion_email.ftl");
mail.parameters.text = "some text, in case template is not found";

// execute action against a document   
mail.execute(document);

Enjoy!  Let me know if you have any problems getting this set up…


*Edit: removed references to my email…again.

mangar
Star Contributor
Star Contributor
Any examples for Java?  I am extending ActionExecuterAbstractBase.

zbennett
Champ in-the-making
Champ in-the-making
I'm afraid not.  I still don't understand how to implement Java code in Alfresco…the whole SpringBeans thing is a mystery to me at this point.  If you can point me to some tutorials that explain how all of that works, I could start looking into it.  I am getting paid to learn how to develop for Alfresco, so I have time and resources available!

Back to the task at hand, though…  Is there a reason that you can't create a rule to execute a JS script to handle this part of your process?

mangar
Star Contributor
Star Contributor
Well, I don't know spring that well either, but here is how to make a java class into an action.
Step 1:  make a spring bean definition file.

call it action-services-custom-context.xml and put it in your extension folder. Here is a basic example:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="Test-Action" class="com.yourcompany.alfresco.extensions.actions.TestActionExecutioner" parent="action-executer">
   <property name="nodeService">
      <ref bean="nodeService" />
   </property>
   <property name="searchService">
        <ref bean="searchService"/>
   </property>
</bean>
</beans>

the 2 properties are not neccesary, but will allow you to have access to alfrescos CMS (nodeService) and do lucene querys (searchService)

Step 2:  make a Java class called TestActionExecutioner. (It must match the class propery above, package and all)

example:

package com.yourcompany.alfresco.extensions.actions;

import java.io.Serializable;
import java.util.*;

import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;

public class TestActionExecutioner extends ActionExecuterAbstractBase {

   public static final String NAME = "TestAction";

   private NodeService nodeService;
   private SearchService searchService;

      public void executeImpl(Action action, NodeRef actionedUponNodeRef)  {
         System.out.println("*******Hello Action World!!!!!*******");
      }

      protected void addParameterDefinitions(List<ParameterDefinition> paramList)   {
         // TODO fill in action parameter definitions
      }
     
      public void setNodeService(NodeService nodeService) {
         this.nodeService = nodeService;
      }
     
      public void setSearchService(SearchService searchService) {
         this.searchService = searchService;
      }

}

compile, deploy, restart.

if all goes well, you should see "Test-Action" in the dropdown list of actions when you create a new rule in alfresco. Add your rule, then trigger your rule, and you should see Hello Action World in the log file.

My real class tries to send an email int the executeImpl() method as shown above.

Hope this helps!