Send a notification email to candidates of a task

Hi, i hope that u will able to help me because i am getting crazy.

I found in order how to send “dynamic” notification.

I found lot of thread and also example but refers to previous version of BonitaSoft and does not work in the latest version.

Could you please say how i should update the groovy script discussed here http://community.bonitasoft.com/send-notification-email-candidates-task
for the latest version of BonitaSoft?

So thanks…

The following is an example from what we use. It does work (7.4.3) but you will have to modify it to work for your circumstances.

Using the Email Connector:

From Script (Groovy):

return "from@emailAddress.com";

To Script (Groovy) (if you have the username in variable bonUser):

def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase()); if(theUser!=null){

// logger.severe(“contact found”);

	// To have professional email
	ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);
	String professionalEmail = professionalData.getEmail();

	if (professionalEmail != null && !professionalEmail.isEmpty()) {
	//	logger.severe("professionalEmail: "+professionalEmail);
		toEmails = professionalEmail;

// logger.severe(toEmails);
}
else{
// logger.severe(“contact NOT found”);
return “contact NOT found”;
}
}
}
return toEmails;

Subject Script (Groovy):

return "Subject";

Message Script (Groovy):

var tbl = tableStyle+"
"+temp2[0].toString()+""+temp2[1].toString()+"


"+ allNotAutoStarted+"

"+ temp1[1].toString()+"
"; return tbl;

regards
Seán

PS: As this reply answers your question, please mark as resolved.

I just need of the “To” script, i edited your code removing one grph from line 20 and importing ContactData, but i am still getting error…it’s a nutshell!

import org.bonitasoft.engine.identity.ContactData;
def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase());
if(theUser!=null){

// logger.severe(“contact found”);

// To have professional email
ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);
String professionalEmail = professionalData.getEmail();

if (professionalEmail != null && !professionalEmail.isEmpty()) {
// logger.severe("professionalEmail: "+professionalEmail);
toEmails = professionalEmail;
// logger.severe(toEmails);
}
else{
// logger.severe(“contact NOT found”);
return “contact NOT found”;
}
}
return toEmails;

The Bootcamp that happened on 27th-March-2017 shows how to send an email to either the persons manager or the person (it shows one or the other, and from that you can figure easily how to do the other one).

Dunno when they’ll get the video of the Bootcamp/webinar online. There’s a PDF of the instructions too, which make it as simple as following a paragraph of very clear instructions to link an SMTP connector to a process.

The previous bootcamp might have it too (hopefully still compatible with the latest version).

Do u know where i can find the pdf? thanks

I’ve pushed it onto Google Drive for you:

Link to PDF

Chapter 5 shows the steps we went through to send an email as part of a process task.

Good Day,

This works if there is only 1 candidate for the task? What if we have 2 or more candidates for the task? For example the task will be assigned to a role “SDesk”, and there are 3 users assigned with the role “SDesk”.

Thank you.

  • Alfred Ayson

Hi There, but did u tried the above code? it is working? i am getting issue…

@Claudio

of course you’re getting an issue, didn’t you read the bit that says:

The following is an example from what we use. It does work (7.4.3) but you will have to modify it to work for your circumstances.

@Alfred

I can’t give you all my code!

This works if there is only 1 candidate for the task? What if we have 2 or more candidates for the task? For example the task will be assigned to a role “SDesk”, and there are 3 users assigned with the role “SDesk”.

Well the task will be assigned to group SDesk through your actor filter. If you really want to send every employee an email every time a support ticket is done I can tell you right now that is not the right thing to do…

It’s up to you but, imagine

3 people, 100 support tickets = 300 emails, if I take one and then x trys to get it he will be annoyed, if I do it quickly and I go on to the next, then x trys to take it - again annoyed. 66% of the time the next available ticket will be not available…66% failure rate.

I would allow the support ticket to sit there, someone will take it - it is their job - if not then have an escalation routine using Non-Interrupting Boundary to fire the email…based on agreed business Service Levels.

Anyway - to answer your question, you know the Group - SDESK - do the following in a script connector:

  • Search users in group SDESK
  • save in List
  • within the next task (Script) you want to multi-Instantiate over the List to email each user.

Very easy,

regards

Hi Sean,

No worries. Was not really expecting to receive code snippets? Just wanted to bounce some ideas on the scenarios that might come across when implementing the requirement above.

Thanks and Best Regards

so you’re getting an error, it was an example.

You have to fix the code,

Have you looked at what the error is?
Have you looked at the logs?
Have you got a variable called bonUser?
Have you assigned it a user name? (wlater.bates for example)

OK here is the full code…

import org.bonitasoft.engine.api.ProcessRuntimeAPI; import java.util.logging.Logger; import java.lang.StringBuilder;

