Alex Suslin

I'm a well known person within myself.

Help Desk With Jira via Emails

In our company we have two offices in USA and Europe. And we want to have a help desk platform and ability to create tickets via email. It is a common task and easily achievable with the help of JIRA, but we have some points, that are not so transparent how to reach.

The Goals

  1. Single email address to send inquires to.
  2. Single project to manage all the help desk tickets for two locations.
  3. Issues should be assigned to the proper person, depends on the location of the reporter.
  4. No commercial plugins should be involved (in worst case create custom mail handler)

Investigation

I’ve made some investigation, what we have and what is already written and how we can use it.

Jira already contains the basic mail handler that can be bound to the project. Unfortunately that handler is not supported several asignees (e.g. create component per location and assign task to the component lead). There is a commercial plugin JEMH that supports assignment issues to component lead, however it is needed to write the component name in email somewhere (subject, body) or have different email addresses. And in our case we want to have single email address for all the tickets.

I spent some time on it cause there is a possibility to use it for free when all the preferences are made manually through the config file (in commercial version there is a GUI for that). The other issue is that JEMH can’t be installed to grab mails from the IMAP folder like the out-of-the-box JIRA mail handler.

The idea was to create some rules on the mail server (we’re using google apps) and filter USA and Europe employee’s mails, assign the proper label and assign tickets to the proper components regarding the IMAP folder they are in. Ideally the combination of Jira mail handler and JMEH will work for us.

And we’re nearly agreed on the following solution:

  • Create separate projects in JIRA for USA and Europe offices
  • Each project will have its own Project lead
  • Setup to JIRA mail handlers and grab emails from the proper IMAP folder
  • Create some filters in gmail to apply the proper labels on mails.

I’ve asked my question on JIRA Answers. Nobody answer with the working solution, however there were an idea about JIRA post functions. Digging in post functions the following solution was born:


Solution

JIRA Project

  1. As a JIRA administrator create a project HELPDESK
  2. Create 2 components “USA” and “EUROPE”
  3. Assign to each of the component component lead

Add POP / IMAP Mail Server

  1. Log in as a JIRA administrator
  2. Go to Administration / System / Mail / Incoming Mail
  3. Click the button “Add POP / IMAP mail server”
FieldValue
NameGoogle App IMAP (or whatever you want)
DescriptionEmail Handler is used to create issues by email
Service ProviderGoogle Apps Mail / Gmail (IMAP)
Timeout10000
Username<your account name>
Password<your account password>
4. Test the connection and press "Add" button

Mail Handlers

  1. Press the button “Add incoming mail handler”
  2. First Screen:
FieldValue
NameHelp Desk
ServerGoogle App IMAP
Delay1
HandlerCreate a new issue or add a coment
Folder Name<leave blank>
  1. Second Screen:
FieldValue
ProjectHELPDESK (or whatever project you are going to use)
Issue TypeTask
BulkIgnore the email and do nothing
Forward Emailhelpdesk@company.com
Create UserFalse
Default Reporterusername (put someone in charge)
Notify Userunchecked
CC Assigneeunchecked
CC Watcherschecked
  1. Test and save

Groups

  1. Create two groups of users: “usa-employee” and “europe-employee”
  2. Assign all the employee to these two groups

Script Runner Plugin

As a JIRA administrator install the following plugin Jira Script Runner

Workflow

  1. As a JIRA administrator go to Administration / Issues / Workflow
  2. Copy your current workflow and change the name to “help-deksk-workflow”
  3. Go to Design view of that workflow and the gear icon, selecting “View Post Functions” from the menu

JIRA Workflow Design

  1. Click “Add Post Function” and select from the list “Script Post-Function”
  2. In the Script file path field insert the path to your groovy script (server path), please see below for the script source of my script helpdesk.groovy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.atlassian.jira.ComponentManager
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent
import com.atlassian.jira.util.collect.MapBuilder
import webwork.dispatcher.ActionResult
import com.atlassian.core.ofbiz.CoreFactory
import com.atlassian.jira.action.ActionNames
import com.atlassian.jira.security.groups.GroupManager
ComponentManager componentManager = ComponentManager.getInstance()
User remoteUser = componentManager.getJiraAuthenticationContext().getLoggedInUser() 
MutableIssue issue = issue
User currentAsignee = issue.getReporter()
GroupManager groupManager = ComponentManager.getComponentInstanceOfType(GroupManager.class)
Project project = issue.getProjectObject()
ProjectComponent component = null
if (groupManager.isUserInGroup(currentAsignee.getName(), "EUROPE"))
  component = componentManager.getProjectComponentManager().findByComponentName(project.getId(), "EUROPE")
