Recently in OmniFocus AppleScript Integration Category

For the final piece on my series on using AppleScript to add information to OmniFocus, I'm going to describe how to send news items from NetNewswire. It ended up being a lot simpler than I thought that it was going to be.

The hardest part was getting an object for the selected headline. I must be missing something, because I couldn't find this in the NetNewswire dictionary, but a Google search turned up the solution: use the selectedHeadline property. It, in turn, has many properties, of which the title and URL are of particular interest. These values are set into variables to send to OmniFocus later:

tell application "NetNewsWire"
    tell selectedHeadline
        set t to title
        set u to URL
    end tell
end tell

From there, it's the standard code to create a new task in OmniFocus:

tell application "OmniFocus"
    tell default document
        set theProject to project "Follow Up"
        set theContext to context "Online"
            of context "Mac" of context "Home"
        set newTask to make new inbox task with properties
            {name:t, note:u, context:theContext}
        set assigned container of newTask to theProject
		
        compact
    end tell
end tell

And that's it!

While I'm by no means an AppleScript expert at this point, I definitely know enough to get stuff done using AppleScript. I think I'm missing something in that I couldn't find out how to get the currently selected headline on my own (and I have had similar issues with other research this week), but in time I'm sure that I'll get it down.

Yesterday, I described how to send the current tweet in Twitterrific to OmniFocus. Today, I'll show you how to create an OmniFocus task containing the URL and title of the current window in Safari.

At first, I thought that I wouldn't need to write this script, since OmniFocus can bring in the current Safari URL using the Clippings feature. However, in order for this to work, some text in the web page must be selected first (which will become the title of the task). I'm fine with always using the title of the page, so I don't need to worry about finding the title somewhere on the page to copy it.

Anyway, the URL and title of the active Safari window need to be retrieved with AppleScript. For some reason, the document object contains the URL, while the window contains the title. They can be found like this:

tell application "Safari"
    set u to URL of front document
    set t to name of front window
end tell
The front modifier tells Safari which property to route the request to. This ensures that the window that you're working in will be the one that gets the request. Now that we have the URL and title, the same code that was used yesterday to create the task can be reused here, plugging in the data from above:
tell application "OmniFocus"
    tell default document
        set theProject to "Follow Up"
        set theContext to context "Online"
            of context "Mac" of context "Home"
        make new inbox task with properties
            {name:t, note:u, context:theContext}
        set assigned container of newTask to project theProject
        compact
    end tell
end tell
And that's it! As always, if you have any questions, comments, or suggestions, please let me know.

Today I'm going to describe how I can send the contents of the currently selected Tweet in Twitterrific to OmniFocus using AppleScript.

The first step is to pull the necessary information from Twitterrific. In my case, I'm going to use the name of the poster as the title of the task, with the text of the Tweet as the note on the task. While this seems a bit weird at first, I couldn't think of a better way to handle it - while the content makes sense as the title at first, links in task titles aren't clickable. Plus, that could result in some pretty long tasks titles. This seems like the most automatic way of handling the situation.

In Twitterrific's AppleScript dictionary, there is a tweet object that contains a variety of information about the tweet. Today, only two properties are of interest: text (which contains the content of the tweet) and user name (which is the real name of the poster (and yes, AppleScript properties don't have to be just one word, which takes a bit of getting used to)).

For me, the hardest part of understanding AppleScript is the syntax. While it is my understanding that Apple developed it so that AppleScript would be easy for most anyone to use, for me this is hardly the case. Maybe it is because I'm use to more traditional programming languages, but AppleScript's English-like syntax strikes me as rather odd. I'm starting to get used to it, finally, but it's extremely different from any other programming language that I've used.

To pull information from a running application, you tell the application what information you want. To get the text of the currently selected tweet, the following AppleScript will do just that:

tell application "Twitterrific" to set tweetText to the text of selection

This sets the contents of the variable tweetText to the value of the text property of the currently selected tweet.

If multiple actions are desired against the same application, then you can use a multi-line tell:

tell application "Twitterrific"
    set tweetText to the text of selection
    set tweetPoster to the user name of selection
end tell

In addition to getting the content of the tweet, it also sets the real name of the poster to the tweetPoster variable.

Now that we have the information that we need from Twitterrific, we need to send that information to OmniFocus by creating a new task. This is a bit more complicated, but not too bad.

