in Alfresco

Alfresco Email Tracking – part I

Introduction

Currently there are more than enough email tracking services that allow you to see when and if email that you have sent has been opened, from what location and when. Few that i like are YesWare , Signals, contactMonkey also there are many others.

Check the code https://github.com/savicprvoslav/alfresco-mail-tracking-module

How do this services work??

One of the ways is to append you email with img tag. Image is loaded from their servers that is 1×1 px and every download of this image is converted to one email opening. Next startup will definitely be this kind of service, just saying if anyone is interested let me know :)…

Lets talk in alfresco language now, alfresco sends emails all the time, invite user , notify space users and so on, but alfresco does not have email tracking ability UNTIL NOW :). I as the administrator of multiple servers really like to know if user received my invitation to the space/site/project and if he actually read it, so this is why this feature is developed.  Lets move on how this is done….

Solution

Alfresco blog is finally going to use github and you can find all of the code here. If you look at the code you will be able to see few things like models, messages, webscripts… here we are going to explain how does this work.

Model

For this feature we have developed a nice model and type called ab:emailTracked . EmailTracked type has few properties that you can see below .

<type name="ab:emailTracked">
   <title>Track Email</title>
   <parent>cm:folder</parent>
<properties>
 <property name="ab:subject">
   <type>d:text</type>
   <mandatory>true</mandatory>
 </property>
 <property name="ab:mailDate">
   <type>d:date</type>
   <mandatory>true</mandatory>
 </property>

 <property name="ab:receiver">
   <type>d:text</type>
   <mandatory>true</mandatory>
 </property>
 <property name="ab:opened">
   <type>d:boolean</type>
   <mandatory>true</mandatory>
 </property>
 <property name="ab:openedDate">
   <type>d:date</type>
   <mandatory>true</mandatory>
 </property>
</properties>
 </type>

Parent is selected to be folder so we can put details on every opening of the email inside it, like who opened it, when, what browser, what IP address and location… Properties of this type are

  • Subject, subject of the email sent
  • MailDate, when email was sent
  • Receiver, what is the user receiving the email
  • Opened, did he opened it ever
  • OpenedDate,when was the last opening

Outbound SMTP SubSystem overriding

To pull this off we needed to override outbound SMTP subsystem and mailService. Overriding this subsystem is done by adding outboundSMTP-context.xml to this path

\src\main\amp\config\alfresco\extension\subsystems\email\OutboundSMTP\outbound\

After this we needed to specify our own class for mailService implementation

<bean id="mailService" class="com.alfrescoblog.service.ABAlfrescoJavaMailSender">...

MailService implementation is done using next code

public class ABAlfrescoJavaMailSender extends AlfrescoJavaMailSender {

 private static final String CONTENT_TYPE_HTML = "text/html";

 public void setNodeService(NodeService nodeService) {
 this.nodeService = nodeService;
 }

 @Override
 public void send(MimeMessage mimeMessage) throws MailException {
   modifyBody(mimeMessage);
   super.send(mimeMessage);
 }

 @Override
 public void send(MimeMessage[] mimeMessages) throws MailException {
   for (MimeMessage mm : mimeMessages) {
    modifyBody(mm);
   }
   super.send(mimeMessages);
 }

If you take a look at the code you can see that every email that is sent is modified in the method modifyBody. What this method does is it adds html like this in the end of the email and sets content type to HTML by default.

<img src="[pathToTheServer]/alfresco/service/track"

Tracking and java webscripts

We mentioned track webscript above and this is implemented as java webscript. Java webscripts are implemented by adding desc xml, we have created track.get.desc.xml

<webscript>
 <shortname>Track evetn</shortname>
 <description>Track Event</description>
 <url>/track</url>
 <format default="html">argument</format>
 <authentication>none</authentication>
 <transaction>required</transaction>
</webscript>

As you can notice authentication is set to none, reason for this is that person who opens the email does not have to login in alfresco. Of course we take care of this in the webscript is self and runAs system user.

Every java webscript needs to have spring configuration in order to work.

<bean id="webscript.com.alfrescoblog.webscript.track.get" 
     class="com.alfrescoblog.webscript.Track"  parent="webscript">
   <property name="serviceRegistry">
    <ref bean="ServiceRegistry" />
   </property>
</bean>

How does one create webscript that serves gif that is transparent and 1×1 px ?

After we have found a number of ways how this gif should not be served we striked gold with this that we will share with you.

private static final byte[] GIF = { 71, 73, 70, 56, 57, 97, 1, 0, 1, 0,
 -16, 0, 0, 0, 0, 0, 0, 0, 0, 33, -7, 4, 1, 0, 0, 0, 0, 44, 0, 0, 0,
 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59 };

...
public void execute(WebScriptRequest req, final WebScriptResponse res)
 throws IOException {
final String id = req.getParameter("id");

 AuthenticationUtil.runAs(new RunAsWork<Void>() {

 @Override
 public Void doWork() throws Exception {
.....

 res.setContentType("image/gif");
 res.setHeader("Content-Type", "image/gif");
 res.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
 res.setHeader("Pragma", "no-cache");
 res.getOutputStream().write(GIF);
 return null;
 }

}, AuthenticationUtil.getSystemUserName());

So when user opens his email this webscript is triggered, download is tracked and we know that user opened the email. YES!

How does this look in the alfresco browser?

Email Tracked Alfresco Browser

Email Tracked Alfresco Browser

So far we did it only in the alfresco browser and alfresco share customizations will be part of the next blog post that we are preparing.

What does one have to do to make this module work?

Only thing you need to setup is to add one property to your config properties ( shared, repository …)

email.tracker.domainaddr=http://localhost:8080/alfresco/service

 

 Summary

This module allows you to track every email that is sent by alfresco in beautiful and easy to use, this feature is seamlessly integrated into your alfresco system.

If you have any questions, problems and so on please let us know!

https://github.com/savicprvoslav/alfresco-mail-tracking-module

 

Don't be shellfish...Tweet about this on TwitterShare on LinkedInShare on Google+Share on RedditShare on Facebook

Was this helpful ?

    • Thanks,
      very simple when user who received the email loads the 1x1px image we do not want to make him authenticate to alfresco. So this way we set runAs user that has permissions to required data in alfresco.

      Hope this explains it, if you have any other questions let us know.