else if (groupManager.isUserInGroup(currentAsignee.getName(), "USA"))
  component = componentManager.getProjectComponentManager().findByComponentName(project.getId(), "USA")
if(component != null)
{
  issue.setAssigneeId(component.getLead())
  issue.setComponents([component.getGenericValue()])
   
  Map<String, Object> actionParams = MapBuilder.build("issue", issue.getGenericValue(), "issueObject", issue, "remoteUser", remoteUser, "dispatchEvent", Boolean.FALSE);
  ActionResult aResult = CoreFactory.getActionDispatcher().execute(ActionNames.ISSUE_UPDATE, actionParams);
}

Code is obvious. It’s a groovy script (to be honest, never dealt with it before and java itself). It’s just trying to resolve the reporter group and if the reporter in USA group, the task is updated with proper component and component lead. The same for the EUROPE group.

  1. Save the post function and the workflow.
  2. Go to Workflow schemes and create the new one “help-desk-scheme” and assign the “help-desk-workflow” workflow for lets say just tasks.

The Final One

  1. Now go to project “HELPDESK” / Administer Project
  2. Open “Workflows” tab. Action / Select a scheme and choose our “help-desk-shcema” as a primary schema for the project.
  3. Here we’re!

Testing

Now, lets try to send email to our helpdesk mail addess. You should see something like: Hooray! It's working!


Hope that helps someone else!

Daily Backup Atlassian JIRA & Confluence on Windows

Requirements:

  • daily jira & confluence mysql database backup;
  • daily backup of jira & confluence attachments directory;
  • backups archiving;
  • deleting the old backups (more than 14 days);

Please note that I had a requirements for windows machine, and I understand that linux provides more scalabale and elegant way to do that. That is a basic script that can be used as a working solution, any system administrator can do that without my help :)

At first, let’s define the variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
::Path to the directory with attachments (JIRA or Confluence)
set attachments="C:\Program Files\Atlassian\Application Data\JIRA\data"

:: Path to the directory for daily backups
set backup_folder=D:\Backups\Atlassian\JIRA\daily_backups

:: Path to mysqldump.exe
set mysqldump_path="C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump.exe"

:: Username of MySQL database
set dbuser=root

:: Password to MySQL database
set dbpass=<change password>

:: Database that we're going to backup (JIRA or Confluence)
set dbname=jiradb

Every backup should have a unique name. So I’m proposing to use year, month, day and time interval in that name.

1
2
3
4
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set dt=%%c-%%a-%%b)
For /f "tokens=1-4 delims=:." %%a in ('echo %time%') do (set tm=%%a%%b%%c%%d)
set backupdate=%1%dt%_%tm%
set date_folder=%1%dt%

Please feel free to name it as you wish. In my case the name pattern is : [db name].YYYY-MM-DD_tt

date_folder variable is for a directory. I’d like to have a folder with the name like YYYY-MM-DD that will be created on a daily basis and put the proper backups in it.

Thus, let’s create the directory if it is not created yet:

1
2
3
if exist %backup_folder%\%date_folder% GOTO NODIR
   mkdir %backup_folder%\%date_folder%
:NODIR

After that, the regular backup process with the help of mysqldump and archiving with 7zip. After that we can clean the archived file (as we have archive).

1
2
3
%mysqldump_path% --user=%dbuser% --password=%dbpass% --databases %dbname% > "%backup_folder%\%date_folder%\%dbname%.%backupdate%.sql"
"zip\7za.exe" a -tzip "%backup_folder%\%date_folder%\%dbname%.%backupdate%.zip" "%backup_folder%\%date_folder%\*.sql"
del "%backup_folder%\%date_folder%\*.sql"

Do not forget to archive our attachments:

1
"zip\7za.exe" a -tzip %backup_folder%\%date_folder%\attachments.%backupdate%.zip %attachments%

And what we still have to do is to delete the old backups:

1
forfiles -p %backup_folder% -s -d -14 -c "cmd /c if @isdir == TRUE rd /s /q @path"

That’s it! Now we can use that batch script in Windows Task Scheduler and scheduled it on a daily basis.

P.S. If the task is not working, please check: - Task should be launched even when the user is logged off - The user that is launching that task has the permissions to do that (r/w permissions) - Task should be launched from the directory where the script is located (optional parameter, but it is required to set the proper path)

P.P.S. If you would like to download script, please find it here: download