OSX automator in clojurescript
I don’t quite remember how I found the post, but anyways I landed upon this blog by @mbcrump about how automator now supports Javascript as a language. I don’t even remember how I got the idea of playing with clojurescript to get it to automate tasks, but definitively read it somewhere. Update: Now I was reminded: @borkdude retweeted
(let [mail (new js/Application "com.apple.mail")
inbox (.. mail -inbox -messages)
first-message (aget inbox 0)](.subject first-message)) 2/2
— Daniel Szmulewicz (@danielszmu) October 29, 2014
So how did I go about this?
Starting a new Clojurescript project
This is always a pain, since I hardly ever do it. I took a chance on David Nolens mies plugin for leinigen
$ lein new mies applescript
This gives you a new project called applescript with a minimal directory-structure.
Transforming js to clojurescript
Given the js-code from @mbcrump’s post:
var Mail = Application('Mail');
content = "This is my message to you";
msg = Mail.OutgoingMessage({
subject: "Thanks",
content: content,
visible: true
});
Mail.outgoingMessages.push(msg);
Mail.activate();
it was quite easy to translate it to clojurescript
(ns applescript.core)
(def mail (js/Application "Mail"))
(def content "This is my message to you!")
;; Note the use of the #js reader macro to make a
;; clojure map into a js-map
(def msg (.OutgoingMessage mail #js{:subject "Thanks"
:content content
:visible true}))
;; Needed aget to achieve
;; mail.outgoingMessages.push(msg)
(.push (aget mail "outgoingMessages") msg)
(.activate mail)
$ lein cljsbuild once
builds it, but bob is not your uncle yet, since it will not run.
Making the stuff run
According to the post, it should only be a matter of running
$ osascript -l JavaScript file.js
to execute the script. Problem was, how to achieve this, telling leiningen to include all neccessary js into a file that osascript could run?
The solution
was in project.clj. changing
:cljsbuild {
:builds [{:id "applescript"
:source-paths ["src"]
:compiler {
:output-to "applescript.js"
:output-dir "out"
:optimizations :none ;; change this to :simple
:source-map true}}]}) ;; remove this
to
:cljsbuild {
:builds [{:id "applescript"
:source-paths ["src"]
:compiler {
:output-to "applescript.js"
:output-dir "out"
:optimizations :simple}}]})
gave me one file, applescript.js, containing everything, which I could run as
osascript -l JavaScript applescript.js
#Bonus Just for fun, having a look at applescript.js, all the way at the bottom, you find:
var applescript = {core:{}};
applescript.core.mail = Application("Mail");
applescript.core.content = "This is my message to you!";
applescript.core.msg = applescript.core.mail.OutgoingMessage({visible:!0, content:applescript.core.content, subject:"Thanks"});
applescript.core.mail.outgoingMessages.push(applescript.core.msg);
applescript.core.mail.activate();
Which translates pretty nicely to the original js-code.