Last updated Sep 12, 2019

Sending emails in a plugin

Applicable:

This tutorial applies to Confluence 4.3

Level of experience:

This is an intermediate tutorial. You should have completed at least one beginner tutorial before working through this tutorial. See the list of developer tutorials .

Time estimate:

It should take you approximately 45 minutes to complete this tutorial.

StatusLEGACY This tutorial applies to Confluence versions that have reached end of life.

This tutorial is out of date

From Confluence 7.0 com.atlassian.mail.queue.MailQueueItem no longer extends com.atlassian.core.task.Task which will lead to compile errors around task managers used in email notifications.

You will need to wrap the MailQueueItem in a lambda before passing it down to the task manager, for example:

1
2
taskManager.addTask(name, () -> item.send())

See Preparing for Confluence 7.0 for details of all breaking changes in 7.0.

Overview of the tutorial

This tutorial shows you how to write a service within a plugin in Confluence, to send an email message. Your completed plugin will consist of the following components:

  • Java classes encapsulating the plugin logic.
  • A plugin descriptor (XML file) to enable the plugin module in the Confluence application.
  • Java test classes that show you how to use the written plugin service. 

When you have finished, all these components will be packaged in a single JAR file.

Prerequisite knowledge

To complete this tutorial, you need to know the following:

  • The basics of Java development: classes, interfaces, methods, how to use the compiler, and so on.
  • How to create an Atlassian plugin project using the Atlassian Plugin SDK.
  • How to write JUnit tests using JUnit and Mockito.

Plugin source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you have finished, you can find the plugin source code on Atlassian Bitbucket. Bitbucket serves a public Git repository containing the tutorial's code. To clone the repository, issue the following command:

1
2
git clone https://bitbucket.org/atlassian_tutorial/confluence-email-demo

Alternatively, you can download the source using the get source option here: bitbucket.org/atlassian_tutorial/confluence-email-demo

About these Instructions

You can use any supported combination of OS and IDE to construct this plugin. These instructions were written using Eclipse on a MacPro running Mac OS X. If you are using another combination, you should use the equivalent operations for your specific environment.

Step 1. Create the plugin project

In this step, you'll use the two atlas- commands to generate stub code for your plugin and set up the stub code as an Eclipse project. The atlas- commands are part of the Atlassian Plugin SDK, and automate much of the work of plugin development for you.

  1. Open a terminal and navigate to your Eclipse workspace directory.

  2. Enter the following command to create a plugin skeleton:

    1
    2
    atlas-create-confluence-plugin
    

    When prompted, enter the following information to identify your plugin:

    group-id

    com.example.plugins.tutorial.confluence

    artifact-id

    example-mail-sending-plugin

    version

    1.0.0-SNAPSHOT

    package

    com.example.plugins.tutorial.confluence.mail

  3. Confirm your entries when prompted.

  4. Change to the example-mail-sending-plugin directory created by the previous step.

  5. Run the following command:

    1
    2
    atlas-mvn eclipse:eclipse
    
  6. Start Eclipse.

  7. Select File > Import.
    Eclipse starts the Import wizard.

  8. Filter for Existing Projects into Workspace (or expand the General folder tree).

  9. Choose Next and browse to the root directory of your plugin (where the pom.xml file is located).
    Your Atlassian plugin folder should appear under Projects.

  10. Select your plugin and choose Finish.
    Eclipse imports your project.

Step 2. Review and tweak the generated stub code

It is a good idea to familiarise yourself with the project configuration file, known as the POM (Project Object Model definition file). In this section, you will review and tweak the pom.xml file. Open your plugin project in Eclipse and follow along in the next sections.

Add plugin metadata to the POM

The POM (Project Object Model definition file).is located at the root of your project and declares the project dependencies and other information.

Add some metadata about your plugin and your company or organisation.

  1. Edit the pom.xml file in the root folder of your plugin.

  2. Add your company or organisation name and your website to the <organization> element (the following code blocks show how it looks in plain text):

    1
    2
    <organization>
        <name>Example Company</name>
        <url>http://www.example.com/</url>
    </organization>
    
  3. Update the <description> element:

    1
    2
    <description>This plugin provides a simple example of how to write a service that will send email.</description>
    
  4. Save the file.

Verify your Confluence version

When you generated the stub files, a default Confluence version was included in your pom.xml file. Take a moment and examine the Confluence dependency:

  1. Open the pom.xml file.
  2. Scroll to the bottom of the file.
  3. Find the <properties> element.
    This section lists the version of Confluence and also the version of the atlas- commands (AMPS commands) you are running.
  4. Verify that the Confluence version is the one you want, and if not modify the confluence.version and confluence.data.version to the correct versions. If you are not sure which version of Confluence you need, check the version table at the top of this tutorial.
  5. Save the pom.xml file

