J tricks - Little JIRA Tricks
  • Home
  • Plugins ↓
    • JQL Tricks Plugin
      • JQL Tricks Plugin - Cloud
        • JQLT Cloud Installation
        • JQLT Cloud Configuration
        • JQLT Cloud Usage
        • JQLT Cloud License
        • JQLT Cloud FAQ
      • JQL Tricks Plugin - DC
        • JQLT DC Installation
        • JQLT DC Configuration
        • JQLT DC Usage
          • JQLT Issue Functions
          • JQLT Subtask Functions
          • JQLT Links Functions
          • JQLT Development Functions
          • JQLT Worklog Functions
          • JQLT Project Functions
          • JQLT Component Functions
          • JQLT Version Functions
          • JQLT Group Functions
          • JQLT User Functions
          • JQLT Date Functions
        • JQLT DC License
        • JQLT DC FAQ
        • JQLT DC Known Issues
        • JQLT DC Performance
      • JQL Tricks Cloud Migration
    • Simplified Planner
      • J-Planner Installation
      • J-Planner Configuration
      • J-Planner Usage
        • Creating a plan
        • Editing a plan
        • Deleting a plan
        • Viewing a plan
        • Modifying a plan
      • J-Planner FAQ
    • Atla-Search Plugin
      • Atla-Search Installation
      • Atla-Search Configuration
      • Atla-Search Usage
      • Atla-Search License
      • Atla-Search FAQ
    • Copy to subtask Plugin
    • All Plugins
  • Tutorials
  • The Book
  • Contact Us
  • Home
  • Plugins ↓
    • JQL Tricks Plugin
      • JQL Tricks Plugin - Cloud
        • JQLT Cloud Installation
        • JQLT Cloud Configuration
        • JQLT Cloud Usage
        • JQLT Cloud License
        • JQLT Cloud FAQ
      • JQL Tricks Plugin - DC
        • JQLT DC Installation
        • JQLT DC Configuration
        • JQLT DC Usage
          • JQLT Issue Functions
          • JQLT Subtask Functions
          • JQLT Links Functions
          • JQLT Development Functions
          • JQLT Worklog Functions
          • JQLT Project Functions
          • JQLT Component Functions
          • JQLT Version Functions
          • JQLT Group Functions
          • JQLT User Functions
          • JQLT Date Functions
        • JQLT DC License
        • JQLT DC FAQ
        • JQLT DC Known Issues
        • JQLT DC Performance
      • JQL Tricks Cloud Migration
    • Simplified Planner
      • J-Planner Installation
      • J-Planner Configuration
      • J-Planner Usage
        • Creating a plan
        • Editing a plan
        • Deleting a plan
        • Viewing a plan
        • Modifying a plan
      • J-Planner FAQ
    • Atla-Search Plugin
      • Atla-Search Installation
      • Atla-Search Configuration
      • Atla-Search Usage
      • Atla-Search License
      • Atla-Search FAQ
    • Copy to subtask Plugin
    • All Plugins
  • Tutorials
  • The Book
  • Contact Us

Sending mails from JIRA Plugins

7/7/2012

17 Comments

 
Sending emails from a Java application is not rocket science! But why bother if JIRA has its own APIs to do the job for
you?

I am talking about taking advantage of the issue event management in JIRA.

We all know about the notification schemes in JIRA and how JIRA sends email to the various subscribers when an event is fired. All we need to do is to make use of this feature.

