Beruflich Dokumente
Kultur Dokumente
This template provides a starting point for implementing email response in your process.
For example, suppose you want your process to send an email to a manager asking for
approval and you want them to respond to the email with "yes" or "no".
New in v2
The basics are all the same. v2 adds a generic email response sub-process that you can use
for demo or a quick initial implementation of your use case.
Download: 610-Community-EmailResponse-v2.export.zip
Overview
In Teamworks, even the processing of an inbound email is a process. This allows the same capabilities to
resolve exceptions in handling emails as in the any other process.
This process is invoked by a Teamworks' "Undercover" agent that polls (via pop or IMAP) a specific email
accounts.* To maintain transactional integrity as much as possible, the only processing done at the initial
polling level is to get an email and pass it to an event – the event initiates the process above. Once that
event is sent, all Teamworks standard transaction / state mgmt applies.
• *- Note : You could also have the email system (for example, a server macro in Outlook) send
Teamworks the email pro-actively instead of having Teamworks poll.
Determine the email type applies basic parsing, usually to the subject of the email, to determine the
'type' of the email. The type needs to identify if the email is 'recognized' and usually identifies the event-
type (specific UCA) that the email is for.
If unknown type, escalate ensures that if the type of an email cannot be determined, the email is not
ignored. It is sent to an admin for manual determination. At the same time an email reply is sent back to
the sender identifying that the email was not recognized.
At this point, there are two design approaches for how the admin resolves the unknown email type.
You could allow the admin to process the result of the email directly - this would mean the service they
execute would directly trigger events in the process. The other approach is to have the admin 'correct'
the email such that it can be processed. For example, the template implementation simply asks the
In any case, once the email type is determined, it is time to Process the Email. This determines the
information in the response - and in particular must determine the correlation parameters! One very
common correlation parameter is the instance Id (or task Id - if this is used, the email must be sent
after the task is created using a zero-length timer). There are some javascript functions available in the
template to parse 'responses' (see below). This step also includes triggering the appropriate process
event based on the response. Sometimes the email type will determine the event to fire, and sometimes
it is based on the content of the email.
Note: The distinction between 'email type' and this more detailed 'response' is somewhat arbitrary.
However, experience indicates that when email response is part of a process implementation, there is
often more than one part of the process that uses it, and therefore the notion of a higher-level 'email
type' serves to distinguish the different application of an email response.
Example Usage
Intro
There is an example that uses the template (described below). Here is the process that allows creating a
new instance and completing the approval via email:
Note: - v2 adds another step at the end that uses a re-usable subprocess.
To use the example, you need to first configure the EPV in the configuration folder. The settings
are:
To start, the example, you can either start the BPD manually, or run the "erEx_Send Email for Initiation"
service (see location below) - this service will prompt you for an email address and then send an email
that you can reply to.
For a quick demo, I usually hit play and enter the request manually. Once you show the
process moving forward from an email response, you have credibility to say, "and you can
have an email initiate a process" w/o needing to show it.
After you reply to the email, you will need to trigger the email polling since the polling UCA is disabled by
default. In fact, in development, I find it easiest to leave the UCA disabled and trigger the service myself
instead.
Assuming the instance is successfully initiated, a task is created (for tw_admin). In this task, you need to
enter the email address that will get an email for approval. Enter an email address and complete the task.
The process now sends an email to the address you entered and creates a task (for tw_admin). You can
either complete the task itself, or more to the point, go check the email. The email is an example that
allows you to either provide a response directly, or to fill in answers within the email. As a previous, here
is what the email looks like:
Dear ,
Description: ex
Amount: 0
Either reply to this email with yes or no, or place an x in the appropriate response below. You can
include comments in the body of the reply or in the comment []s below.
Approve:
[] Yes.
[] No.
[] Maybe.
--------
Comments: []
You can also click on of these buttons and then send the email:
Yes
No
Maybe
When you dive into the example, you'll note that the response to this email not only correlates on
the instance id, but also requires that the 'from address' of the email match the email specified in the
process.
The example usage also demonstrates that there is no reason your could also allow the user to complete
the same step via a standard task - in fact, this is a best practice in my experience.
You can re-use this subProcess in your own process outside of this example. It makes it
very easy to include email response in a demo, or to demonstrate it for playback 1.
After configuring the example (and testing it), you can easy add an email response example to your
process! Drag this sub-process into your process, configure the inputs, map the outputs, and you are
all set! It implements a generic approval where the first line of the email response is returned as one
variable (called the "response"), and the rest of the email reply is returned as another variable (called the
"comments").
Inputs:
Outputs:
• response - the first line of the email reply (for example, "yes" or "no").
• comments - the rest of the email response.
Template
The template provided implements the design discussed above and provides a baseline to get started.
It is expected that all components in the template (except maybe the contents of the "Polling" folder and
the "_Email Processing" BPD will be edited as part of your implementation. Here is a brief explanation of
every components:
1. _Start eMail Received Process (service) - the UCA service that initiates the process email BPD
2. _Start eMail Received Process (uca) - the event UCA that initiates the process email BPD.
3. _EmailPollingConfiguration (epv)- this EPV contains the settings used by the template.
4. _Get Email Polling Configuration Values (service)- this service is used to access the values specified
in the BPD - it is the only component that references the EPV. This is done so that you can change
where / how the configuration values are stored and only need to change the implementation of this
service (instead of everywhere the EPV is used).
5. _Email Polling (service) - the UCA service that polls the email inbox configured in the EPV. This is
also a root process b/c if you want to expose the polling as a manual option, you could do this via a
favorite.
6. _Email Polling (uca) - the time-based UCA that initiates polling the email inbox configured in the
EPV. This time-based UCA is disabled by default. And since no timing is selected, if you enable the
The configuration EPV provides the configuration parameters for the template. It is encapsulated by
the service above for two reasons: (1) to create a single point to edit the EPV name after importing the
template, and (2) you can change how these configuration settings are maintained (eg, in a properties
file instead of an EPV) and only modify this one service.
After configuring the epv (and service to get the value), you will need to edit the "determine email type"
service. The template implementation simply looks for a particular value in the subject.
You will also need to edit the "Unknown Email Type" service to allow specifying your email type in the
dropdown.
Finally, you will need to edit "Process Email" to both parse the email response and fire the appropriate
UCA. Sample javascript functions are provided to aid in the parsing (please submit more efficient
implementations of these methods and others!).
The best way to understand the template is to review the example usage provided.
Javascript functions
Here are the javascript functions provided in the template in the components where I expect you to be
parsing emails. (see the Example Usage).
Note: These implementation may not be efficient or correct, but they work for me. Please post
improvements and addition functions that you develop.
For use when the user can respond with a 'simple' response (eg, yes or no), and comments on following
lines:
//Returns the body only -- should not include the original email.
function getResponseOnly(emailBody) {
var dashIndex = emailBody.indexOf("---");
var origIndex = emailBody.indexOf("Original");
var fromIndex = emailBody.indexOf("From");
if (dashIndex == -1) { dashIndex = 999999; }
if (origIndex == -1) { origIndex = 999999; }
if (fromIndex == -1) { fromIndex = 999999; }
var bEnd = Math.min(dashIndex, origIndex, fromIndex );
if (bEnd > -1) {
return emailBody.substring(0,bEnd);
} else {
return emailBody;
}
}
For use when the user needs to respond with more structured data.
//Returns the value corresponding to the position that the user enters and x (resulting in [x])
// <tag>:
// [] <value1>.
// [] <value2>.
// [] ... .
// ---
function getTagSelection(emailBody,tag) {
var emailBodyLC = emailBody.toLowerCase();
var tagPos = emailBody.indexOf(tag + ":");
var endTagPos = emailBody.indexOf("---",tagPos);
if (tagPos > -1) {
var selectionPos = emailBodyLC.indexOf("[x] ",tagPos);
if (selectionPos < endTagPos) {
var startAnswerPos = selectionPos + 4;
var endAnswerPos = emailBodyLC.indexOf(".",startAnswerPos);
if (selectionPos > -1 && endAnswerPos > -1) {
return emailBody.substring(startAnswerPos,endAnswerPos);
}
}
}
//If we get here, there is no answer provided for the tag
//Returns the value for the tag. the first ] in the value ends the value
// <tag>: [<value>]
function getBracketValue(emailBody,tag) {
var tagPos = emailBody.indexOf(tag + ":");
if (tagPos > -1) {
var startAnswerPos = emailBody.indexOf("[",tagPos);
var endAnswerPos = emailBody.indexOf("]",tagPos);
if (startAnswerPos > -1 && endAnswerPos > -1 && endAnswerPos > startAnswerPos) {
return emailBody.substring(startAnswerPos+1,endAnswerPos);
}
}
return "";
}