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 .
×
Create a free account

Various APIs Integration

Hello community I face an issue of integration between APIs that i solve for the moment by modifying existing APIs, which obviously is not the desired integration Let explain my issue: I have an API that manages various actions for my campaign There is a for instance a locksmith test to try to open a door Now, when success, i would like to call : !knock --key|toggle, using knock API, so i have nothing to manage by hand Now comes the issue. I send the command on the chat {"content":"!knock --key|toggle","playerid":"API","type":"api","who":"MON"} and sending through the player: {"content":"!knock --key|toggle", "playerid":"-JFfBFlUsSVTtKun72Bj","selected":[{"_id":"-MVs0a1xcdAsxcj1ucWl","_type":"graphic"}] ,"type":"api","who":"JPL (GM)"} To work, knock uses msg.playerid and msg.selected This is the same for aura, updateBar, tj, ... lot of scripts in fact !! So for the moment, i download the script and install it by myself, modify the code to handle --selected and --playerId new parameters, and in the code, if msg.playerId is undefined i replace by the parameter i pass Obviously it works, but as soon as new release of API is done, i'm out of date, need to redo the integration etc etc Is there a way to integrate correctly two APIs together rather than passing through the chat ? Or is there a way to populate the missing parameters ? This is a big lack for the moment and it's really a pain to automate and ease GM life :)
1615913965
timmaugh
Pro
API Scripter
The idea of getting scripts to play nicely together (metascripting) is something I've spent a lot of time on recently. I think you want to look into SelectManager as a way to preserve the very properties you are trying to pass on to the downstream message. As you know, generating a call to !knock from the api would typically strip the selected property, and it would change the who and playerid properties... SelectManager can give any/all of those back. That gets you around having to modify DoorKnocker (I think that's the doorknocker handle...?)... the downstream script. If you want to try to get around modifying the upstream call, you can use another metascript, APILogic . APILogic gives *other* scripts logic structures, inline math, variable muling, term definitions, and plugin evaluation. So you could run the !knock command only if the lock pick check passes: !{& if [[1d20 + @{selected|lockpick}]] > 10 }knock --key|toggle{& else}@{selected|character_name} failed to pick the lock, and feels a bone-deep shame.{&simple}{&end} That's an out-of-thin-air example of what the check might look like, just to show the example. If the check passes, it will run the !knock call. If it doesn't, it will output a message to the chat about the shame-inducing perils of lock-picking. In this case, SelectManager doesn't even need to be involved, because you're handling everything in one user-generated call (it's all the same message object, handed from one script to the next), so your selected, who, and playerid properties are all there. If you need to run a script to generate your testable condition, that would be slightly more complicated, but still doable. For now, I'll stop here to see if this gets you where you want to go. If you have a specific question about a more complex usage, post back!
Thanls, i'll give a try tonight and keep ou informed
This is working as i expect. it rocks!!! Now time to integrate all together :) Thanks a lot
1615928434
timmaugh
Pro
API Scripter
Great! Glad to hear it! Can I ask which way you went? (Also, if you are utilizing APILogic, I should share that I am currently breaking out those component parts (math, muling, etc) into their own component part... they will all be a part of what I'm calling the "Meta-Toolbox" script set, but to avoid scope creep and to better facilitate further development on any of them individually, it makes more sense to have each be separate. Depending on time, hoping to have that out next week!)
I use select manager and let the script populate the values that was missing for next API. One case I find tonight that may be is not working, i need still to investigate 1. I do a lock skill, without targeting any token as !knock works on the nearest --> it's ok, i have the selected info in the message 2. I decide tonight to add also the brutal force, with an attack, we can also open a door like this :). I reuse my standard attack api that is asking for a target for this, and here, when the !knock is called, i have the playerId, who, but the selected is lost, which is almost true as the initial token that does the attack is not selected anymore because of the target selection For the moment i will solve by not selecting any target but your inputs are welcome !!
1615942973

Edited 1615943078
timmaugh
Pro
API Scripter
Hmm... I'll have to test, but you might get some mileage from deferring the @{target} resolution using APILogic. There are a lot of ways to do that, but the easiest is with an EVAL that goes nowhere. Let's say your "attack" command is: !attack --tgt|@{Target|token_id} --then|knock --key|toggle ...which is a from-whole-cloth attempt to represent an attack api that later calls knock. In order to defer that targeting call and let SelectManager still gather the selected property, you would need to change it to: !attack --tgt|@\{Target|token_id} --then|knock --key|toggle {& eval}null(){& /eval} That should defer the targeting resolution one cycle (APILogic runs in cycles until all of its constructs have been escaped and processed). One cycle is enough for SelectManager to gather the selected property and hang on to it for when that later call to !knock happens. You just need both SelectManager and APILogic installed, and probably in the order of SM before APIL. (The Meta-Toolbox will hopefully give you the ability to configure this on the fly so that part doesn't matter as much, but right now, it might.) EDIT : To be clear, the changes you need to notice are the backslash breaking up the Targeting call, as well as the EVAL block which will disappear from your line (and do nothing as long as you don't have a script that answers the !null handle!)
I'll give it a try !
Arg, i have the following error after installing api logic : TypeError: Cannot set property 'version' of undefined, which blocks the starting of scripts As always it is not clear where the pb is without adding logs but you may have faced this issue already so better to ask before i disable step by step all other scripts to see where a potential conflict cause the issue
1615985482
timmaugh
Pro
API Scripter
Yeah, that's a known issue with the version that made it into the one-click. Sorry. You'll have to get it from my repo . (I wasn't even aware that had made it to the one-click... but I remember that after I submitted it I found that error. My apologies)
Installed, still have a little issue Let me give you first a 1 min background on my settings Basically, I always find something that was not exactly how i want in a specific script (example : powercard miss real variable, ...), so i decide to manage my own api that does all the needs of the campaign, and calls the different existing api to not redevelop everything :) So your work is absolutely key for what i am trying to achieve :) So the player has habilities, and these abilities call my API that handles the different calls. In addition, i manage internal cache due to the problems that you solve :) so probably will be able to disable all the internal cache of my api So, a fight for instance, ability "fight" !mon --target|@{target|token_id} !mon --fight|step1 --typeoffight|?{....} --attitudeinfight|?{...    --> basically asking all "common" for fight then on my script, if additional info is needed (the player choose a firearm, so i need to know if he wants to shoot the 2 bullets of the riffles in one time, etc etc, specific after first choices), so i use api button to complete (i do this because in powercard, if you have multiple ?{...}, even in an if --> then, even if the then is not managed, it asks the inputs, so it's not good so next call will be like !mon --fight|step2 --2shoots|?{yes|no}, ... unitl i call the final ability !mon --fight|stepfinal to resolve the attack Then as i said, to not recode evryhting, i call aura script to show FX on character, i call jaber truntracker to add "effects", i call knock if the player attacks a door,  Now you have the context So the issue now My first macro is then !mon --target|@{target|token_id} !mon --fight|step1 --typeoffight|?{....} --attitudeinfight|?{... --> when second one is called, i have lost selected 1. I try to group my 2 lines in the macro: !mon --target|@\{target|token_id} --then|mon --fight|step1 --typeoffight|?{....} --attitudeinfight|?{... and the eval you mention --> in that case, the target on the roll20 gui is not asked at all, it asks me immediately the second input it gives me this error: "ERROR: Unable to find character target in chat command." "Error     at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:158:1), <anonymous>:637:11)     at String.replace (<anonymous>)     at Object.d20.textchat.doChatInput (eval at <anonymous> (/home/node/d20-api-server/api.js:158:1), <anonymous>:549:29)     at sendChat (/home/node/d20-api-server/api.js:1817:16)     at handleInput (apiscript.js:17082:9)     at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:154:1), <anonymous>:65:16)     at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:154:1), <anonymous>:70:8)     at /home/node/d20-api-server/api.js:1663:12     at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560     at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147)" and i see in logs : {"content":"","playerid":"-JFfBFlUsSVTtKun72Bj","selected":[{"_id":"-MVlDlIfDSbPSwzNEbpi","_type":"graphic"}],"type":"api","who":"JPL (GM)"} {"content":" !null ","playerid":"-JFfBFlUsSVTtKun72Bj","type":"api","who":"JPL (GM)","selected":[{"_id":"-MVlDlIfDSbPSwzNEbpi","_type":"graphic"}]} {"content":" !mon --target target|token_id  --then|mon --fight 84 ","playerid":"-JFfBFlUsSVTtKun72Bj ","type":"api", "who":"JPL (GM)" , "selected":[{"_id":"-MVlDlIfDSbPSwzNEbpi" ,"_type":"graphic"}],"logicgroups":{},"variables":{},"mules":[],"parsedinline":[]} the target tokenid is not right (but all 3 parameters are here) so i am doing something wrong with APILogic
1616007852
timmaugh
Pro
API Scripter
ok... so, yeah, that's why I said I'd have to test, too. I *thought* we'd be able to defer the targeting statement within the APIL cycle, but I have learned differently. Apparently all of those various commands in the one macro drive off the same chat event, which, if it contains an @{target} statement is going to drop the selected property. Since they are coming from a user-generated api call, SelectManager tries to track the selected property of the message (which is undefined). I will have to do more testing on it to see if there is something else to be done, but right now your best bet might be to split the first line off into its own macro. It will make for a 2 step process for now, but it will work. As a longer-term solution, I see a new syntax token for SelectManager... {& inject ... } ... which would turn targeting calls into selected tokens, so that you could effectively use both in the same message: {& inject @{target|To Selected 1|token_id} @{target|To Selected 2|token_id} } I will see if I can get that turned around and released tonight. (Also, you were probably using APILogic right just to have the slash and the EVAL token in the way I described... it was the above problem that was stopping you. However, the  --then  part of my example wasn't a part of the APILogic call, so that wouldn't have worked in your command line, anyway. That was just a part of the imagined structure of what you might be working with).
1616045789

Edited 1616045836
Victor B.
Pro
Sheet Author
API Scripter
Check out combat master code if you want to integrate multiple APIs together.  It requires a menu so users can config integration because APIs are all different.   And note that some APIs can't be integrated for various reasons.  
Thanks a lot. Yeah i will split the macro in 2 parts for now. It is crazy developper of roll20 don't thought of integration of APIs together at the conception of APIs ! You do a fantastic reverse engineering :)
I still need a little help very simple now sorry to bother The first macro is launched by the player itself (so i put only the target selection). You are right, selected property is lost So here i face 2 issues 1. Selected is lost, so selectmanager is not able to send the selected if the first macro is making the target So i do in fact a little different I do a first macro that does nothing, so sleectmanager have the time to catch the selected Then i call my normal macro --> I see the selected in the log of the sandbox So everything is perfect Except i am a noob :) I only call macros in my api through button, with the syntax             [GO!!!](!
#mymacro) What should be the syntax, i try the following syntax to send :  #mymacro !#mymacro                --> "content":"!#mymacro" !
#mymacro        --> "content":"!
#mymacro" (!
#mymacro) And i fail 4 times :(, not executing the macro So it is totally unrelated to select manager, i'm just too bad coder :)
1616085494
timmaugh
Pro
API Scripter
The setup I would suggest (for now) would be for two macros. I'll call them Step1 and Step2 just to keep them straight, but you can call them whatever you want to. The Step1 macro should have content like this: !mon --target|@{target|token_id} [Step 2](!
#Step2) The Step2 macro should have the rest of the commands that don't use targeting (but rely on the selected tokens: !mon --fight|step1 --typeoffight|?{....} --attitudeinfight|?{... When you run the Step1 macro, it should give you a chat button to run the second step. Splitting things this way should ensure you have the selected tokens available to you.
For info, this is working fine with this setup. Thanks a lot
1616648316

Edited 1616648406
Victor B.
Pro
Sheet Author
API Scripter
I'm sorry but all of these API developers should stop creating command driven APIs that force PRO users to becomes programmers.  Create menus that make use of your API easier.  Easier is better.  Ancient linux based commands or menu driven commands.  You can do both.  Provide commands AND provide a menu so a PRO user doesn't have to know YOUR syntax.  Nice thing is that users can hold mouses over the menus and find the commands for macros or whatever