Jump to content

Recommended Posts

I'm just getting started with creating my own workflows and I have a couple questions I haven't found the answers for yet after a bunch of searching, reading and testing.


A quick note to begin with, I'm writing this partially as an exercise to improve me proficiency with AppleScript, as frequently painful as it is. It does seem like a good workflow to use it for since its functionality is almost entirely reading information from and sending commands to the iTunes AppleScript Dictionary.  JXA is a little further down the to-learn list.


1. What is the proper way (if there is one) to get Alfred's workflow environment variables into an AppleScript file?


Right now I'm using the Script Filter to issue the Bash command osascript *file*, I can append a variable to it like "alfred_workflow_data" and read it as an argv or use (do shell script "pwd") to get the workflow path but I haven't found a way to access all of the variables directly.


I'm open to ultimately running it as a usr/bin/osascript if that's the best solution, but it's nice to just run the script from my code editor rather than copying and pasting it every time I want to test a change.


I have read the pinned post on using environment variables but I'm not sure how to apply it in this context.


2. It looks like the best practice is to use alfred_workflow_data and alfred_workflow_cache where possible but is it appropriate to use the workflow folder for things like included icons or should I be creating a data directory, copying the files there and then using that location when setting icons in a Script Filter?


Given that there doesn't appear to be a provided environment variable for the workflow folder path I wasn't sure if that was to discourage using that in the workflow or because it's trivial to determine that path another way.


3. I have a couple of different icons I'm using for different workflow components so I don't want them all to inherit the workflow icon but I also use some of the same icons for multiple trigger objects. If I assign them the same icon I get duplicate *iud*.png files, is there a way to set the path for the icon programmatically so I can set a single image to multiple objects?


4. Along similar lines, does Alfred allow you to use any vector formats for icons? It doesn't seem to accept SVG and it converts vector PDFs to PNG images but I know that some of Alfred's internal workflows use vector code for icons so I thought it was worth asking.


If not, is 512px the appropriate resolution? I've seen 128px referenced in older threads but that seems pretty small for uses like icons in the iOS remote app for devices like retina iPads.


5. Finally, is there a good way to assign multiple keywords to the same action? I'd like to trigger my script filter with both itunes and love and I had hoped that using a Keyword object as the input to a script filter would do it but while it still lets me trigger the action object I've linked the script filter to the script filter functionality doesn't work. 


I've also tried adding an Arg and Vars utility to overwrite the query to the keyword for the Script Filter but I get the same result. 


I can just duplicate the Script Filter with a different keyword but am trying not to repeat an identical function if I don't need to.


Thanks for any help, I really appreciate you taking the time to read over this.


The workflow in its current state can be found on GitHub.


Alfred 3.6.2 [921]
macOS 10.13.5 (17F77)
I've customized a lot of my macOS environment but I don't think anything that would affect AppleScript and likely not anything that would affect running osascript commands from /bin/bash.

Edited by chrisWhite
Link to comment

Regarding 1: You can't read workflow variables in an editor. They're environmental variables that only exist within Alfred, so to read them, you must run your script from Alfred (or a shell with the same variables exported). You use set myVar to (system attribute "variable_name"), as described in the sticky, but as the variable only exists within Alfred, that isn't going to work in Script Editor.