All projects, contexts, and tasks in OmniFocus are saved in a document. The document that is opened by default when running OmniFocus can be retrieved by getting the value of the default document property of the OmniFocus application. Since we're going to be asking multiple things of the document, I'm going to create a multi-line tell for it:

tell application "OmniFocus"
    tell default document
        -- Interact with the document here
    end tell
end tell

(In AppleScript, -- is the comment character. Any text after that line is treated as a comment, and is ignored when the script is executed.)

In order to create a task, the following information is needed:

  • Task Name
  • Context
  • Project
  • Notes

We have the name and note for the task already - those are stored in the tweetPoster and tweetText variables, respectively. The context and project for the task can be retrieved from the OmniFocus document that we just set up.

First, the project. Each OmniFocus document has a projects collection that can be used for this. In my case, I have a "Follow Up" project that I use to keep any tasks that I want to look into later. To get this project from AppleScript, use the following:

set theProject to project "Follow Up"

To use a different project name, just change the text in the quotes.

Getting the context can be a bit more tricky. If you want to use a top level context (that is, a context that is not within another context), then it is as simple as getting the project, only replace project with context:

set theContext to context "Online"

However, in my case, the context that I want to use is within two other contexts. To get my context, you just chain them together:

set theContext to context "Online" of context "Mac" of context "Home"

Now that we have all of the necessary parts of the task, we can tell OmniFocus to create. This is done using the make action:

set newTask to make new inbox task
    with properties {name:tweetPoster,
        note:tweetText,
        context:theContext}
    set assigned container of newTask to theProject

(You do not need to have the first two lines on separate lines - I only wrote it that way so that it would look nicer here.)

The project of the new task can't be set using properties, but instead it is set to the assigned container property of the task.

While the new task is now created, it is still sitting in the OmniFocus Inbox - even though it has a project and context defined. While you could press the Clean Up button manually in OmniFocus, that isn't very automatic now, is it? ;) Thankfully, this too can be accomplished via AppleScript:

compact

And that's it! The contents of the current tweet in Twitterrific are now safely stored in OmniFocus to be processed later.

Click the "more" link below for the full text of the AppleScript described here. If you have any questions, comments, or suggestions about this, please don't hesitate to ask. :)

I've been meaning to look into AppleScript for some time now, but I never had a reason to. This past week, I finally motivated myself to do so, since I had a goal in mind.

When I was reading my RSS feeds using Google Reader, I would star an item that I wanted to read later instead of right then. Once I had some time, I would go to my Starred Items and then read through them, or act on them as appropriate.

I have a similar process for Mail - if I wanted to remember a message for later, I would flag it and then go through the Flagged Items folder as necessary.

Once I started using Twitter, things got a bit more complicated. I finally settled on using Twitterrific as my Twitter client. While I does have built-in support for adding Favorites (which I would treat like Starred items in Google Reader), it has no way of listing my Favorite Tweets. This requires me to remember to go to the Twitter website, and then go to my Favorite Tweets section. Not the easiest thing to do in the world.

I realized that there must be a better way to handle this, since it was easy for me to forget that I had Favorite Tweets that I needed to go through. Since Twitterrific has an AppleScript dictionary, I wondered if I would be able to pull out the contents of the current Tweet and store that somewhere else on my computer where I would be more likely to remember to go through the tweets there.

OmniFocus seemed like the most logical place to put this information, since I keep the rest of my to do items there as well (with the added bonus of getting them automatically synced onto my iPod touch, as well). Since OmniFocus also has an extensive AppleScript dictionary, this approached seemed to have promise.

This then lead me to thinking about how to move my other to do/follow up items into OmniFocus as well. Mail shouldn't be a problem, but Google Reader would be another matter entirely. Since I use Firefox as my web browser (which doesn't much at all in the way of an AppleScript dictionary) this could be problematic. However, I've been thinking of switching back to Safari for a few weeks now, so this might just be enough to push me over the edge.

I have never done anything with AppleScript before (aside from copying some code into Script Editor and saving it), so this should be quite the learning experience for me. To help others out in the same situation, I am going to post the scripts that I came up for to pull follow up items from Twitterrific, Safari, and NetNewsWire into OmniFocus so that all of my information will be in one centralized location.

I hope that you will enjoy this series as posts as much as I had fun making them. :)