Skip to main content
Skip table of contents

Workflow Notification Plugin Tutorial


This tutorial introduces you to using the Scroll Content Management Apps API for Scroll Versions and Scroll Translations.

You will develop a "workflow-notification" Confluence app that sends an email to reviewers informing them when the workflow status of a page is set to "review".

With Scroll Versions 4.5.0 Scroll Roles are hidden per default and need to be activated manually.

Before you get started, be sure you have experience with the Atlassian SDK and building a Project as well as using Spring and Maven. This tutorial doesn't focus on the structure of the app, but on the implementation code.

At any time, you can reference the source of the complete app.

Create an app skeleton

First, create a new project for your app. Create an app skeleton using the Atlassian SDK with the following command:

CODE
atlas-create-confluence-plugin

Feel free to remove unused files and code from the skeleton:

  • Remove everything under src/test/java, src/test/resources and src/main/java

  • Remove test dependencies in the pom.xml

  • Remove "js", "images" and "css" and workflow-notifications.properties under src/main/resources

  • Remove all components from the atlassian-plugin.xml

Add the Java API

Next, add the Java API to your project. The Java API retrieves the reviewers in a space and gets an event whenever the workflow status of a page changes.

To use the Java API in the project, add the Maven dependency to the pom.xml:

CODE
<dependency>
    <groupId>com.k15t.scroll</groupId>
    <artifactId>scroll-content-management-api</artifactId>
    <version>1.0.0</version>
    <scope>provided</scope>
</dependency>

Once the dependency is imported into your IDE, you can browse and use the Java API.

View the pom.xml.

Create component interfaces

Now, create the interfaces of the components you will need to send an email to reviewers:

  1. Create a component that provides the email addresses of the reviewers in a given space. Name it MailAddressesProvider:

    JAVA
    public interface MailAddressesProvider {
    
        Set<String> getReviewerAddresses(String spaceKey);
    
    }
  2. Create a component that creates the subject and content of the email. Name it MailContentProvider:

    JAVA
    public interface MailContentProvider {
    
        String getMailBody(WorkflowStatusChangeEvent event);
    
    
        String getMailSubject(WorkflowStatusChangeEvent event);
    
    }
  3. FInally, create a component for sending the emails. Name it MailService:

    JAVA
    public interface MailService {
    
        void sendMail(Set<String> toAddresses, String subject, String htmlBody);
    
    }

Bring it together

Now you have the components, create an event listener named WorkflowStatusChangeEventListener that listens for WorkflowStatusChangeEvents from the Scroll Content Management API.

The event publishes whenever the workflow status of a page changes. The event listener then sends out emails to reviewers.

WorkflowStatusChangeEvent is thrown whenever the workflow status of a page changes.

After checking that the workflow status of the page was updated to "approval" we can construct the subject and content of the email and send it to all reviewers of the space:

JAVA
@EventListener
public void onWorkflowStatusChangeEvent(WorkflowStatusChangeEvent event) {
	if (pageMovedToApproval(event)) {
    	Set<String> reviewerAddresses = mailAddressesProvider.getReviewerAddresses(event.getScrollPage().getSpaceKey());
    	String content = mailContentProvider.getMailBody(event);
    	String subject = mailContentProvider.getMailSubject(event);
		mailService.sendMail(reviewerAddresses, subject, content);
  	}
}


private boolean pageMovedToApproval(WorkflowStatusChangeEvent event) {
  	return WorkflowStatus.approval == event.getNewStatus();
}

View the WorkflowStatusChangeEventListener class.

Implement the components

The only thing left for the "workflow-notification" app to work is to implement the components.

MailAddressesProvider

First, implement MailAddressesProvider in a class named MailAddressesProviderImpl.

Use the SpaceRolesService component from the Scroll Content Management API to retrieve the email addresses of reviewers. You can inject or wire the SpaceRolesService the same way you inject Confluence components. The component is provided by the Scroll Platform app bundled with each Scroll Content Management app.

You will first retrieve the configured space roles in the getReviewerAddresses() method using SpaceRolesService.

Then, you will use GroupManager and UserAccessor to get the email addresses of reviewers in the space:

JAVA
@ComponentImport
@Autowired
private SpaceRolesService spaceRolesService;

...

@Override
public Set<String> getReviewerAddresses(String spaceKey) {
	Set<String> addresses = new HashSet<>();
    SpaceRoles spaceRoles = spaceRolesService.getConfiguredSpaceRoles(spaceKey);

    for (String groupName : spaceRoles.getReviewerGroupNames()) {
    	for (ConfluenceUser user : userAccessor.getMembers(userAccessor.getGroup(groupName))) {
        	addresses.add(user.getEmail());
        }
   	}

    for (String userKey : spaceRoles.getReviewerUserKeys()) {
    	ConfluenceUser user = userAccessor.getUserByKey(new UserKey(userKey));
        addresses.add(user.getEmail());
   	}

    return addresses;
}

View the MailAddressesProviderImpl class.

MailContentProvider

Implement MailContentProvider next, in a class named MailContentProviderImpl.

The getMailSubject method creates a String containing the title of the page whose workflow has been set to "approval".

The getMailBody method renders the HTML body of the page through a velocity template named mail.vm.

JAVA
@Override
public String getMailBody(WorkflowStatusChangeEvent event) {
	Page page = pageManager.getPage(event.getScrollPage().getConfluencePageId());

    Map<String, Object> context = new HashMap<>();
    context.put("link", (settingsManager.getGlobalSettings().getBaseUrl() + page.getUrlPath()));
    context.put("space", page.getSpace().getDisplayTitle());
    context.put("spaceUrl", (settingsManager.getGlobalSettings().getBaseUrl() + page.getSpace().getUrlPath()));
    context.put("pageName", event.getScrollPage().getScrollPageTitle());
    context.put("pageVersion", event.getScrollPage().getVersion().getName());
    StringWriter writer = new StringWriter();
    try {
    	templateRenderer.render("/com/k15t/workflow/notification/mail.vm", context, writer);
    } catch (IOException e) {
    	throw new RuntimeException("Could not render the mail body.", e);
    }
    return writer.toString();
}


@Override
public String getMailSubject(WorkflowStatusChangeEvent event) {
	String pageTitle = event.getScrollPage().getScrollPageTitle();
    return String.format("Page '%s' is ready for approval.", pageTitle);
}

View the MailContentProviderImpl class.

Resulting Email

The mail.vm template takes some variables like the page url and space name to render an HTML message like this:

MailService

The last component to implement is MailService. Create a class named MailServiceImpl that implements the sendMail() method using the Confluence MultiQueueTaskManager to add a new email to the "mail" task queue:

JAVA
@Override
public void sendMail(Set<String> toAddresses, String subject, String htmlBody) {
	taskManager.addTask("mail", new ConfluenceMailQueueItem(concatAddresses(toAddresses), subject, htmlBody, MIME_TYPE_HTML));
}


private String concatAddresses(Set<String> addresses) {
	return StringUtils.join(addresses, ", ");
}

View the MailServiceImpl class.

Try it out

Now the app is complete, try it out:

  1. Start Confluence.

  2. Configure an outgoing mail server.

  3. Install Scroll Versions and the "workflow-notification" app.

  4. Create a new space.

  5. Create a version "1.0" and activate the simple workflow.

  6. Configure some users and/or groups as reviewers.

  7. Create a new page.

  8. Change the workflow status of the page to "approval".

All reviewers should have received an email saying the updated page is ready for their approval.

Congratulations on completing this tutorial!

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.