Execute random macro from macro group

I saw this post, but it's not exactly what I'm looking for:

I would like to create a macro group where I can create as many macros as I want and then I would have a main macro that would trigger random macros from that group.

My goal is to create kind of a "motivational" notification that will just show me short messages as notifications, but I want to be able to keep adding macros to the group without changing the main macro that triggers them.

1 Like

Rather than this, why not have a single macro that does a random notification?

You can select a random message from a list with a simple trick:

  • Set message to first message
  • Set Count to 2
  • If RANDOM(Count) < 1.0
    • Set message to next message
  • Set Count to calculation Count + 1
  • If RANDOM(Count) < 1.0
    • Set message to next message
  • Set Count to calculation Count + 1
  • If RANDOM(Count) < 1.0
    • Set message to next message
  • Set Count to calculation Count + 1
  • If RANDOM(Count) < 1.0
    • Set message to next message
  • Set Count to calculation Count + 1
  • If RANDOM(Count) < 1.0
    • Set message to next message

So you can just add a message by duplicating those last three actions and setting a new message.

1 Like

Thank you and this is also an option indeed! :slight_smile:
I'm relatively new to KM and I know the basic actions for basic stuff.
Looking at your steps I have no idea what actions I should be using? It seems a bit confusing to me...
Can you maybe share a screenshot or even a macro that I can then use?
Thank you!

I know some people here, maybe you included, want others to learn instead of giving them the finished macro, but I learn faster by looking at what is done and understanding it, instead of spending a whole lot of time first trying to understand what the other person is even trying to explain with just text.

Here's another approach, but still keeping it all in one Macro as @peternlewis has suggested.

The tricky part of what you are asking is that the total number of messages will change as you add more messages so to do the Random Math you need to count how many messages you have in total and that total will change as you add/delete more messages in the future. If you always had a fixed number of total message (say, 5) it would be a lot easier.

So, the approach below stores your messages in a local Variable and you can add/delete/edit your messages by just editing that Variable. Each message needs to be on its own line as it is the line count that gives us the total.

The Macro checks how many lines (messages) there are, uses that in the Random Calculation, which comes up with a line number and then displays that line from the Variable.

But there was still a bit of jumping through hoops as you will see by the number of Actions.

Firstly Keyboard Maestro cannot directly split a Variable by line breaks. We have to replace those line breaks with a symbol that Keyboard Maestro can then use to split the Variable up. I chose the star symbol as it is a symbol that probably won't be in the messages text.

We can get the total number of lines using %Variable%LOCAL__Messages[0]★%
(it is the zero in the square brackets that gives us the total - if "3" was in the square brackets that would give us line 3)

We can use that total to do the Math to choose a Random number from 1 to the total number of lines.

Now we can split that numbered line out from the Variable. But... the tricky part here is that the line number exists as a Variable and Keyboard Maestro cannot directly use a Variable within a Variable.

In other words, Keyboard Maestro could easily display the third message like this:

%Variable%LOCAL__Messages[3]★%

But it cannot directly do that if the "3" is also a Variable - %LOCAL__RandomLine%

%%Variable%%LOCAL__Messages[%Variable%LOCAL__RandomLine%]★%%

That text has to be filtered to process all those Variables...

Finally we can display the result of all that (our random line) by using:
%Variable%LOCAL__DisplayLine%

Bear in mind that this is a true random result - so you might easily get the same message displayed a few times in a row.

EXAMPLE Display Random Message - with expandable list.kmmacros (5.1 KB)

3 Likes

While the array method fast, it's hampered by not being able to use line breaks as delimiters. You've a lovely workaround for that, making for a very neat macro.

But speed really isn't an issue here, so we could use another approach -- let's go loopy!

Random Message Test.kmmacros (4.4 KB)

Summary

3 Likes

Ah, that's clever! That LINES token gets the total number of lines. And then the For Each gets at those individual lines without having to split the Variable.

I can think of a couple of ways of doing that:

  1. Use AppleScript to get the macros in a Group and trigger a randomly chosen one -- but that means having the KM Editor running all the time, which I know you don't like. You could do similar by parsing the KME plist instead, but that would be resource intensive which I know you also don't like!
  2. Your "main" macro has a variable containing pointers to the macros you want to pick from -- get pointer randomly, fire off target. But then you'll have to maintain that list of macros, which is probably more work that @peternlewis's and @Zabobon's approach of a single macro holding all your messages.

Do you want your messages to be pithy text one-liners (it sounds like it), or something a bit more involved?

Are you using the latest version of KM? Asking because the new "with modifiers" options in the "Pick from List" action could be a neat way of deleting messages without having to edit the macro itself, and it would be easy to add actions that let you add messages -- again, without having to edit the macro's variable directly.

The nerd in me prefers your method -- arrays, FTW! But my inner "lazy git" will go for easy mode every time...

Just throwing this out there -- do you want to curate your own quotes, or are you happy with random choices from someone else's collection? If the latter you could always hit someone's web API -- here's an example chosen at random from a Google search (how you process the results to get displayable text will depend on the service you use):

Motivational Quotes.kmmacros (1.7 KB)

Image

1 Like

There is a longstanding Unix command for returning random aphorisms called fortune. Apple doesn't included it in macOS, but you can install it through Homebrew:

brew install fortune

fortune comes with a large set of aphorism files, but you can create your own by making a file in which the quotes are separated by lines containing a single % character. You can update this file at any time.

The system is described in this post. The only caveat I have is that if you're using an Apple Silicon Mac, your fortunes file will have to be installed in

/opt/homebrew/share/games/fortunes

because Homebrew has changed where it installs things.

1 Like

Thank you all for your suggestions, especially @Zabobon and @Nige_S
I was able to make it work using your macros.
And yeah, I would never get there myself. Too complicated. But I am looking at them and see if I can at least learn something new, which I always do, so I appreciate your time and help!

@Nige_S My goal is to just show my own "motivational" sentences, because they are more of a "mindset" reminder, than really a motivational quote from someone else. So yeah, the macro you guys created is perfect. I only have to have in mind that the notification box is limited to 77 characters (including spaces).

This is not important and if it can't be done, not a big deal: is it possible to replace the title of the box from "Display Text" to something else? Again, if not, or if it takes too much time, please ignore this. It's more of an aesthetic thing than anything else. :wink:

1 Like

Yes. Instead of using Display text briefly at the end of the Macro use the Notification Action. Then you can set the title of the Notification to whatever you want.

EXAMPLE Display Random Message - with expandable list v2.00.kmmacros (5.2 KB)

Click to Show Image of Macro

1 Like

I'm surprised no one implemented this using a dictionary. Keys can be numbered or descriptive. Values can accommodate multiline entries. Adding new entries or removing unwanted ones are easy.

I'm late to this thread, however I'd take a completely different approach of using a file that contains your quotes/motivational messages. A script is used to get a random line from the file and then displays it in an auto dismissing prompt (currently set to 7 seconds).

Random Quotes From File.kmmacros (3.5 KB)

In the attached macro, it uses a file named quotes.txt that is contained in your Documents folder, so you'll need to create one before running this macro. I would have attached an example one, but it appears this forum doesn't allow text files?!

Here's an example of how it looks:

QuotePrompt