Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×

Question about combining/nesting API Commands and "#macros "

Hello, My Apologies, I'm relatively new to advanced Roll20 stuff but I've been learning fast (obsessively) after a friend introduced me to Macros and API Commands Question 1: Is it possible to nest 2 layers of API Commands into one macro to output 3 separate templates? (part of a much larger project) basically what i'm setting up &{template:default}{{name=cat1}}{{line1= [cat2](! &{template:default}{{name=dog1}}{{line1= [dog2](! &{template:default}{{name=bird1}}{{line1= bird2}})}})}} When I convert the nested reserved characters I end up with &{template:default}{{name=cat1}}{{line1= [cat2](! &{template:default}{{name=dog1}}{{line1= [dog2](!
 &{template:default}{{name=bird1}}{{line1= bird2}})}})}} Currently I am able to generate 2 Separate Templates each with embedded API Command buttons, but if my 2nd API Command attempts to generate a 3rd Template it breaks the 2nd Template. If my 2nd API command outputs simple text it doesn't break &{template:default}{{name=cat1}}{{line1= [cat2](! &{template:default}{{name=dog1}}{{line1= [dog2](!
 bird)}})}} I'm not sure if it's simply not possible to do or I'm just writing it incorrectly. Question 2: I've been trying to make custom macros for some attacks replacing values in the template with "#Macros " so that I don't want to have to edit the whole macro every time I level up or change weapons. When I use the "#Macros " in a normal macro it works, but if the "#Macros " are nested they don't work and it breaks the macro Do i need to do anything special when nesting them like? or is it simply not possible? Example: &{template:atk} {{charname= #ch1 }} {{rname=[ #wp1 ](!  macro)}} {{mod= #wp1mod }} {{r1=Atk Roll: [[1d20 #wp1atkmodr ]]}} {{attack=1}} {{range=80ft/320ft}} {{normal=1}}
1624101137
Oosh
Sheet Author
API Scripter
Question 1: What you're trying to do is possible, but a pretty solid path to madness if you want to go much further than 3 levels of nesting. This should achieve what you're trying to do: &{template:default} {{name=cat1}} {{line1=[button](`#&{template:default} {{name=dog1}} {{line1=[dog2](`#&{template:default} {{name=bird1}} {{line1=bird2}})}}) }} Each level of nesting requires more and more escaping. So you start with: &{template:default} {{name=cat1}} {{line1=[button]( So far, so simple. The nested template inside this requires escaping so the parser doesn't try to render it with the outer template: &{template:default} {{name=dog1}} {{line1=[dog2]( Here, the braces are escaped to stop the parser from trying to assemble anything until it's clicked. I use the abbreviation escapes, since I always get the numbers mixed up if I use those.... but it doesn't matter if you want to switch them back to &123; and so forth. The next layer of nesting, you basically take what you had above and escape it one more time. The leading ampersand is easy, that's just & The braces all need their escaped version - { - to have the leading ampersand escaped: { . This means on the first trip through the parser, it'll be converted to a 1st level escape: { => { . So we end up with this: &{template:default} {{name=bird1}} {{line1=bird2}} Then we get to the closing part: )}}) }} That first part is important - the ) . It's the closing parenthesis ) from the deepest layer. If you don't escape this, it's going to ruin the next button up the chain, as it'll close it early. We don't want that [button]() to close until it get's to the unescaped parenthesis, almost at the end. There's some more info in this thread. Question 2: Nesting macros like that doesn't work without escaping characters (just like nesting a template in a button), as the linked macro is inserted into the calling code before it's run. So any characters in your linked macro which will break the outer, calling macro will.... break that macro. Using chat menus is the easiest way to avoid this issue. Otherwise, you essentially need to write two copies of each macro - one to use directly, and another escaped version for nesting. If it's a once-off, just copy the contents of the linked macro into the one you're calling it from, and manually do all the escaping required.
1624112337

Edited 1624112459
I have stared at the first layer of the abyss and found there is no handrail..  Tyvm for the information.. so the growth/processing of the script is not linear as I originally thought.. where it waits until the next button is pressed before it begin decode the next layer.. At every level of depth that the script goes through and stops at, it process everything on that level including the nested levels contained, each time stripping away of one layer of escaping.  If i only escape the layers once, all that encoding is stripped away after going down just 1 level of depth at which point anything nested beyond that point is no longer escaped and gets all processed as one layer of code..   @_@; So to keep the nested layers safe I need to increase the complexity of escaping so that as it re-encodes it the layers make sense Macroception
1624114728
timmaugh
Roll20 Production Team
API Scripter
I wanted to draw a distinction that what you're referencing isn't what we would call "API commands". An API message will begin with an exclamation point and bypass the visible chat interface. API commands are a Pro perk, but you don't have to be a Pro to have access to them -- you just have to be playing in a game created by a Pro subscriber. Not trying to be pedantic; I'm actually making a point: if you have access to API commands (real API commands), you can use ZeroFrame (1.07 or later) and Fetch to bypass some of your HTML replacements... (SelectManager, too, if you have any selected tokens). Fetch gives you the ability to return macros (or sheet items, etc.) after the Roll20 parsers have already done their thing, so it won't matter if you bring in HTML characters that would typically require escaping, because they won't get in the way. To make sure you only get the right piece of data at the right time (you get Macro 2 when Macro 1 processes; you get Macro 3 when Macro 2 processes, etc.), ZeroFrame 1.0.7 gives you the ability to "late-escape" certain constructions using the {& escape ... } syntax token. That means you can do things like break up text formations that might otherwise be recognized and parsed by a meta-script (say, a Fetch construction), so that it isn't detected as Macro 1 is processing, but it shows up when Macro 2 is processing. .......#=+=(Macro1){&escape =+=}.... When that message gets "released", this portion will become #(Macro1) , a valid Fetch construction, which would exist into your button (in fact, all instances of =+= would be removed, throughout the line). Click the button generated as a part of that message and you initiate a Fetch return of the Macro1 syntax after the Roll20 parsers are out of the way. That's pretty deep in the meta if you don't actually have true API access, but it's out there. If you want a more thorough example, I can provide one.
timmaugh said: I wanted to draw a distinction that what you're referencing isn't what we would call "API commands". An API message will begin with an exclamation point and bypass the visible chat interface. API commands are a Pro perk, but you don't have to be a Pro to have access to them -- you just have to be playing in a game created by a Pro subscriber. Not trying to be pedantic; I'm actually making a point: if you have access to API commands (real API commands), you can use ZeroFrame (1.07 or later) and Fetch to bypass some of your HTML replacements... (SelectManager, too, if you have any selected tokens). Fetch gives you the ability to return macros (or sheet items, etc.) after the Roll20 parsers have already done their thing, so it won't matter if you bring in HTML characters that would typically require escaping, because they won't get in the way. To make sure you only get the right piece of data at the right time (you get Macro 2 when Macro 1 processes; you get Macro 3 when Macro 2 processes, etc.), ZeroFrame 1.0.7 gives you the ability to "late-escape" certain constructions using the {& escape ... } syntax token. That means you can do things like break up text formations that might otherwise be recognized and parsed by a meta-script (say, a Fetch construction), so that it isn't detected as Macro 1 is processing, but it shows up when Macro 2 is processing. .......#=+=(Macro1){&escape =+=}.... When that message gets "released", this portion will become #(Macro1) , a valid Fetch construction, which would exist into your button (in fact, all instances of =+= would be removed, throughout the line). Click the button generated as a part of that message and you initiate a Fetch return of the Macro1 syntax after the Roll20 parsers are out of the way. That's pretty deep in the meta if you don't actually have true API access, but it's out there. If you want a more thorough example, I can provide one. Sorry about that , I'm still not used to all the terminology and the word MACRO/SCRIPT is used so much in every aspect of all this that the one time i found an old post that specifically discussed the pink box links it called them API Commands and it just stuck. But Thank you tho so What I'm looking for is not actual API Commands that is a little higher level than I'll probably get into atm lol
1624127139
timmaugh
Roll20 Production Team
API Scripter
No worries! You're just likely to get different suggestions based on the terms you use, and some of it (like my suggestion) not what you're looking for!
Oosh said: Question 2: Nesting macros like that doesn't work without escaping characters (just like nesting a template in a button), as the linked macro is inserted into the calling code before it's run. So any characters in your linked macro which will break the outer, calling macro will.... break that macro. Using chat menus is the easiest way to avoid this issue. Otherwise, you essentially need to write two copies of each macro - one to use directly, and another escaped version for nesting. If it's a once-off, just copy the contents of the linked macro into the one you're calling it from, and manually do all the escaping required. I got the nested #macro  to work :D #ch1 -> Sparks &{template:default} {{name=cat1}} {{line1=[button](!     &{template:default} {{ name=#ch1 }} {{line1=[dog2](!
&{template:default} {{ name=#ch1 }} {{line1=bird2}})}}) }}