Instead of copying-and-pasting your script into Alfred (and you shouldn't use Run NSAppleScript in any case), save the script file in the workflow, and call it via a Run Script as you're doing with the Script Filter script.


Regarding 2: Leave icons in the workflow folder. They're part of the workflow, not data, so they belong in the workflow folder.


There isn't an exported variable for the workflow folder because that's the working directory when your workflow is run, i.e. the workflow folder is always ./. You don't need to faff about with workflowPath in your script. Just use ./icons/notplaying.png etc.


I'd say it's generally not worth the effort trying to make your workflow scripts runnable from anywhere. As soon as you start using workflow variables or adding control flow to the workflow in Alfred's workflow editor, it becomes largely pointless to run the scripts from anywhere else. cd to the workflow's directory in your shell, and do your command-line stuff from there.


Regarding 3: You can only set icons programatically in Script Filter output. Your best bet is to make the duplicates symlinks to the original.


Regarding 4: No SVG. You can use ICNS files, though. I usually use 256px icons. But I'm not a good icon guy.


Regarding 5: You can't easily assign two keywords to a single Script Filter (you have to duplicate the filter). But you can connect multiple Keyword Inputs to one Script Filter.  Where you seem to be going wrong is with the Args & Vars Utility. The Script Filter's keyword is for calling it directly from Alfred's query box. You don' t use it in the workflow: the connection is enough to run the Script Filter. What you're actually doing is passing the query "love" (which is perhaps intended?) to your Script Filter, but it isn't configured to accept a query…


This is all a bit complicated to explain in text, so I've submitted a PR with some fixes.

Edited by deanishe
Link to comment

Wow, thank you so much deanishe, your answers and pull request were immensely helpful!


Regarding 1, that makes sense about variables, while I'm okay at bash scripting I'm still figuring out what information AppleScript has and what it doesn't, I figured it wasn't a full shell but didn't know if it could access some of the same information, thank you for clarifying! I agree that the Run NSAppleScript object wasn't ideal, it's where I started before switching to the Script Filter, learning a lot more and hadn't gotten back to reworking the action itself, I'm glad it looks like I would have been on the right track!


Regarding items in the workflow directory, I had tried to call them using a relevant path but had missed the leading `.`, that's much easier to work with! I didn't plan to leave the code in there to allow it to be run anywhere, just did to for convenience as I was working on it but with a working relative path even that's unnecessary.


I hadn't thought of using a symlink, that's brilliant!


Thanks for the info on resolution, I'll try 256px and see how they look on an iPad.


Regarding the last item, I had tried chaining a Keyword as input to the Script Filter like you reworked it but while it will execute the downstream action it won't trigger the Script Filter's functionality to run so I get the placeholder result rather than actual results, it sounds like I should just use duplicate script filters and running a script file limits the repeat for the most part, just hoped there might be a better approach. 


@Andrew if you don't mind a feature request it would be wonderful if you could set multiple keywords throughout Alfred, something like `love|itunes`, I definitely would use them for workflows and web searches so I could assign general keywords that I can arrow/number select from when I'm blanking on a specific keyword. Here's an example of where I've chosen general over specific:



Edited by chrisWhite
Link to comment
33 minutes ago, chrisWhite said:

I agree that the Run NSAppleScript object wasn't ideal


It's not so much the copy-and-pasting (which is fine for short scripts), it's that Run NSAppleScript (as opposed to using a regular Run Script with language = /usr/bin/osascript (AS)) executes on Alfred's main thread, blocking the app. Run Script actions are executed in subprocesses. Also, Run NSAppleScript behaves weirdly sometimes and code that works fine in Script Editor or a regular Run Script action doesn't in a Run NSAppleScript.


33 minutes ago, chrisWhite said:

I had tried to call them using a relevant path but had missed the leading `.`


AFAIK, the leading ./ shouldn't actually be necessary. icon.png and ./icon.png are equivalent paths, and it should only make a difference when you're trying to execute a command in your shell. Perhaps an AppleScript weirdness? It wouldn't be the only one…


33 minutes ago, chrisWhite said:

while it will execute the downstream action it won't trigger the Script Filter's functionality to run


It won't trigger it automatically, no. You have to hit ↩ to run the downstream element. That's how Keywords work.


33 minutes ago, chrisWhite said:

running a script file limits the repeat for the most part, just hoped there might be a better approach.


Exactly. Generally, doing stuff with workflow elements is clunky compared to doing it in code. There's no way around it, though, because the way Alfred is designed requires that your script always passes control back to Alfred.


But why do you want multiple keywords for the same thing, anyway? Users can change keywords at will, and Alfred will preserve them across workflow updates.


33 minutes ago, chrisWhite said:

if you don't mind a feature request


You should post that in the appropriate forum, where other members will see it, too. Let's keep this thread about your workflow.

In any case, you might find this workflow useful. It shows the keywords for all your workflows.

Edited by deanishe
Link to comment

Yeah, I had picked up a little bit about the actual problems for NSAppleScript doing forum searches along the way, copy and paste is a minor thing.


I just tried omitting the `.` in the icon path to make sure I hadn't originally had a typo or other error and Alfred does not show an image without it, I'm not sure whether it's an AppleScript problem however since the JSON is returning the correct path to Alfred, does Alfred care what is being executed or just what is returned back?

"icon": {
	"path": "/icons/unloved.png"

That makes sense about how keywords work, I hadn't thought through that entirely.


In terms of duplicate keywords, yeah, there are contexts in which having multiple keywords are helpful, between Alfred, Keyboard Maestro macros, app shortcuts, Karabiner triggers, TextExpander/Alfred/Teacode Snippets and app palettes commands for Visual Studio Code, Sketch, etc. it can be hard to remember everything so being able to fallback on a general keyword, like iTunes for all iTunes workflows makes things easier and is still usually faster than consulting a cheatsheet or that workflow (though I do use it as well ?).


Yes, it would be better to consolidate automation workflows but that's a constantly ongoing evolution.


Thanks again, I can't tell you how much I appreciate your help!

Link to comment
1 hour ago, chrisWhite said:

"path": "/icons/unloved.png"


Yeah, that's a completely different thing. Any path that starts with a slash is an absolute path. You can't just leave off the ., you have to omit the following slash, too:

./relative/path is the same as relative/path. Start with a slash and you have /an/absolute/path.



Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...