import org.bonitasoft.engine.api.IdentityAPI;
import org.bonitasoft.engine.identity.ContactData;

int dI = 0;
boolean debug = true;
StringBuilder logWrite = new StringBuilder();
Logger logger = Logger.getLogger(“org.bonitasoft”);

ProcessRuntimeAPI processRuntimeAPI = apiAccessor.getProcessAPI();
logWrite.append(“\n\n”);

//set the name of the routine
logWrite.append("Process Name: "+ processRuntimeAPI.getProcessInstance(processInstanceId).getName());

logWrite.append(“\n\t” + dI++ + “Trace Start”);

//TODO - Code goes in here - START

String bonUser = “walter.bates”;
String toEmails = “”;

def identityAPI = apiAccessor.getIdentityAPI();
def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase());
if(theUser!=null){

logWrite.append("\n\t" + dI++ + "contact found");

// To have professional email
ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);
String professionalEmail = professionalData.getEmail();

if (professionalEmail != null && !professionalEmail.isEmpty()) {

	logWrite.append("\n\t" + dI++ + "professionalEmail: "+professionalEmail);
	toEmails = professionalEmail;
	logWrite.append("\n\t" + dI++ + toEmails);
}
else{
	logWrite.append("\n\t" + dI++ + "contact NOT found");
	return "contact NOT found";
}

}

logWrite.append(“\n\t” + dI++ + “Trace End”);
logWrite.append(“\n\n”);
if(debug){logger.severe(logWrite.toString())}

return toEmails;

and here is the output in the log

Process Name: sendEmail 0Trace Start 1contact found 2professionalEmail: walter.bates@acme.com 3walter.bates@acme.com 4Trace End

regards
Seán

Hi…i tried your code…still issue :frowning:

java.lang.reflect.InvocationTargetException
org.bonitasoft.engine.bpm.connector.ConnectorExecutionException: USERNAME=install | org.bonitasoft.engine.core.connector.exception.SConnectorException: org.bonitasoft.engine.expression.exception.SExpressionEvaluationException: Groovy script throws an exception of type class org.bonitasoft.engine.bpm.process.ProcessInstanceNotFoundException with message = org.bonitasoft.engine.core.process.instance.api.exceptions.SProcessInstanceNotFoundException: Process instance with id <-1> not found

Expression : SExpressionImpl [name=to(), content=import org.bonitasoft.engine.api.ProcessRuntimeAPI;

import java.util.logging.Logger;

import java.lang.StringBuilder;

import org.bonitasoft.engine.api.IdentityAPI;

import org.bonitasoft.engine.identity.ContactData;

int dI = 0;

boolean debug = true;

StringBuilder logWrite = new StringBuilder();

Logger logger = Logger.getLogger(“org.bonitasoft”);

ProcessRuntimeAPI processRuntimeAPI = apiAccessor.getProcessAPI();

logWrite.append(“\n\n”);

//set the name of the routine

logWrite.append("Process Name: "+ processRuntimeAPI.getProcessInstance(processInstanceId).getName());

logWrite.append(“\n\t” + dI++ + “Trace Start”);

//TODO - Code goes in here - START

String bonUser = “walter.bates”;

String toEmails = “”;

def identityAPI = apiAccessor.getIdentityAPI();

def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase());

if(theUser!=null){

logWrite.append(“\n\t” + dI++ + “contact found”);

// To have professional email

ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);

String professionalEmail = professionalData.getEmail();

if (professionalEmail != null && !professionalEmail.isEmpty()) {

logWrite.append(“\n\t” + dI++ + "professionalEmail: "+professionalEmail);

toEmails = professionalEmail;

logWrite.append(“\n\t” + dI++ + toEmails);

}

else{

logWrite.append(“\n\t” + dI++ + “contact NOT found”);

return “contact NOT found”;

}

}

logWrite.append(“\n\t” + dI++ + “Trace End”);

logWrite.append(“\n\n”);

if(debug){logger.severe(logWrite.toString())}

return toEmails;, returnType=java.lang.String, dependencies=[SExpressionImpl [name=processInstanceId, content=processInstanceId, returnType=java.lang.Long, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]], SExpressionImpl [name=apiAccessor, content=apiAccessor, returnType=org.bonitasoft.engine.api.APIAccessor, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]]], expressionKind=ExpressionKind [interpreter=GROOVY, type=TYPE_READ_ONLY_SCRIPT]]

