Отправка email-уведомлений пользователю роли UserTask

Прошу помочь со следующим вопросом.

Необходимо отправлять email-уведомления для пользователей роли в UserTask. Я предполагаю, что для этого можно использовать Task listener на событие create (или assignment?).
Как в таком случае заполнить этот диалог?
image

Class, как я понял:

public class MyTaskCreateListener implements TaskListener {

  public void notify(DelegateTask delegateTask) {
    // Custom logic goes here
  }
}

Он должен располагаться в core/scr/com.company/core/? Как правильно передать туда пользователя?

Вот пример слушателя:

package com.company.bpmtest8.process.listener;

import com.google.common.base.Strings;
import com.haulmont.cuba.core.app.EmailerAPI;
import com.haulmont.cuba.core.global.*;
import com.haulmont.cuba.security.entity.User;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;

public class MyTaskListener implements TaskListener {

    private static final Logger log = LoggerFactory.getLogger(MyTaskListener.class);

    @Override
    public void notify(DelegateTask delegateTask) {
        String assignee = delegateTask.getAssignee();
        EmailerAPI emailerAPI = AppBeans.get(EmailerAPI.class);
        DataManager dataManager = AppBeans.get(DataManager.class);
        UUID userId = UUID.fromString(assignee);
        User user = dataManager.load(LoadContext.create(User.class)
                .setId(userId)
                .setView(View.LOCAL));
        if (user == null || Strings.isNullOrEmpty(user.getEmail())) {
            log.error("Email for user {} is not defined", user);
            return;
        }
        try {
            emailerAPI.sendEmail(user.getEmail(), "Email subject", "Email body");
        } catch (EmailException e) {
            log.error("Email sending error", e);
        }
    }
}

Располагайте класс слушателя где угодно в модуле core, главное пропишите полный путь к классу в поле Class:

image

3 симпатии

Большое спасибо за сниппет, Максим.
Да еще и с выводом в лог! Здорово!

Максим, подскажите, пожалуйста. Хочу использовать значения атрибутов entity, в которой запущен процесс в теле письма.
Получить entity, из которой запущен процесс в этом методе можно только только следующим образом?

  • delegateTask.getProcessInstanceId()
  • запрос LoadContext и получение ProcessInstance
  • получение entityId из ProcessInstance
  • запрос LoadContext и получение entity

Или можно как-то по-проще?

Обычно идентификатор связанной сущности хранится в процессной переменной entityId. Можете получить её в листенере, например, так:

Object entityId = delegateTask.getVariable("entityId");

Далее, зная идентификатор, с помощью DataManager получаете сущность

1 симпатия

Максим, и еще вопрос. А нельзя это завернуть в кастомный стенсил, “унаследовав” его от стандартного UserTask?

Сейчас кастомные стенсилы, которые делаются из UI - это по сути ServiceTask. Из коробки стенсил для UserTask средствами платформы и двумя кликами мышки сделать не получится.
Если у вас емейлы отсылаются для всех UserTask в процессе, то м.б. вам имеет смысл навешивать слушатель не на каждую таску, а реализовать логику отправки писем в слушателе уровня процесса? https://www.activiti.org/userguide/#eventDispatcher

1 симпатия

Максим, коли пошла такая пьянка. А нет, “случайно”, свойства таска, в которое можно было бы положить “тему” письма, например с параметрами типа {0} или %s для дальнейшего заполнения?

Произвольные свойства в дизайнере задавать вроде бы нельзя. В качестве костылей, поле “Documentation” можно попробовать использовать. Либо на старте процесса заранее положить в процессную переменную мапу: имя таски - шаблон письма. И в слушателе уже из этой мапы для текущей таски шаблон находить

1 симпатия

Хотелось бы сделать это декларативно. Тоже посматривал на поле Documentation… Подскажите, пожалуйста, а как его получить в слушателе?

delegateTask.getDescription()

1 симпатия

Мде… прямо под носом. Спасибо еще раз.

Если остановитесь на варианте с TaskListener, то есть ещё способ передать параметр в слушатель:

image

Можете определить значение свойства, напр. emailBody, в диалоге Task listeners. А потом в коде слушателя получить значение параметра:

public class MyTaskListener implements TaskListener {

    private Expression emailBody;

    @Override
    public void notify(DelegateTask delegateTask) {
        String emailBodyValue = (String) emailBody.getValue(delegateTask);
        ....
   }
}
2 симпатии