Following are the simple configuration steps needed.


  1. Define a template which renders the subject and body of the email message - both html and text version. I have discussed about this in detail in my book. In case if you missed it, check out the email-template-id-mappings. xml file under WEB-INF/classes folder. I have created the following entry:

    <templatemapping id="99">
      <name>Mail Servlet</name>
      <template>mailservlet.vm</template>
      <templatetype>issueevent</templatetype>
    <
    /templatemapping>

    Note that you can do this programmatically when the plugin is enabled but I am not going into those details here.
  2. Write the templates defined above. You need 3 templates, all with the same name mailservlet.vm (name defined above).

    Subject : The subject file goes into WEB-INF/classes/templates/email/subject folder

    Subject will be something simple. We are going to keep it very simple!

    Test Mail from Servlet

    html : The html file goes into WEB-INF/classes/templates/email/html folder

    This can be as fancy as you want. Let us keep it simple, using just 2 velocity params.

    Hello there!
    <br><br>
    #set ($baseUrl = $params.get("baseurl")) Are you having fun reading the <a 
    href="http://www.j-tricks.com">j-tricks</a> tutorial? Take a look at <a href="$baseUrl/browse/$issue.key">$issue.key</a>.
    <br><br>
    $params.get("sender").getDisplayName()


    As you can see, there are 2 velocity variables, $params and $issue, that we have used in this template. We will see soon where those comes from.

    text : The text file goes into WEB-INF/classes/templates/email/text folder

    Again, let us keep it simple as shown:

    Hello there!

    Are you having fun reading the j-tricks (http://www.j-tricks.com) tutorial? Take a look at $issue.key.

    $params.get("sender").getDisplayName()

  3. Restart your JIRA so that the template mapping is effective. No need to do this if you are handling it programmatically when the plugin is enabled.
  4. Create a custom event and map it to the new template we defined.
  5. Add the new event to the notification scheme and add subscribers to this event notification.

Now that the template is defined and the event added, we can write the code that feeds the relevant context for the template and then fires the event. In your plugin, all you needed is a few lines of code.

  1. Create the context needed for the velocity template used by the event. For an issue event, a large number of variables are already available: https://developer.atlassian.com/display/JIRADEV/Contents+of+the+Velocity+Context.

    You can see both issue and params, the two velocity variables we used, a part of the list. params here will be populated by us when the event is fired.

    A map of variables that will be added to params is created as follows.

    Map<String, Object> context = new HashMap<String, Object>();
    context.put("sender", loggedInUser);
    context.put("baseurl",ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL));


    We are adding just sender and baseurl as those are the 2 ones taken from params in the template above.
  2. Fire the event. Here 10000L is the id of the event to be fired. We use the custom event that is mapped to our velocity template but the same mechanism can be sued to fire system events as well.

    issueEventManager.dispatchEvent(10000L, issue, context, loggedInUser, true);

That's it! The event is fired and mail will now be sent to all the subscribers as defined in the notification scheme.

How about sending it only to selected people and not depending on the notification schemes? Like the share feature in
JIRA5? i.e. send only to selected users? Replace the dispatchEvent with the following.

  1. Create the map of params as in the above case.
  2. For each user, create a notification recipient and add it into a Set of recipients.

    User user = ComponentAccessor.getUserUtil().getUser("jobin");
    NotificationRecipient recipient = new NotificationRecipient(user);
    HashSet<NotificationRecipient> recipients = new HashSet<NotificationRecipient>();
    recipients.add(recipient);


  3. Create an IssueEvent object with our issue, context and the event Id.

    IssueEvent event = new IssueEvent(issue, context, loggedInUser, 10000L);

  4. Create a MailQueueItem using this event, recipient list and the template id. Here 99 is the template id.

    MailQueueItem item = issueMailQueueItemFactory.getIssueMailQueueItem(event, 99L, recipients, "");

    Note that you will have to enable to jira-core dependency in the pom.xml for IssueMailQueueItemFactory.
  5. Add the item to the mail queue.

    ComponentAccessor.getMailQueue().addItem(item);

And that's all. The mail queue will take care of dispatching our message.
Sample Mail
I have attached the code of a simple servlet plugin which does both the approaches at the end of this page. After installing the plugin, it can be tested by accessing the servlet. Use a valid issue key and a receiver attribute if you are not using notification scheme.

Example calls:

http://localhost:8080/plugins/servlet/mailservlet?receiver=jobinkk&issue=DEMO-1
http://localhost:8080/plugins/servlet/mailservlet?issue=DEMO-1


Have a good day!
send-mail.zip
File Size: 15 kb
File Type: zip
Download File

17 Comments
Matt Doar link
7/10/2012 06:31:23 am

Jobin,

A handy article, as ever. It looks like the email is sent by the mail queue, which has a 60s interval, right?

Also, a useful trick I found for adding more variables to the standard Velocity context for regular email templates is to define a calculated custom field type that always returns the same thing - a Map of the objects you want in the context. Then in the email velocity template
retrieve the value of the custom field with $customFieldManager.getCustomFieldObjectByName()

~Matt

Reply
J-Tricks
7/10/2012 07:07:06 am

Matt, yes. It will be sent by the mail queue every N minutes as defined in the MailQueueService.

Nice trick about adding the objects to velocity context. Never thought about that before :)

Reply
email lists link
7/22/2012 11:49:02 pm

It is quite interesting to know this kind of emails sending process and will try the plugins you mention in the post .

Reply
Bastien
11/23/2012 03:06:42 am

Hi !

I've tried this code, and i have this exeception :