Review the generated plugin descriptor

Your stub code contains a plugin descriptor file atlassian-plugin.xml. This is an XML file that identifies the plugin to the host application (Confluence) and defines the required plugin functionality. In your IDE (integrated development environment, such as Eclipse or IDEA) open the descriptor file which is located in your project under src/main/resources. You should see something like this:

1
2
<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.artifactId}" plugins-version="2">
    <plugin-info>
        <description>${project.description}</description>
        <version>${project.version}</version>
        <vendor name="${project.organization.name}" url="${project.organization.url}" />
    </plugin-info>
</atlassian-plugin>

Step 3. Add your plugin modules to the plugin descriptor

Now you will use the plugin module generator (another atlas- command) to generate the stub code for modules needed by the plugin.

For this tutorial, you will need a 'Component' plugin module. You'll add this via the atlas-create-confluence-plugin-module command.

  1. Open a command window and go to the plugin root folder (where the pom.xml is located).

  2. Run atlas-create-confluence-plugin-module.

  3. Choose the number corresponding to the option labelled Component.

  4. Supply the following information as prompted:

    Enter Interface Name

    MailService

    Package Name

    com.example.plugins.tutorial.confluence.mail

    Enter Class Name

    MailServiceImpl

    Enter Package Name

    com.example.plugins.tutorial.confluence.mail

  5. Choose N for Show Advanced Setup.

  6. Choose N for Add Another Plugin Module.

  7. Return to Eclipse and Refresh your project.

  8. Review the components added by the plugin module generator to your plugin descriptor.

    atlassian-plugin.xml

    The mail-service-impl module was added.

  9. You can also safely remove the xhtml-macro plugin module descriptor from the atlassian-plugin.xml since this is a boiler plate example macro that isn't needed by this tutorial.

Step 4. Update your project and refresh your IDE

If you change your Atlassian project, Eclipse is not automatically aware of the changes. Moreover, sometimes your project dependencies require an update. We need to fix that.

  1. Switch to a terminal window.

  2. Change directory to the project root.
    This is the directory that contains the pom.xml file.

  3. Update your project metadata with the new POM information.

    1
    2
    atlas-mvn eclipse:eclipse
    
  4. Back in Eclipse, refresh the plugin project to pick up the changes.

Remember to do this update and refresh step each time you edit your pom.xml and whenever you modify your plugin source with an Atlassian command.

Step 5. Write the plugin code

You have already generated the stub for your Component plugin module. Now, you will write some code that will make your plugin do something. Recall that this plugin will allow you to send an email message from within Confluence. To do this, you will implement the MailService interface, and hook this up to the TaskManger within Confluence.

To see the auto-generated Java code, right-click the com.example.plugins.tutorial.confluence.mail package name, and choose 'Refresh'.

Subtask - Implementing the MailService interface

This is the MailService interface that we are going to implement. You will need a new method sendEmail(MailQueueItem mailQueueItem). Add this method to your currently blank interface:

MailService.java

1
2
package com.example.plugins.tutorial.confluence.mail;
 
import com.atlassian.mail.queue.MailQueueItem;


/**
 * This service has the responsibility of sending an email
 */
public interface MailService
{
    /**
     * This will send an email based on the details stored in the ConfluenceMailQueueItem
     *
     * @param mailQueueItem the item to send
     */
    void sendEmail(MailQueueItem mailQueueItem);
}

You will now need to implement this method in the MailServiceImpl class, which was also auto-generated for you earlier. Our implementation will make use of the com.atlassian.core.task.MultiQueueTaskManager that Confluence uses for task management.

Here is an example implementation of this class.

MailServiceImpl.java

1
2
package com.example.plugins.tutorial.confluence.mail;

import com.atlassian.core.task.MultiQueueTaskManager;
import com.atlassian.mail.queue.MailQueueItem;

/**
 * Default implementation of the {@link MailService}
 */
public class MailServiceImpl implements MailService
{
    public static final String MAIL = "mail";
    private final MultiQueueTaskManager taskManager;

    public MailServiceImpl(MultiQueueTaskManager taskManager)
    {
        this.taskManager = taskManager;
    }

    /**
     * This will use a MultiQueueTaskManager to add add the mailQueueItem to a queue
     * to be sent
     *
     * @param mailQueueItem the item to send
     */
    @Override
    public void sendEmail(MailQueueItem mailQueueItem)
    {
        taskManager.addTask(MAIL, mailQueueItem);
    }
}

Note that this class is pretty simple, but it makes use of a TaskManager. This task manager will need to be imported into the plugin via a component-import module descriptor, so lets do that now.

