cancel
Showing results for 
Search instead for 
Did you mean: 

How to add 'CC' and 'BCC' list in javascript mail executer

chiranjeevi
Champ in-the-making
Champ in-the-making
Hi Friends,

   I have created a rule on update the document.

  I have added a javscript on created rule.

   below is my javascript.

var mail = actions.create("mail");
  mail.parameters.to = "abc@gmail.com"
  mail.parameters.subject = "Hello from JavaScript";
  mail.parameters.from = person.properties.email;
  mail.parameters.template = companyhome.childByNamePath("Data Dictionary/Email Templates/sample.ftl");
  mail.parameters.text = "Welcome";
  mail.execute(document);

  My problem is i have to add 'CC' and 'BCC' list also in the above javascript.

  I have tried with mail.parameters.cc and mail.parameters.bcc.  but, it's not working.

   is it possible in Alfresco?

   can any one help me in this issue?

   if possible which files i have to modify?

   Thanks in advance.
3 REPLIES 3

kriton
Champ in-the-making
Champ in-the-making
Bring this topic back up again, as I have an identical problem.

Anyone ? Smiley Happy

kriton
Champ in-the-making
Champ in-the-making
Ok I've figured this out in case anyone else has the same problem.

Basically the mail action does not support that. you have to actually modify the MailActionexecuter class. Here is my modified version of that class (I include the code for the whole class):



package org.alfresco.sample;

