set theMacroGroupName to "_Tests"
tell application "Keyboard Maestro"
set theMacroGroup to macro group theMacroGroupName
tell theMacroGroup
-- Creates new macro
set theMacro to make new macro with properties {name:"_New Macro"}
tell theMacro
-- Creates the AppleScript Action
make new action with properties {xml:"<dict>
<key>ActionColor</key>
<string>Green</string>
<key>ActionName</key>
<string>Open File</string>
<key>ActionUID</key>
<integer>15806619</integer>
<key>IsDefaultApplication</key>
<true/>
<key>MacroActionType</key>
<string>Open1File</string>
<key>Path</key>
<string></string>
</dict>"}
end tell
end tell
end tell
Now I will just create the complete macro to add a Prompt to paste the path and name of the link, etc. Will share it here once it's done in case someone else wants to use it
Have you got the KM AppleScript dictionary open? Check the entry for "duplicate":
duplicate v : Copy an object.
duplicate list of specifier : The object(s) to copy.
[to location specifier] : The location for the new copy or copies.
→ list of specifier : The duplicated objects.
...and the last line tells you "the result of the duplicate action is a list of the new duplicates".
It's always a list, even if you only duplicate one thing, and you access the contents of a list item by item -- so you grab the contents of item 1 of the list and put them into newMacroID. newMacroID now hold a reference to first (in this case, the only) thing you duplicated.
You don't actually have to go any further -- that reference is the macro ID. For example, in Script Editor:
tell application "Keyboard Maestro"
set theMacro to item 1 of (get selectedMacros)
return theMacro
end tell
-> "F3B94063-5050-4E2D-8222-93EA72C9EFDD"
...from which you can get/set the name, etc:
tell application "Keyboard Maestro"
set theMacro to item 1 of (get selectedMacros)
set the name of macro id theMacro to "Whoops!"
end tell
I've been watching this discussion evolve in real time (yes, it's a s l o w day) and I was wondering how - after you've created all these single-action macros - you intend to actually call them up and run them. Just curious
So I want to transfer as much as I can from Raycast to KM, because some things I do with KM require me to create an actual AppleScript file that Raycast reads and triggers KM. If I just start using KM 995 of the time, then I don't need to create those files anymore and it's also faster, because the macros run directly when I select them in that window, instead of having Raycast trigger KM, which always takes 1-2 seconds.
So my goal is to start using CMD+Space for KM and OPTION/ALT + Space for Raycast as a secondary tool, while KM will be the main tool
Another advantage of using KM over Raycast (when I'm using the AppleScript files to trigger KM macros) is that I can easily assign an icon to a KM macro, but with Raycast I need to have a folder with all the scripts, then a folder with all the icons as png files, which I then have to manually assign if I want to see the icons next to the script. For example these are scripts without the icon, but with a default icon
I see...
So similar to the For Each action, even if only 1 item is selected.
So item 1 refers to the position of that item in the list (which can be 1 or more items).
Makes perfect sense!
Your explanation is on point! Thank you so much. Definitely saving this to my notes now.
This seems like a very strict approach to what I'm trying to have. It's easier for me to just hit a shortcut, which in my case is CMD+Space, and then search for anything I want to do, instead of having another shortcut just for a favorites window that I need to keep updating with new ones and then I need to scroll to find the one I want, etc. It seems harder to maintain than Raycast, actually, because with Raycast I created a macro that automatically creates a new script file with the name, the script inside, etc, from the selected macro.
If you are going to mess around with AS, start using a script editor -- it's much easier than trying things out in KM AppleScript actions. I'm stuck in my ways and use Apple's Script Editor (in the Utilities folder), but the cool kids will point you to Script Debugger which is much better, even in the free version.
Both will have an "Open Dictionary" menu item, from which you can select an app to view what (if anything, lots of apps don't support AS) commands are available.
My approach to this is to make a template Macro with the Actions I want and then copy this template Macro as XML. I edit this XML to replace the elements I want to customise with KM Variables.
Then I use an AppleScript to make new Macros with my bespoke elements. The nice thing is that the Macros aren't limited to single Actions as the XML is the whole Macro and can include lots of things such as the Macro trigger, its icon etc etc.
Really interesting approach as well!
It's still important for me to find other approaches such as AS so I can get used to it as much as possible, so my other solution was a good way to practice a bit more.
In your approach, you are using the Group Name instead of the ID, but what if I then change the name?
I can see the reference to both Name and ID in the XML:
So my question is: if the XML in my macro (that you saved as LOCAL__XML) contains:
_Tests
but then I change it
_My New Tests
will that still work, if I keep
FDC4407D-E1B2-4684-909A-CC0EC04C6423
in there?
How does KM know that it should use the Name and not the ID or vice versa?
tell application "Keyboard Maestro"
importMacros macroXML
end tell
I discovered (through trial and error when I was trying to find the simplest way to make new bespoke Macros) that when Keyboard Maestro imports a Macro with the same UUID as an existing Macro it automatically gives the imported Macro its own new UUID.
So using your approach, how can I make sure that it always goes to the right group, in case I rename the group (e.g. _My New Tests), other than updating the LOCAL__XML variable, of course. If I want to "set and forget" that macro.
I'm thinking that maybe we can use AppleScript to first create a variable that gets the name of the group from the Group ID and then use that variable in the Local__XML variable?
Okay. If in future you rename the Group but want new Macros to go into that same Group you would just change the name of the Group in the prompt and the new Macro will still go into the same named group. You would not edit the XML again.
Yes, but again, I would like to "set and forget" that macro so basically I wouldn't even have that field for the Group name, because on my macro I will have some conditions that will automatically set the group based on the content. For example if the URL is set to something that starts with ~/ I know that this is a Finder path and it will go to a group called "Internal Links".
If it starts with https or http then it goes to a group called "External Links".
I'm aware that making this change only takes a few seconds, but if I can create a macro that will do all the work for me automatically based on the ID of the group, regardless of the name, why not?
So I guess that the AppleScript approach to gather the group's ID and save it as a variable seems like the only way?
Yes -- but why? Having two (or more) Groups with the same name is just making your life more difficult!
But let's say we're trying to make a macro for other people, who may well have duplicate group names. Assuming you could detect that problem and give them some way to choose which group they actually meant, I would
Change the group name in the XML template to something (almost certainly) unique
Import the macro
Move the macro from that uniquely named group to the target group
Delete the uniquely named group
So for a temp group call "My_Clever_Group_Name" (I'd actually use a spoofed UUID) the important bit of the AS would be:
tell application "Keyboard Maestro"
importMacros macroXML
move first macro of macro group "My_Clever_Group_Name" to macro group id "94B3E220-2AE1-4957-973A-8ADFC260E35D"
delete macro group "My_Clever_Group_Name"
end tell
How you'd get the target group when there are multiple groups of the same name will depend on how you are getting the initial data. If you're hard-coding the group then that's easy -- just replace the id in the above.
Of course. Don't forget that the Macro I uploaded was the most basic I could make it just to show the technique. You can customise it to do whatever you need.
This was just a test to see if KM would allow groups with the same name or not. I was trying to understand if having a certain name in the XML would make a difference or not, so for example if the XML is set to having the group name "Tests", but that group is not available anymore (if the ID was 1234, for example), but there's another "Tests" group with ID 5678, then the XML would be using the 5678 group as the destination, which is not desired. So yes, that was just a test. I don't have any groups with duplicate names.
That's why I think that having the XML set to using the right name and ID is ideal to avoid any potential issues. And I can just set and forget that macro, regardless of what name I give the group in the future.
Let's say I rename the group and forget to update the XML. Every time I create a new link it will be adding it to a new group with the old name, right? So now I have to go and move all those macros to the new group and delete the old group. If I am using KM to avoid extra work, then that approach is convoluted when I can have a macro that does all the work automatically based on the ID and the current name of the group based on that same ID. Hope it makes sense?