2017-03-31 10:50:25.683 +0200 SEVERE: org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork THREAD_ID=3042 | HOSTNAME=ASWFILESTORE | TENANT_ID=1 | org.bonitasoft.engine.expression.exception.SExpressionEvaluationException : "PROCESS_DEFINITION_ID=8069098858181670315 | PROCESS_NAME=Attività Pre-Apertura | PROCESS_VERSION=2.0 | PROCESS_INSTANCE_ID=3061 | ROOT_PROCESS_INSTANCE_ID=3060 | FLOW_NODE_DEFINITION_ID=7989273653481810811 | FLOW_NODE_INSTANCE_ID=60105 | FLOW_NODE_NAME=Contrattazione locali | CONNECTOR_IMPLEMENTATION_CLASS_NAME=Email | CONNECTOR_INSTANCE_ID=20002 | Groovy script throws an exception of type class org.bonitasoft.engine.identity.UserNotFoundException with message = org.bonitasoft.engine.identity.SUserNotFoundException:
Expression : SExpressionImpl [name=to(), content=import org.bonitasoft.engine.api.ProcessRuntimeAPI;

import java.util.logging.Logger;

import java.lang.StringBuilder;

import org.bonitasoft.engine.api.IdentityAPI;

import org.bonitasoft.engine.identity.ContactData;

int dI = 0;

boolean debug = true;

StringBuilder logWrite = new StringBuilder();

Logger logger = Logger.getLogger(“org.bonitasoft”);

ProcessRuntimeAPI processRuntimeAPI = apiAccessor.getProcessAPI();

logWrite.append(“\n\n”);

//set the name of the routine

logWrite.append("Process Name: "+ processRuntimeAPI.getProcessInstance(processInstanceId).getName());

logWrite.append(“\n\t” + dI++ + “Trace Start”);

//TODO - Code goes in here - START

String bonUser = “walter.bates”;

String toEmails = “”;

def identityAPI = apiAccessor.getIdentityAPI();

def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase());

if(theUser!=null){

logWrite.append(“\n\t” + dI++ + “contact found”);

// To have professional email

ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);

String professionalEmail = professionalData.getEmail();

if (professionalEmail != null && !professionalEmail.isEmpty()) {

logWrite.append(“\n\t” + dI++ + "professionalEmail: "+professionalEmail);

toEmails = professionalEmail;

logWrite.append(“\n\t” + dI++ + toEmails);

}

else{

logWrite.append(“\n\t” + dI++ + “contact NOT found”);

return “contact NOT found”;

}

}

logWrite.append(“\n\t” + dI++ + “Trace End”);

logWrite.append(“\n\n”);

if(debug){logger.severe(logWrite.toString())}

