Jira and Omnifocus

Hello Guys,

Since the absence of a simple way to synchronize Jira with OmniFocus, I created a native Sync Plugin, which works without complicate requirements.

Looking forward to getting some feedback about bugs and about my implementation. It currently works the way I need it for my projects. All Details here:

Regards Bastian

2 Likes

Greetings! Great idea, and thank you for sharing with the Automation community. I’m sure this project will inspire fellow Omni Automation enthusiasts. Also, glad that the new Fetch APIs are working for you.

A couple small issues:

  1. The plug-in is using an older template design where the action was stored in the _ var. New design uses self-invoking anonymous function like the example shown below.

  2. Since the plug-in is only targeting OmniFocus (and not other Omni apps as well), you can use the app-specific file extension of “omnifocusjs” which will cause the plug-in to adopt the proper OmniFocus plug-in icon and trigger the installation process when the plug-in file is opened.

     (() => {
     	var action = new PlugIn.Action(function(selection, sender){
     		// action processing code goes here
     	});
     	
     	action.validate = function(selection, sender){
     		// perform any status checks and returns a boolean value
     		return true
     	};
    
     	return action;
     })();
    

Cheers!

Thank you @Sal

Updated the File Extension and the Template design.

Some Updates:

  1. The JavaScript Programmer Martin Joly helped me and made the code JavaScript Style and not Python Style any more ;)
  2. The Plugin has now the option, to add all Jira Ticket Comments as Subtask to the Task (for me a perfect)
  3. The Plugin now supports multiple Jira instances.

Cool. I can’t wait until I have time to try this out.

Does it support OAUTH or am I going to still have to figure that out for myself?

Nope Sorry, currently only AuthBasic with Password or API Key.
Don’t have the need for OAUTH currently, but I’m open for contributions.

I suspected as much. When/if I get to this, I fully expect to share any OAUTH updates back to you in a pull request.

I can not find any notation about what the URL needs to be and I am concerned this is the reason this script is not working for me.

I am getting this on the console:

NOTICE: Synced https://___.atlassian.net/jira/software/projects/___/boards/1. Checked 0 Tickets, Created 0 new tasks, Added 0 Subtickets for Comments

The edits I made:
(() => {
const action = new PlugIn.Action(function (selection, sender) {
// START EDIT
const configs = [{
user: “email address used”, // use email address for jira cloud
password: “api key used”, // you can use api tokens, see https://id.atlassian.com/manage-profile/security/api-tokens
jiraUrl: “https://.atlassian.net/jira/software/projects//boards/1”,
omnifocusTagToUse: “Jira”, // you can also use the format “Parent1 : Parent2 : Child”
jiraQuery: “assignee=currentuser() and resolution is empty”,
processComments: false, // if true, a subtask is added for each ticket comment
omnifocusCommentTagToUse: “Jira-Comment”,
// },
// {
// user: “”,
// password: “”,
// jiraUrl: “”,
// omnifocusTagToUse: “”,
// jiraQuery: “assignee=currentuser() and resolution is empty”,
// processComments: false,
// omnifocusCommentTagToUse: “”,
//
}]
// END EDIT

Hello Anthonii,

You don’t need the URL to the board, just the base URL of the instance, so the URL with the main folder where Jira is in.

For the instances I work with, its https://jira.domain.de/ and in another case https://domain.de/jia since there it’s in a folder instead a subdomain.

From the Base URL you give, the script needs to reach /api/rest/2

1 Like

Thank you, in my region I had to use the following. https://domain.atlassian.net My next question is, can I have these imported into a specific folder/project directly?

Not yet, but I’m thinking already about a concept to build it. Problem: I sync with more than one instance, so how can I make sure to not miss a new ticket direct after a sync without clicking through the Projects.

Don’t want to use an extra view for that instead the inbox. But will come somehow :)

1 Like

I do ask, but there is something magical that comes when I process my inbox. It is certainly not necessary.

Hello Together,

Just pushed a small but important update.
Tasks with Subtasks are no longer closed automatically.
This Improves the Handling of the Sync Comments Function a lot, and makes is less possible to miss something.

I also planned to integrate the Credential Store. But seams I can’t use it for my kind of Configuration, where you can add multiple Instances? Or has someone an Idea for me? Want to get rid of Credentials in the Script. Would also make updates easier.

I got nerd sniped with this and thought I’d send you my opinion:
( Feel invited to disregard )

I would imagine you can use an extra set of k/v pairs to assess that user/site combo’s existance.

essentially give yerself a namespace to be able to safely leave yourself breadcrumbs to be able to constrain userdata exposure and be able to predict the data a bit.

that way, jondoe-myinstanceone can be a different credential than billdoe-myinstanceone

create a key in which you enumerate which sites youve seen thus far. something like [myinstance]
and then create a key for myinstanceone with a val of [jondoe, billdoe]

(hashed somehow such that you’d not be obviously revealing anything to someone perusing datasets looking for ‘Oh Interesting…’ )

then you know which sites you’ve seen before
and you know which usernames already should have their own set of creds
and they’re all stored safely… because each value and each key is idempotently encyphered before it’s saved… so you have to decrypt it before you display it, but since most of the time you’ll be able to ask if there’s a match rather than asking for a list of things to display, the overhead of that isn’t quite as painful… as you only have to encypher the username and make the query which will tell you if that username is a value you’ve seen before for that domain, and therefore whether or not you have a credential stored for it…
without revealing anything meaninfully sensitive,
without overloading upstream things,

essentially
if you’re able to store a thing securely,
and
you’re able to store many things,
and
you’re able to store many distinct things securely,

then you have the foundational isolation necessary to be able to reasonably obfuscate the underlying data, without overcomplicating things too terribly much… the downside is that human readability of datasets becomes completely useless as a diagnostic; but that’s kinda the the point in certain areas, right? :)

anyways… hope this helps more than it doesn’t?

and if it doesn’t… well… mea culpa… at least maybe the knowledge that someone wanted to say thank you for making something cool and had an idea that might make your day a little easier, or might not, but I didn’t want to not offer my … uh… $.03…

Blockquote Hello Guys,

Thank you I just made an exam because of you.