Create macro that either creates a new macro or duplicates and renames macro [SOLVED]

For context: I've been using Raycast for a while now, but they have been improving the app while not offering support for old macOS so now some extensions are not working anymore. Not only that, but the vast majority of things I do there can easily be replicated with KM without the need for me to create additional scripts (I open Raycast and run an Applescript that triggers KM).

So I'm trying to use KM as my main Spotlight replacement and have Raycast for very specific things that I can't do with KM (yet).

One of things I do a lot with Raycast is create links to websites or internal links to files and folders in Finder. With Raycast that's super fast and easy:

How can I replicate this in KM?
I created a Macro Group called Links where all my links will be stored, internal or external. So I would like to create a macro that then creates new macros inside that group. I'm aware that using XML is probably the best option to create the actions inside a macro.

Now how can I create new macros and then rename them, and then add a single action? Each new macro will just contain one of these actions below, nothing else:

Or if it's easier, I can create a template macro inside that group and then let KM duplicate it, rename it, change the action inside. Whatever's easier to implement.

Thanks

EDIT: I'm getting closer, thanks to @Nige_S contribution here:

I was able to duplicate a macro with this simple script:

set newMacroName to "duplicated"

tell application "Keyboard Maestro"
	set newMacro to item 1 of (duplicate macro id "64163561-B5DB-4422-A5B2-B1E144A842D9")
	set the name of newMacro to newMacroName
end tell

Now I just seem to need it to edit the action inside that duplicated macro so first it seems that I need to know the duplicated macro's UUID or maybe the name?

So it's either that or create a completely new macro, if that's easier than going the "duplicate" route.

You already have a reference to the duplicated macro -- you stored it in newMacro and then used it when setting the name.

Could you use that to get the id? (Hint: yes!)

1 Like

I understand the logic behind that, but due to my still limited AS knowledge, it's hard to put that into script...
Can you explain what this is doing, in plain English?

set newMacro to item 1 of (duplicate macro id "64163561-B5DB-4422-A5B2-B1E144A842D9")

What does item 1 mean in this context?

What I read is: set the variable newMacro to "whatever item 1 means" of a duplicate of macro with the ID....

So I understand that now I need to grab the ID from newMacro, but I need to understand how that is translated into AS?

I tried this, even though I have no idea what I'm doing, and the action was validated, but then it doesn't work:

set newMacroID to item 1 of (macro id newMacro)

I also tried this, and even though it validated, doesn't work either

set newMacroID to (macro id newMacro)

UPDATE: I found this thread and it seems that this is what I need as a starting point:

I'm going to check it and then report it here if I find the answer :wink:

Aaaaaand... DONE!!!

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 :slight_smile:

How I can then grab the ID from a Macro Group or a Macro?
I would like to use ID instead of the name in case I rename the Group or the Macro.

And if you can still explain that line and what item 1 means, I'm always open to some more knowledge :slight_smile:

EDIT: I found how to get the ID... super easy and obvious haha

set newMacroID to newMacro

Using the first script I ended up with this:

image

and when I use Display in Window I get this:

image

Now I just need to merge all this information with the final script.
Getting closer and closer...

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
1 Like

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 :wink:

I just open KM's window and search for those macros.

Right now I use CMD+Space to open Raycast's window:

And I use OPTION/ALT + Space to open KM's window:

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

And these are the ones with custom icons, which require me to add them manually, once a week:

So by using KM I end up saving time and work every week and I don't have to have those folders with scripts and icons anymore

Wow - that sounds like hard work!

Have you thought of triggering your macros with a macro that looks like this?

image

It saves having to open KM and is more spotlight-like.

Then there's something like @mrpasini 's Favourites macro which is at the other end of the spectrum of complexity:

1 Like

How do I find that?

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! :slight_smile: Thank you so much. Definitely saving this to my notes now.

That's exactly what my OPTION/ALT+Space does:

image

That's why I get this when I hit OPTION/ALT+Space:

1 Like

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.

1 Like

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.

Here is a basic example:

EXAMPLE Create New Go to URL Macro v1.00.kmmacros (7.5 KB)

2 Likes

Yes, I use Script Debugger (used to use Script Editor in the past).
I'm just not familiar with the whole Dictionary stuff yet.

I found it:

image

I still need to understand how to read the content itself... :wink:

Thanks for sharing. This seems like a very useful tool (once I understand it)

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:

image

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?

This is the sneaky thing about my use of:

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.