Alfresco 4 Customize inbound email handler

Posted on Thursday, November 1, 2012

This document shows how to override the default Alfresco
email handler. This document assumes
you already have Alfresco 4.0 Community Edition installed you have inbound
email already configured.

If you do not have this done you can look at my other guide Alfresco_4_Install_on_ubuntu_12_04_and_make_folder_emailable

For this particular install I am using Alfresco 4.0.e on
Ubuntu 12.04

Why?

Why would you want to override the default inbound email
handler?

Well, I am sure you can think of many reasons, for me I had
a project for a company that would forward emails from gmail and send them all
to the same folder. The custom email
handler would check for an attachment and based on its name save it to a
different folder. Also it only saved
the attached file and not the email itself.

According to http://wiki.alfresco.com/wiki/Inbound_SMTP_Email_Server_Configuration#Configuration
[2] you should be able to copy this folder over to / opt/tomcat/shared/classes/alfresco/extension/subsystems/email/InboundSMTP/inboundSMTP-context.xml and have it override the default alfresco
XML file, but I can never get this to
work for some reason. I merely copied it
over, but it never overrides, if anyone has any advice on this I would love to
hear it.

Create your custom class and install it

Now that the default
inbound email handler is overridden a new class needs to be created to replace
it. In the prior section we are looking
for a class named com.10x13.alfresco.email.CustomFolderEmailMessageHandler . Therefore
we need to create a program with this same name.

Now before I go too
far I want to say this example overrides folderEmailMessageHandler which
only overrides the inbound email handler for folders. There are other handlers for other objects
in alfresco.

Before we get into
programming it’s probably a good idea to update the logger so we can log some
messages. To do this you need to edit /opt/tomcat/webapps/alfresco/WEB-INF/classes/log4j.properties

now send an email
into your system (of course this will
only work if you had your alfresco set up to accept inbound emails before
starting this guide, this guide does not cover that) in my case I set it up to accept emails to
inbox. So since this is an Amazon
server I set an email to inbox@ec2-23-11-12.compute-1.amazonaws.com

Now if you look at the folder you emailed into (in my case its in share)

The e-mail is there.

Then look at the log you tailed and you should see

Now that is all well and good but all we really accomplished
was to write a log message out. Let’s
do something real.

In this part of the code you can see how you can get the
String for where the email was sent to “message.getTo()” who the email was sent from
“message.getFrom()” and the subject line “message.getSubject()”.

log.info("An Email was sent to:
" + toAddress);

log.info("An Email was sent
from: " + fromAddress);

log.info("An Email was sent with
the subject line of: " + subject);

This is just the log messages

for(EmailMessagePart attachment:
message.getAttachments()) {

//Skip saving the email as an
html file

if(!attachment.getFileName().startsWith(subject)){

An email can contain several attachments so this is here to
iterate through each one. The if
statement is for a special case.
Alfresco considers the body of the email to be a file, well it creates
an html version of it. It names it
after the subject line plus a few characters the .html. This may not be the best way to skip
uploading this object but it works well enough for a demonstration.

log.info("attached file
is named: " + attachment.getFileName()

+
"And Has a size of: " + attachment.getSize() + " Bytes");

Another log message that gives the object name and size in
bytes

contentIs =
attachment.getContent();

mimeType = mimetypeService.guessMimetype(attachment.getFileName());

contentNodeRef =
addContentNode(getNodeService(),

folderNodeRef, attachment.getFileName(), true);

writeContent(contentNodeRef,
contentIs, mimeType,

attachment.getEncoding());

contentIs =
attachment.getContent(); gets the java.io.InputStream of the attachment.

mimeType =
mimetypeService.guessMimetype(attachment.getFileName());

This guesses the mimetype based on the name. There is
another one that guesses the mimetype based on the name and does a quick search
on the file, but that is more processing time.

contentNodeRef
= addContentNode(getNodeService(),

folderNodeRef, attachment.getFileName(), true);

If my memory serves me right on this one, it create a stub
file to write to in the correct location.
folderNodeRef must be the parent director you want to place this file
into. The Boolean on the end, if set to
true, will overwrite any file with the same name, if you set it to false it
will change its name so it can still be uploaded.

If I remember right I remember this being an issue with
action folders. If a folder will perform
an action when a new file is created within it then this addContentNode will
cause that action to happen even though we have yet to write to it, just a word
of warning… that is if I remember correctly.

3 comments:

I've been referencing your blog a lot lately, and I thank you for your Alfresco posts!

I think I've discovered how to extend the inboundSMTP-context.xml without simply overwriting the original. It appears that due to changes around 3.2-3.3 (https://issues.alfresco.com/jira/browse/ALF-4361), the new path for overwriting the inbound and outbound SMTP is now extension/subsystems/email/InboundSMTP/inbound/inboundSMTP-context.xml.