import java.io.Serializable;
/**
* Mail action executor implementation.
*
*/
public class MailActionExecuter extends ActionExecuterAbstractBase
    implements InitializingBean, TestModeable
{
    private static Log logger = LogFactory.getLog(MailActionExecuter.class);
   
    /**
     * Action executor constants
     */
    public static final String NAME = "mail";
    public static final String PARAM_TO = "to";
    public static final String PARAM_CC = "cc";
    public static final String PARAM_BCC = "bcc";
    public static final String PARAM_TO_MANY = "to_many";
    public static final String PARAM_CC_MANY = "cc_many";
    public static final String PARAM_BCC_MANY = "bcc_many";
    public static final String PARAM_SUBJECT = "subject";
    public static final String PARAM_TEXT = "text";
    public static final String PARAM_HTML = "html";
    public static final String PARAM_FROM = "from";
    public static final String PARAM_TEMPLATE = "template";
    public static final String PARAM_TEMPLATE_MODEL = "template_model";
    public static final String PARAM_IGNORE_SEND_FAILURE = "ignore_send_failure";
    public static final String PARAM_SEND_AFTER_COMMIT = "send_after_commit";
      
    /**
     * From address
     */
    private static final String FROM_ADDRESS = "alfresco@alfresco.org";
   
    private static final String REPO_REMOTE_URL = "http://localhost:8080/alfresco";
   
    /**
     * The java mail sender
     */
    private JavaMailSender javaMailSender;
   
    /**
     * The Template service
     */
    private TemplateService templateService;
   
    /**
     * The Person service
     */
    private PersonService personService;
   
    /**
     * The Authentication service
     */
    private AuthenticationService authService;
   
    /**
     * The Node Service
     */
    private NodeService nodeService;
   
    /**
     * The Authority Service
     */
    private AuthorityService authorityService;
   
    /**
     * The Service registry
     */
    private ServiceRegistry serviceRegistry;
   
    /**
     * Mail header encoding scheme
     */
    private String headerEncoding = null;
   
    /**
     * Default from address
     */
    private String fromAddress = null;
   
    /**
     * Default alfresco installation url
     */
    private String repoRemoteUrl = null;
   
    private boolean sendTestMessage = false;
    private String testMessageTo = null;
    private String testMessageSubject = "Test message";
    private String testMessageText = "This is a test message.";

    /**
     * Test mode prevents email messages from being sent.
     * It is used when unit testing when we don't actually want to send out email messages.
     *
     * MER 20/11/2009 This is a quick and dirty fix. It should be replaced by being
     * "mocked out" or some other better way of running the unit tests.
     */
    private boolean testMode = false;
    private MimeMessage lastTestMessage;
   
    /**
     * @param javaMailSender    the java mail sender
     */
    public void setMailService(JavaMailSender javaMailSender)
    {
        this.javaMailSender = javaMailSender;
    }
   
    /**
     * @param templateService   the TemplateService
     */
    public void setTemplateService(TemplateService templateService)
    {
        this.templateService = templateService;
    }
   
    /**
     * @param personService     the PersonService
     */
    public void setPersonService(PersonService personService)
    {
        this.personService = personService;
    }
   
    /**
     * @param authService       the AuthenticationService
     */
    public void setAuthenticationService(AuthenticationService authService)
    {
        this.authService = authService;
    }
   
    /**
     * @param serviceRegistry   the ServiceRegistry
     */
    public void setServiceRegistry(ServiceRegistry serviceRegistry)
    {
        this.serviceRegistry = serviceRegistry;
    }
   
    /**
     * @param authorityService  the AuthorityService
     */
    public void setAuthorityService(AuthorityService authorityService)
    {
        this.authorityService = authorityService;
    }

    /**
     * @param nodeService       the NodeService to set.
     */
    public void setNodeService(NodeService nodeService)
    {
        this.nodeService = nodeService;
    }
   
    /**
     * @param headerEncoding     The mail header encoding to set.
     */
    public void setHeaderEncoding(String headerEncoding)
    {
        this.headerEncoding = headerEncoding;
    }

    /**
     * @param fromAddress   The default mail address.
     */
    public void setFromAddress(String fromAddress)
    {
        this.fromAddress = fromAddress;
    }

    /**
     *
     * @param repoRemoteUrl The default alfresco installation url
     */
    public void setRepoRemoteUrl(String repoRemoteUrl)
    {
        this.repoRemoteUrl = repoRemoteUrl;
    }
   
    public void setTestMessageTo(String testMessageTo)
    {
        this.testMessageTo = testMessageTo;
    }
   
    public void setTestMessageSubject(String testMessageSubject)
    {
        this.testMessageSubject = testMessageSubject;
    }
   
    public void setTestMessageText(String testMessageText)
    {
        this.testMessageText = testMessageText;
    }

    public void setSendTestMessage(boolean sendTestMessage)
    {
        this.sendTestMessage = sendTestMessage;
    }

   
    @Override
    public void init()
    {
        super.init();
        if (sendTestMessage)
        {
            Map<String, Serializable> params = new HashMap<String, Serializable>();
            params.put(PARAM_TO, testMessageTo);
            params.put(PARAM_SUBJECT, testMessageSubject);
            params.put(PARAM_TEXT, testMessageText);
           
            Action ruleAction = serviceRegistry.getActionService().createAction(NAME, params);
            executeImpl(ruleAction, null);
        }
    }

    /**
     * Initialise bean
     */
    public void afterPropertiesSet() throws Exception
    {
        if (fromAddress == null || fromAddress.length() == 0)
        {
            fromAddress = FROM_ADDRESS;
        }
       
        if (repoRemoteUrl == null || repoRemoteUrl.length() == 0)
        {
            repoRemoteUrl = REPO_REMOTE_URL;
        }
    }
   
    /**
     * Send an email message
     *
     * @throws AlfrescoRuntimeExeption
     */
    @Override
    protected void executeImpl(
            final Action ruleAction,
            final NodeRef actionedUponNodeRef)
    {
        if (sendAfterCommit(ruleAction))
        {
        AlfrescoTransactionSupport.bindListener(new TransactionListenerAdapter()
        {
            @Override
            public void afterCommit()
                {               
                    prepareAndSendEmail(ruleAction, actionedUponNodeRef);           
                }
            });           
        }
        else
            {
            prepareAndSendEmail(ruleAction, actionedUponNodeRef);           
            }
    }
   
    private boolean sendAfterCommit(Action action)
    {
        Boolean sendAfterCommit = (Boolean) action.getParameterValue(PARAM_SEND_AFTER_COMMIT);
        return sendAfterCommit == null ? false : sendAfterCommit.booleanValue();
    }
   
    @SuppressWarnings("unchecked")
    private void torecipient(MimeMessageHelper message, Action ruleAction, String param) throws MessagingException {
        // set recipient
        String to = (String)ruleAction.getParameterValue(param);
        if (to != null && to.length() != 0)
        {
           if (param.equals(PARAM_TO))
              message.setTo(to);
           else if (param.equals(PARAM_CC))
              message.setCc(to);
           else if (param.equals(PARAM_BCC))
              message.setBcc(to);

        }
        else
        {
           
            // see if multiple recipients have been supplied - as a list of authorities
            Serializable authoritiesValue = ruleAction.getParameterValue(param+"_many");
            List<String> authorities = null;
            if (authoritiesValue != null)
            {
                if (authoritiesValue instanceof String)
                {
                    authorities = new ArrayList<String>(1);
                    authorities.add((String)authoritiesValue);
                }
                else
                {
                    authorities = (List<String>)authoritiesValue;
                }
            }
           
            if (authorities != null && authorities.size() != 0)
            {
                List<String> recipients = new ArrayList<String>(authorities.size());
                for (String authority : authorities)
                {
                    AuthorityType authType = AuthorityType.getAuthorityType(authority);
                    if (authType.equals(AuthorityType.USER))
                    {
                        if (personService.personExists(authority) == true)
                        {
                            NodeRef person = personService.getPerson(authority);
                            String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
                            if (address != null && address.length() != 0 && validateAddress(address))
                            {
                                recipients.add(address);
                            }
                        }
                    }
                    else if (authType.equals(AuthorityType.GROUP) || authType.equals(AuthorityType.EVERYONE))
                    {
                        // Notify all members of the group
                        Set<String> users;
                        if (authType.equals(AuthorityType.GROUP))
                        {       
                            users = authorityService.getContainedAuthorities(AuthorityType.USER, authority, false);
                        }
                        else
                        {
                            users = authorityService.getAllAuthorities(AuthorityType.USER);
                        }
                       
                        for (String userAuth : users)
                        {
                            if (personService.personExists(userAuth) == true)
                            {
                                NodeRef person = personService.getPerson(userAuth);
                                String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
                                if (address != null && address.length() != 0)
                                {
                                    recipients.add(address);
                                }
                            }
                        }
                    }
                }
               
                if(recipients.size() > 0)
                {
                   if (param.equals(PARAM_TO))
                      message.setTo(recipients.toArray(new String[recipients.size()]));
                   else if (param.equals(PARAM_CC))
                      message.setCc(recipients.toArray(new String[recipients.size()]));
                   else if (param.equals(PARAM_BCC))
                      message.setBcc(recipients.toArray(new String[recipients.size()]));
                   
                }
                else
                {
                   if (param.equals(PARAM_TO))
                    // All recipients were invalid
                    throw new MailPreparationException(
                            "All recipients for the mail action were invalid"
                    );
                }
            }
            else
            {
               if (param.equals(PARAM_TO))
                // No recipients have been specified
                throw new MailPreparationException(
                        "No recipient has been specified for the mail action"
                );
            }
        }
    }
   
    private void prepareAndSendEmail(final Action ruleAction, final NodeRef actionedUponNodeRef)
    {
        // Create the mime mail message
        MimeMessagePreparator mailPreparer = new MimeMessagePreparator()
        {
            @SuppressWarnings("unchecked")
            public void prepare(MimeMessage mimeMessage) throws MessagingException
            {
                if (logger.isDebugEnabled())
                {
                   logger.debug(ruleAction.getParameterValues());
                }
               
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
               
                // set header encoding if one has been supplied
                if (headerEncoding != null && headerEncoding.length() != 0)
                {
                    mimeMessage.setHeader("Content-Transfer-Encoding", headerEncoding);
                }
               
                torecipient(message, ruleAction, PARAM_TO);
                torecipient(message, ruleAction, PARAM_CC);
                torecipient(message, ruleAction, PARAM_BCC);
               
                    
                // from person
                NodeRef fromPerson = null;
                if (! authService.isCurrentUserTheSystemUser())
                {
                    fromPerson = personService.getPerson(authService.getCurrentUserName());
                }
               
                // set subject line
                message.setSubject((String)ruleAction.getParameterValue(PARAM_SUBJECT));
               
                // See if an email template has been specified
                String text = null;
                NodeRef templateRef = (NodeRef)ruleAction.getParameterValue(PARAM_TEMPLATE);
                if (templateRef != null)
                {

                    Map<String, Object> suppliedModel = null;
                    if(ruleAction.getParameterValue(PARAM_TEMPLATE_MODEL) != null)
                    {
                        Object m = ruleAction.getParameterValue(PARAM_TEMPLATE_MODEL);
                        if(m instanceof Map)
                        {
                            suppliedModel = (Map<String, Object>)m;
                        }
                        else
                        {
                            logger.warn("Skipping unsupported email template model parameters of type "
                                    + m.getClass().getName() + " : " + m.toString());
                        }
                    }
                   
                    // build the email template model
                    Map<String, Object> model = createEmailTemplateModel(actionedUponNodeRef, suppliedModel, fromPerson);
                   
                    // process the template against the model
                    text = templateService.processTemplate("freemarker", templateRef.toString(), model);
                }
               
                // set the text body of the message
               
                boolean isHTML = false;
                if (text == null)
                {
                    text = (String)ruleAction.getParameterValue(PARAM_TEXT);
                }
               
                if (text != null)
                {
                    // Note: only simplistic match here - expects <html tag at the start of the text
                    String htmlPrefix = "<html";
                    if (text.length() >= htmlPrefix.length() &&
                            text.substring(0, htmlPrefix.length()).equalsIgnoreCase(htmlPrefix))
                    {
                        isHTML = true;
                    }
                }
                else
                {
                    text = (String)ruleAction.getParameterValue(PARAM_HTML);
                    if (text != null)
                    {
                        // assume HTML
                        isHTML = true;
                    }
                }
               
                if (text != null)
                {
                   logger.fatal("NOT FATAL: 4 –> Setting Text");

                    message.setText(text, isHTML);
                }
               
                // set the from address
                String fromActualUser = null;
                if (fromPerson != null)
                {
                    fromActualUser = (String) nodeService.getProperty(fromPerson, ContentModel.PROP_EMAIL);
                }
               
                if (fromActualUser != null && fromActualUser.length() != 0)
                {
                    message.setFrom(fromActualUser);
                }
                else
                {
                    String from = (String)ruleAction.getParameterValue(PARAM_FROM);
                    if (from == null || from.length() == 0)
                    {
                        message.setFrom(fromAddress);
                    }
                    else
                    {
                        message.setFrom(from);
                    }
                }
            }
        };
       
        try
        {
            // Send the message unless we are in "testMode"
            if(!testMode)
            {
                javaMailSender.send(mailPreparer);
            }
            else
            {
               try {
                  MimeMessage mimeMessage = javaMailSender.createMimeMessage();
                  mailPreparer.prepare(mimeMessage);
                  lastTestMessage = mimeMessage;
               } catch(Exception e) {
                  System.err.println(e);
               }
            }
        }
        catch (MailException e)
        {
            String to = (String)ruleAction.getParameterValue(PARAM_TO);
            if (to == null)
            {
               Object obj = ruleAction.getParameterValue(PARAM_TO_MANY);
               if (obj != null)
               {
                  to = obj.toString();
               }
            }
           
            // always log the failure
            logger.error("Failed to send email to " + to, e);
           
            // optionally ignore the throwing of the exception
            Boolean ignoreError = (Boolean)ruleAction.getParameterValue(PARAM_IGNORE_SEND_FAILURE);
            if (ignoreError == null || ignoreError.booleanValue() == false)
            {
                throw new AlfrescoRuntimeException("Failed to send email to:" + to, e);
            }  
        }
        catch (NullPointerException e)
        {
            String to = (String)ruleAction.getParameterValue(PARAM_TO);
            if (to == null)
            {
               Object obj = ruleAction.getParameterValue(PARAM_TO_MANY);
               if (obj != null)
               {
                  to = obj.toString();
               }
            }
            logger.error("NullPointerException: "+e.getMessage());
            // always log the failure
            logger.error("Failed to send email to " + to, e);
           
            // optionally ignore the throwing of the exception
            Boolean ignoreError = (Boolean)ruleAction.getParameterValue(PARAM_IGNORE_SEND_FAILURE);
            if (ignoreError == null || ignoreError.booleanValue() == false)
            {
                throw new AlfrescoRuntimeException("Failed to send email to:" + to, e);
            }  
        }
    }
   
   
    /**
     * Return true if address has valid format
     * @param address
     * @return
     */
    private boolean validateAddress(String address)
    {
        boolean result = false;
       
        EmailValidator emailValidator = EmailValidator.getInstance();
        if (emailValidator.isValid(address))
        {
            result = true;
        }
        else
        {
            logger.error("Failed to send email to '" + address + "' as the address is incorrectly formatted" );
        }
     
        return result;
    }

   /**
    * @param ref    The node representing the current document ref (or null)
    *
    * @return Model map for email templates
    */
   private Map<String, Object> createEmailTemplateModel(NodeRef ref, Map<String, Object> suppliedModel, NodeRef fromPerson)
   {
      Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
     
      if (fromPerson != null)
      {
          model.put("person", new TemplateNode(fromPerson, serviceRegistry, null));
      }     
     
      if (ref != null)
      {
          model.put("document", new TemplateNode(ref, serviceRegistry, null));
          NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(ref).getParentRef();
          model.put("space", new TemplateNode(parent, serviceRegistry, null));
      }
     
      // current date/time is useful to have and isn't supplied by FreeMarker by default
      model.put("date", new Date());
     
      // add custom method objects
      model.put("hasAspect", new HasAspectMethod());
      model.put("message", new I18NMessageMethod());
      model.put("dateCompare", new DateCompareMethod());
     
      // add URLs
      model.put("url", new URLHelper(repoRemoteUrl));
      model.put(TemplateService.KEY_SHARE_URL, UrlUtil.getShareUrl(this.serviceRegistry.getSysAdminParams()));
     
      // if the caller specified a model, use it without overriding
      if(suppliedModel != null && suppliedModel.size() > 0)
      {
          for(String key : suppliedModel.keySet())
          {
              if(model.containsKey(key))
              {
                  if(logger.isDebugEnabled())
                  {
                      logger.debug("Not allowing overwriting of built in model parameter " + key);
                  }
              }
              else
              {
                  model.put(key, suppliedModel.get(key));
              }
          }
      }
     
      // all done
      return model;
   }
   
    /**
     * Add the parameter definitions
     */
    @Override
    protected void addParameterDefinitions(List<ParameterDefinition> paramList)
    {
        paramList.add(new ParameterDefinitionImpl(PARAM_TO, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_TO)));
        paramList.add(new ParameterDefinitionImpl(PARAM_TO_MANY, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_TO_MANY), true));
        paramList.add(new ParameterDefinitionImpl(PARAM_CC, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_CC)));
        paramList.add(new ParameterDefinitionImpl(PARAM_CC_MANY, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_CC_MANY), true));
        paramList.add(new ParameterDefinitionImpl(PARAM_BCC, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_BCC)));
        paramList.add(new ParameterDefinitionImpl(PARAM_BCC_MANY, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_BCC_MANY), true));
        paramList.add(new ParameterDefinitionImpl(PARAM_SUBJECT, DataTypeDefinition.TEXT, true, getParamDisplayLabel(PARAM_SUBJECT)));
        paramList.add(new ParameterDefinitionImpl(PARAM_TEXT, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_TEXT)));
        paramList.add(new ParameterDefinitionImpl(PARAM_FROM, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_FROM)));
        paramList.add(new ParameterDefinitionImpl(PARAM_TEMPLATE, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_TEMPLATE), false, "ac-email-templates"));
        paramList.add(new ParameterDefinitionImpl(PARAM_TEMPLATE_MODEL, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_TEMPLATE_MODEL), true));
        paramList.add(new ParameterDefinitionImpl(PARAM_IGNORE_SEND_FAILURE, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_IGNORE_SEND_FAILURE)));
    }

    public void setTestMode(boolean testMode)
    {
        this.testMode = testMode;
    }

    public boolean isTestMode()
    {
        return testMode;
    }

    /**
     * Returns the most recent message that wasn't sent
     *  because TestMode had been enabled.
     */
    public MimeMessage retrieveLastTestMessage()
    {
        return lastTestMessage;
    }
   
    /**
     * Used when test mode is enabled.
     * Clears the record of the last message that was sent.
     */
    public void clearLastTestMessage()
    {
        lastTestMessage = null;
    }

    public static class URLHelper
    {
        String contextPath;
        String serverPath;
       
        public URLHelper(String repoRemoteUrl)
        {
            String[] parts = repoRemoteUrl.split("/");
            this.contextPath = "/" + parts[parts.length - 1];
            this.serverPath = parts[0] + "//" + parts[2];
        }
       
        public String getContext()
        {
           return this.contextPath;
        }

        public String getServerPath()
        {
           return this.serverPath;
        }
    }
}

You can use the sdk to apply the changes. Build a jar using the SDK CustomAction example. This is how your context xml should look like:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
     <!– Override mail Action Bean –>
    <bean id="mail" class="org.alfresco.sample.MailActionExecuter" parent="action-executer">
      <property name="mailService">
         <ref bean="mailService"></ref>
      </property>
      <property name="templateService">
         <ref bean="templateService"></ref>
      </property>
      <property name="personService">
         <ref bean="personService"></ref>
      </property>
      <property name="authenticationService">
         <ref bean="authenticationService"></ref>
      </property>
      <property name="nodeService">
         <ref bean="nodeService"></ref>
      </property>
      <property name="authorityService">
         <ref bean="authorityService"></ref>
      </property>
      <property name="serviceRegistry">
         <ref bean="ServiceRegistry"></ref>
      </property>
   </bean>
     
</beans>


Where this custom jar, developed using instructions above should be placed in order to be read by Alfresco Share web application?