Subtask - Creating the component-import module descriptor for the TaskManager

As before, you will use the plugin module generator to generate the stub code for modules needed by the plugin.

You will need a Component Import plugin module. You'll add this via the atlas-create-confluence-plugin-module command.

  1. Open a command window and go to the plugin root folder (where the pom.xml is located).

  2. Run atlas-create-confluence-plugin-module.

  3. Choose the option labelled Component Import.

  4. Supply the following information as prompted:

    Enter Fully Qualified Interface

    com.atlassian.core.task.MultiQueueTaskManager

    Module Key

    task-manager

    Filter (not required)

    press enter

  5. Enter N for Add Another Plugin Module.

  6. Return to Eclipse and Refresh your project.

  7. Review the components added by the plugin module generator.

    atlassian-plugin.xml

    The task-manager component-import was added.

This is effectively it, you now have a basic service in place that can be used to send email within Confluence, but how do you use it? Lets put together a quick unit test that covers how to actually use the MailService.

Subtask - Writing a unit test

There should already be a MailServiceImplTest class present in the src/test/java directory. (Right-click the package name and choose 'Refresh' to see it.) Modify this test class to look like the following:

1
2
package com.example.plugins.tutorial.confluence.mail;

import com.atlassian.confluence.mail.template.ConfluenceMailQueueItem;
import com.atlassian.core.task.MultiQueueTaskManager;
import com.atlassian.mail.queue.MailQueueItem;
import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import javax.activation.DataSource;
import javax.mail.util.ByteArrayDataSource;
import static com.atlassian.confluence.mail.template.ConfluenceMailQueueItem.MIME_TYPE_HTML;
import static com.atlassian.confluence.mail.template.ConfluenceMailQueueItem.MIME_TYPE_TEXT;
import static org.mockito.Mockito.verify;


@RunWith(MockitoJUnitRunner.class)
public class MailServiceImplTest
{
    private MailService mailService;


    @Mock
    private MultiQueueTaskManager taskManager;


    @Before
    public void setUp()
    {
        mailService = new MailServiceImpl(taskManager);
    }


    @Test
    public void testSendEmail() throws Exception
    {
        MailQueueItem mailQueueItem = new ConfluenceMailQueueItem("whoever@atlassian.com", "A test email", "The body of the message", MIME_TYPE_HTML);
        mailService.sendEmail(mailQueueItem);
        verify(taskManager).addTask(MailServiceImpl.MAIL, mailQueueItem);
    }
}
 

This test class uses Mockito to mock our call to the task manager and it will simply verify that our task manager is called once.

As you can see, we simply construct a ConfluenceMailQueueItem providing all the required attributes for the email, and then pass this into our service. If you take a look at the source code for this tutorial from Bitbucket you will see that I have included a secondary example of how you can add attachments to an email as well.

Subtask - Removing unnecessary code

We are not writing any integration tests for this tutorial, so you will need to remove the functional test class automatically generated by the SDK.

  1. Remove MailServiceImplFuncTest.java, which you will find in location src/test/java/it/com/example/plugins/tutorial/confluence/mail/
  2. You can also safely remove the ExampleMacro.java class from your project, since this is a boiler plate example macro that isn't needed by this tutorial

Step 6. Build, install and run the plugin

Follow these steps to build and install your plugin, so that you can test your code.

  1. Make sure you have saved all your code changes to this point.

  2. Open a terminal window and navigate to the plugin root folder (where the pom.xml file is).

  3. Run the following command:

    1
    2
    atlas-run
    

    This command builds your plugin code, starts a Confluence instance, and installs your plugin in it. This may take several seconds. When the process has finished, you will see many status lines on your screen concluding with something like the following:

    1
    2
    [INFO] HOSTAPP started successfully in 71s at http://localhost:XXXX/confluence
    [INFO] Type CTRL-D to shutdown gracefully
    [INFO] Type CTRL-C to exit
    
  4. Open your browser and navigate to the local Confluence instance started by atlas-run: By default, this is at http://localhost:1990/confluence.

  5. At the Confluence login screen, enter a username of admin and a password of admin

  6. Navigate to the Universal Plugin Manager in the Administration section of Confluence, by choosing BrowseConfluence Admin > Plugins.

  7. Choose Show System Plugins.

  8. Here you will see that the example-mail-sending-plugin plugin was successfully installed.

Step 7. Expand the plugin further

Now you have a basic plugin that can provide a way for you to send email messages. You could now think about creating a Struts Action, Servlet, in fact any feature that can make use of this mailing service!

Congratulations, that's it

Have a chocolate!

Rate this page: