How to do `If this macro was recently ran (< 2 seconds ago)` do one thing, if not, do another thing

I have this macro:

I want to make a change to it that if I trigger this macro from non Pathfinder app, say Safari.

And then within 2 seconds, trigger this macro again. Instead of doing this part:

It would do Enter keystroke. But if the 2 seconds passes after I activated the macro, it will Activate last application as it does now.

Not sure how to do this in a nice way.

Thanks. :black_heart:

Hi!
Here's a demonstration of how it can be set up:

DEMONSTRATION- If Your Macro Last Ran Less Than [Your Set Time Interval] Seconds Ago.kmmacros (4.1 KB)
(v11.0.2)

The time interval could also be added straight into the second calculations field of the Switch action by adding the number 2 there in place of local_yourSetTimeInterval

2 Likes

You can use AppleScript to get the last used date of any macro by supplying it’s UUID.

For instance, the following returns the last used date of my “Scratchpad” macro. (click to expand/collapse)
tell application "Keyboard Maestro" to tell macro id "D99EA4F2-C87E-4CF8-B540-E880315F215E" to return used date as string

The results look like this: Wednesday, February 14, 2024 at 11:36:41.

There are a variety of ways to parse date/time stamps for comparisons. I'll work on a sample for you and post it when able.

EDIT: Here’s an example of how you can do different things depending on if a macro was executed within the last two seconds or not. You will need to replace the UUID in the AppleScript action with the UUID of your macro in question.

Download Macro(s): Do different things if more or less than two seconds since last execution.kmmacros (5.6 KB)

Macro Image (Click to expand/collapse)

Macro Notes (Click to expand/collapse)
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
  • The user must ensure the macro is enabled.
  • The user must also ensure the macro's parent macro-group is enabled.
System Information (Click to expand/collapse)
  • macOS 13.6.3
  • Keyboard Maestro v11.0.2
3 Likes
Disproven Beliefs

That AppleScript is a nice take, but it looks to me like your example macro wouldn't work, as the calculation in the If Then is placed in a text field/condition. I believe you'd have to either format the calculation in the text filed as %Calculate%NOW()-CALCULATE(%Variable%debug__lastRunEpoch%)%, or change the condition to Calculation, formatting it as NOW()-CALCULATE(%Variable%debug__lastRunEpoch%) > 2

Have you actually tried my sample? :wink:

Oj …
I actually did, but as the AppleScriped failed (with the error message in the hidden tag bellow), and didn't have time to figure ut why, I just noticed the text field formatted in a way that seemed foreign to me having always believed I have to wrap a calculation in a text field in a %Calculation%%-token. But setting it up now, feeding a valid epoch-time into the variable I can se that the Text-condition indeed evaluates the calculation in the format you've added. And I am not only humbled, but also stumped, as I do not understand anything of the why and the how of this. All information I've been able to find in the wiki supports my now disproved believes: wiki.keyboardmaestro.com/Text_Fields

AppleScript Error Message
2024-02-14 19:31:38 Execute a Shell Script failed with script error: Failed conversion of ``Wednesday, 14 February 2024 at 19:31:37'' using format ``%A, %B %e, %Y at %H:%M:%S''
date: illegal time format
usage: date [-jnRu] [-I[date|hours|minutes|seconds]] [-f input_fmt]
            [-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]]
            [[[[mm]dd]HH]MM[[cc]yy][.SS] | new_date] [+output_fmt] in macro “Do different things if more or less than two seconds since last execution” (while executing Convert human readable time to unix epoch format).

Edit: If you @cdthomer, or anyone, could shed light on why your approach works, I'd love to have it clarified, here or in a PM, because this is totally new to me

Welcome to the club as this is my perpetual state. :sweat_smile:

FWIW, that’s not an AppleScript error, that’s the shell script failing to convert from human readable to epoch (UNIX) formatted timestamp. Not sure why it’s failing because I believe date is a standard part of macOS command line utilities. Wait a minute... I think it might have to do with how your system preferences display dates and time. The results from the AppleScript on my system are like so: Wednesday, February 14, 2024 at 13:26:47... but if your results are different, then the shell script would need to be adjusted to match. If you show me the output of the AppleScript, I can tell you how to adjust the shell script.

Let me mull it over. I’m not sure off the top of my head as this is literally the way I’ve always done things and never thought about why it works the way it does.

1 Like

Hello Chris (@cdthomer)

Is there any reason of hardcoding the Macro's UUID into the AppleScript ??

I've several Macros with Last Runtime checking involved and in all of them I use this method:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions



set kmInst to system attribute "KMINSTANCE"

tell application "Keyboard Maestro Engine"
	
	set macroUUID to getvariable "Local__MacroUUID" instance kmInst
	
end tell

tell application "Keyboard Maestro" to tell macro id macroUUID to return used date as string

Of course, I am thinking about leaving the leading Variable Local__MacroUUID suing the %ExecutingThisMacroUUID% - Token behind by integrating this into the AppleScript but that's something I haven't figured out yet I think....

I would go with this method though - No more editing in the future if you use many Macros set up like this

have a great day

Greetings from Germany

Tobias

You are very much correct in your assumption! The AppleScript on my computer returns Thursday, 15 February 2024 at 16:38:16 (day month year format), while yours returns month day year. Yeah, thank you, if you could tell me how to alter the Shell-script that'd be great, as my first (and only) idea, swapping the %B with the %e, did not work

Haha, thanks! Not in any way an uncommon state for me to be in either



After some testing here now I have finally been able to make sense of why your approach (and now coming forward probably also my way of doing it), is working!

  1. The text field of the Text condition takes the NOW()-%Variable%debug__lastRunEpoch% and processes it into NOW()-1707935691
  • The 1707935691-part in this case is the epoch time value from Wed Feb 14 2024 18:34:51 GMT+0000 (when I last tested your macro yesterday).
  1. Then the is > evaluation performes a calculation on NOW()-1707935691, something that is a perfectly valid calculation in KM!
Here's the test macro where I was able to make sense of this

TEST Functions and calculations in text fields.kmmacros (17 KB)
(v11.0.2)


(Click Image Above To See The Macro In Full)

In this case it was just an example, and you could certanly pass it as a local variable, but if you put it directly into the AppleScript you can have one less action in the macro itself.

For some reason, some tokens don’t seem to pass correctly to AppleScript, or I simply don’t understand how they work. Because the following should pass and return a token...

Pass the %ExcecutingThisMacroUUID% token to AppleScript (click to expand/collapse)
tell application "Keyboard Maestro Engine" to set kmToken to process tokens "%ExecutingThisMacroUUID%"
return kmToken

The above does work for some tokens, but not all. Perhaps @peternlewis could shed light on this (I’ll do another search in the meantime in case he’s not able to respond).

You only needed to remove the commas that mine had but yours didn’t.

date -jf "%A, %e %B %Y at %H:%M:%S" "$KMVAR_debug__lastRun" +%s

Yep, that makes perfect sense and is the way I always understood it to work. That’s why it’s really the only method I’ve ever used.

1 Like

The AppleScript, when accessing the engine, is accessing it without any reference to what you consider the current running macro. So anything that is specific to that macro cannot be accessed (eg local variables, instance variables, as well as tokens like the ExecutingThisMacroUUID token.

You can pass the instance to Keyboard Maestro like this:

set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine" to set kmToken to process tokens "%ExecutingThisMacroUUID%" instance kmInst

But that only works for variables, not for other kinds of tokens like this, so even that wont work.

What you can do is store the value in an local variable, and then access it.

image

2 Likes

That makes perfect sense, thanks for the info.

Any advantage in doing it the way you showed versus the way I would normally do as shown below?

Actions Screenshot (click to expand/collapse)

3 Likes

No. getvariable makes more sense, I was just doing the minimum change, plus demonstrating that process tokens can take an instance parameter just like getvariable.

3 Likes

A big „Thank you“ for clarifying this, from me, too.

What is if I tend to use the token in a variable but instead of doing it with a set Vatiable action as it’s supposed in the editor like in your example would want to use the variable action‘s xml in the AppleScript code and access it from there?

Would this work, too ?
If yes - could you give us an example ?

Greetings from Germany

Tobias

Hey Chris (@cdthomer)

A little tip from my side here … maybe a little confusing first - but it could safe you a lot of time in debugging when using macros with this approach :thinking:.

It comes in very handy to always use %ExecutingThisMacro% for getting the Macro‘s Name & %ExecutingThisMacroUUID% for the UUID… - especially if any Macro is used as SubMacro or Subroutine from many other Macros and the conditional Logic will change based on the callers.

I‘ve converted all my Macros to use these two tokens instead of the other form of them and it makes it so much easier …

Edit:
Use the other form (without „This“) only when a Macro is used as a SubMacro or Subroutine.

Have a nice day

Greetings from Germany

Tobias

Thanks Tobias, that’s my standard approach as well. You know what they say about great minds thinking alike and all that. :wink::sweat_smile:

Good to know … thanks for mentioning that. And thanks :pray: appreciate that. :wink::sweat_smile:

Greetings from Germany

Tobias

I'm afraid I don't understand what you are asking. Could you expand on what you are trying to do?

Hey Peter (@peternlewis)

Sorry for my confusing reply … don’t know why I wrote it this way … what I want to know is if it is also possible when I integrate the Set Variable to Text Action as xml into the AppleScript ? Will this work, too ?

This is absolutely a need to know about information for me and could also help others here as well - especially if they want to reduce the amount of actions as well as like I need this info for - reducing Macro Count and also making them compatible to more than one version of KM.

Greetings from Germany

Tobias