ERROR ServiceRunner Mail Queue Service [atlassian.jira.mail.IssueMailQueueItem] This code or velocity template expects a GenericValue, but received an Issue. We need to recode
java.lang.UnsupportedOperationException: This code or velocity template expects a GenericValue, but received an Issue. We need to recode
at com.atlassian.jira.issue.DocumentIssueImpl.getLong(DocumentIssueImpl.java:446)
at com.atlassian.jira.mail.IssueMailQueueItem.send(IssueMailQueueItem.java:143)
at com.atlassian.mail.queue.MailQueueImpl.sendBuffer(MailQueueImpl.java:66)
at com.atlassian.jira.service.services.mail.MailQueueService.run(MailQueueService.java:28)
at com.atlassian.jira.service.JiraServiceContainerImpl.run(JiraServiceContainerImpl.java:61)
at com.atlassian.jira.service.ServiceRunner.execute(ServiceRunner.java:47)
at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
at com.atlassian.multitenant.quartz.MultiTenantThreadPool$MultiTenantRunnable.run(MultiTenantThreadPool.java:72)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)


Here is a part of my sendMail method code :

String subject = issue.getSummary();

Map<String, Object> context = new HashMap<String, Object>();
context.put("sender", userManager.getUserObject("admin"));
context.put("baseurl",ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL));
context.put("summary", subject);
issueEventManager.dispatchEvent((long) 10023, issue, context, userManager.getUserObject("admin"), true);


Is there a problem with my issue object "issue" in the method ?

Reply
J-Tricks
11/23/2012 07:56:53 am

Which version of JIRA is it?

Reply
Bastien
11/25/2012 07:30:13 pm

My Jira version is 5.0.7

Bastien
11/25/2012 10:15:51 pm

I found a solution to my problem :

The dispatchEvent() method is exepecting a MutableIssue, and not an Issue.
So, i map my issue to a MutableIssue :

MutableIssue i = issueManager.getIssueObject(issue.getKey());

That's it !


Thank you for your tutorial :)

Reply
J-Tricks
11/26/2012 02:35:14 am

Great :)

Reply
moxin link
12/12/2012 09:49:55 pm

does the job perfectly. thanks again.

Reply
moxin link
12/13/2012 09:41:31 pm

also is there a way to do all the process of creating a template, notification scheme and add subscribers in the plugin?
like just install the plugin and you are ready to send email like:
http://localhost:8080/plugins/servlet/mailservlet?issue=DEMO-1

Reply
J-Tricks
12/14/2012 12:47:57 am

You can do most of it when the plugin is enabled. See http://www.j-tricks.com/1/post/2012/03/plugin-lifecycle-events.html for details.

You will have to manually add the template though!

Reply
Shabbir K
2/12/2013 12:50:25 am

HI

I am trying to create a screen where user can select 'groups' from group picker and have an option to send email notification (containing the ISSUE details) to the selected groups only. Is it possible with this plugin, please advise

Reply
J-Tricks
2/12/2013 01:53:23 am

You can try the method where you add recipients and add the mail item.

Reply
Matt Doar
2/14/2013 11:24:46 am

Shabbir, why not just define a notification scheme that uses a Custom Group Picker field. Then have the user populate the custom field and email will be sent to the groups in that field.

Reply
roark
3/25/2013 02:29:14 am

How do i include the package com.atlassian. jira in my project

Reply
J-Tricks
3/25/2013 03:47:25 am

Do you have the jira-api dependancy in the pom.xml? That will bring in most classes. Some of them are still part of core API and so you will have to add jira-core dependancy.

<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-core</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>

Reply
Subject will be something simple. We are going to keep it very simple!
2/26/2015 11:35:14 pm

:)

Reply

Your comment will be posted after it is approved.


Leave a Reply.

    Enter your email address:

    Author

    Jobin Kuruvilla - Works in Adaptavist as Head of DevOps Professional Services. 

    Author of JIRA Development Cookbook and JIRA 5.x Development Cookbook.


    RSS Feed

    Categories

    All
    Acive Objects
    Ajs
    Book
    Components
    Condition
    Custom Fields
    Customization
    Events
    Gadgets
    Javascript
    Jql
    Listener
    Mail
    Permissions
    Plugin Framework
    Post Function
    Properties
    Remote Invocation
    Reporting
    Rest
    Scheduled Tasks
    Search
    Services
    Soap
    Summit
    User Interface
    Validator
    Webwork Actions
    Workflow

    Archives

    October 2016
    August 2016
    March 2016
    January 2016
    December 2015
    May 2014
    December 2013
    November 2013
    July 2013
    June 2013
    April 2013
    October 2012
    September 2012
    August 2012
    July 2012
    May 2012
    March 2012
    February 2012
    January 2012
    December 2011
    November 2011
    June 2011
    May 2011
    April 2011
    March 2011
    February 2011
    January 2011
    November 2010
    October 2010
    September 2010
    August 2010

SUPPORT
APPS
TUTORIALS
THE BOOK
© J-Tricks