return toEmails;, returnType=java.lang.String, dependencies=[SExpressionImpl [name=processInstanceId, content=processInstanceId, returnType=java.lang.Long, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]], SExpressionImpl [name=apiAccessor, content=apiAccessor, returnType=org.bonitasoft.engine.api.APIAccessor, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]]], expressionKind=ExpressionKind [interpreter=GROOVY, type=TYPE_READ_ONLY_SCRIPT]]"
org.bonitasoft.engine.expression.exception.SExpressionEvaluationException: PROCESS_DEFINITION_ID=8069098858181670315 | PROCESS_NAME=Attività Pre-Apertura | PROCESS_VERSION=2.0 | PROCESS_INSTANCE_ID=3061 | ROOT_PROCESS_INSTANCE_ID=3060 | FLOW_NODE_DEFINITION_ID=7989273653481810811 | FLOW_NODE_INSTANCE_ID=60105 | FLOW_NODE_NAME=Contrattazione locali | CONNECTOR_IMPLEMENTATION_CLASS_NAME=Email | CONNECTOR_INSTANCE_ID=20002 | Groovy script throws an exception of type class org.bonitasoft.engine.identity.UserNotFoundException with message = org.bonitasoft.engine.identity.SUserNotFoundException:
Expression : SExpressionImpl [name=to(), content=import org.bonitasoft.engine.api.ProcessRuntimeAPI;

import java.util.logging.Logger;

import java.lang.StringBuilder;

import org.bonitasoft.engine.api.IdentityAPI;

import org.bonitasoft.engine.identity.ContactData;

int dI = 0;

boolean debug = true;

StringBuilder logWrite = new StringBuilder();

Logger logger = Logger.getLogger(“org.bonitasoft”);

ProcessRuntimeAPI processRuntimeAPI = apiAccessor.getProcessAPI();

logWrite.append(“\n\n”);

//set the name of the routine

logWrite.append("Process Name: "+ processRuntimeAPI.getProcessInstance(processInstanceId).getName());

logWrite.append(“\n\t” + dI++ + “Trace Start”);

//TODO - Code goes in here - START

String bonUser = “walter.bates”;

String toEmails = “”;

def identityAPI = apiAccessor.getIdentityAPI();

def theUser = apiAccessor.getIdentityAPI().getUserByUserName(bonUser.toLowerCase());

if(theUser!=null){

logWrite.append(“\n\t” + dI++ + “contact found”);

// To have professional email

ContactData professionalData = identityAPI.getUserContactData(theUser.getId(), false);

String professionalEmail = professionalData.getEmail();

if (professionalEmail != null && !professionalEmail.isEmpty()) {

logWrite.append(“\n\t” + dI++ + "professionalEmail: "+professionalEmail);

toEmails = professionalEmail;

logWrite.append(“\n\t” + dI++ + toEmails);

}

else{

logWrite.append(“\n\t” + dI++ + “contact NOT found”);

return “contact NOT found”;

}

}

logWrite.append(“\n\t” + dI++ + “Trace End”);

logWrite.append(“\n\n”);

if(debug){logger.severe(logWrite.toString())}

return toEmails;, returnType=java.lang.String, dependencies=[SExpressionImpl [name=processInstanceId, content=processInstanceId, returnType=java.lang.Long, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]], SExpressionImpl [name=apiAccessor, content=apiAccessor, returnType=org.bonitasoft.engine.api.APIAccessor, dependencies=, expressionKind=ExpressionKind [interpreter=NONE, type=TYPE_ENGINE_CONSTANT]]], expressionKind=ExpressionKind [interpreter=GROOVY, type=TYPE_READ_ONLY_SCRIPT]]
at org.bonitasoft.engine.expression.impl.GroovyScriptExpressionExecutorCacheStrategy.evaluate(GroovyScriptExpressionExecutorCacheStrategy.java:160)
at org.bonitasoft.engine.expression.impl.ExpressionServiceImpl.evaluate(ExpressionServiceImpl.java:86)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionWithResolvedDependencies(ExpressionResolverServiceImpl.java:213)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluateExpressionsFlatten(ExpressionResolverServiceImpl.java:120)
at org.bonitasoft.engine.core.expression.control.api.impl.ExpressionResolverServiceImpl.evaluate(ExpressionResolverServiceImpl.java:83)
at org.bonitasoft.engine.core.connector.impl.ConnectorServiceImpl.evaluateInputParameters(ConnectorServiceImpl.java:295)
at org.bonitasoft.engine.connector.ConnectorServiceDecorator.evaluateInputParameters(ConnectorServiceDecorator.java:102)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:223)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork$EvaluateParameterAndGetConnectorInstance.call(ExecuteConnectorWork.java:182)
at org.bonitasoft.engine.transaction.JTATransactionServiceImpl.executeInTransaction(JTATransactionServiceImpl.java:274)
at org.bonitasoft.engine.execution.work.ExecuteConnectorWork.work(ExecuteConnectorWork.java:134)
at org.bonitasoft.engine.execution.work.failurewrapping.TxInHandleFailureWrappingWork.work(TxInHandleFailureWrappingWork.java:42)
at org.bonitasoft.engine.execution.work.failurewrapping.TxInHandleFailureWrappingWork.work(TxInHandleFailureWrappingWork.java:42)
at org.bonitasoft.engine.execution.work.failurewrapping.TxInHandleFailureWrappingWork.work(TxInHandleFailureWrappingWork.java:42)
at org.bonitasoft.engine.execution.work.failurewrapping.TxInHandleFailureWrappingWork.work(TxInHandleFailureWrappingWork.java:42)
at org.bonitasoft.engine.execution.work.FailureHandlingBonitaWork.work(FailureHandlingBonitaWork.java:66)
at org.bonitasoft.engine.work.BonitaWork.run(BonitaWork.java:56)
at org.bonitasoft.engine.work.SequenceRunnableExecutor.innerRun(SequenceRunnableExecutor.java:47)
at org.bonitasoft.engine.work.BonitaRunnable.run(BonitaRunnable.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.bonitasoft.engine.identity.UserNotFoundException: org.bonitasoft.engine.identity.SUserNotFoundException:
at org.bonitasoft.engine.api.impl.IdentityAPIImpl.getUserByUserName(IdentityAPIImpl.java:459)
at org.bonitasoft.engine.api.UserAPI$getUserByUserName.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at BScript30.run(BScript30.groovy:53)
at org.bonitasoft.engine.expression.impl.GroovyScriptExpressionExecutorCacheStrategy.evaluate(GroovyScriptExpressionExecutorCacheStrategy.java:141)
… 21 more
Caused by: org.bonitasoft.engine.identity.SUserNotFoundException:
at org.bonitasoft.engine.identity.impl.IdentityServiceImpl.getUserByUserName(IdentityServiceImpl.java:1050)
at org.bonitasoft.engine.api.impl.transaction.identity.GetSUser.execute(GetSUser.java:50)
at org.bonitasoft.engine.api.impl.IdentityAPIImpl.getUserByUserName(IdentityAPIImpl.java:456)
… 27 more

Do you have a user called Walter Bates?

What’s his username?

It’s hard coded so choose a name that exists…