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

[Script] Supernotes

1585006657

Edited 1633904678
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
This was expanded from a short script by the Aaron when he created his gmnotes script. I added a lot of formatting and options. And then I had the Aaron check my work. Any errors however, are on my head. This script pulls the contents from a token's GM Notes field. If the token represents a character, you can optionally pull in the Bio or GM notes from the character. It can also return graphics and tooltip info. The user can decide whether to whisper the notes to the GM or broadcast them to all players. There is an option to add a footer to notes whispered to the GM. This footer creates a chat button to give the option of sending the notes on to the players. Finally, you can direct the note either to chat, or to a named handout. Images, API Command Buttons, Links and most special characters should pass through without issue. Images written in the markdown form of [x](imageURL) should parse correctly in both chat and handouts. This script as written is optimized for the D&D 5th Edition by Roll20 sheet, but can be adapted for most common sheets using the Configuration command below. This is now available for One-Click install, but if you want to install manually,  CODE IS HERE Commands: !gmnote whispers the note to the GM !pcnote sends the note to all players Parameters --token  Pulls notes from the selected token's gm notes field. This is optional. If it is missing, the script assumes --token. This option does not require the token to have an associated character. --charnote  Pulls notes from the gm notes field of the character assigned to a token. --bio  Pulls notes from the bio field of the character assigned to a token. --avatar  Pulls image from the avatar field of the character assigned to a token. --image Pulls first image from the bio field of the character assigned to a token, if any exists. Otherwise returns notice that no artwork is available --images Pulls all images from the bio field of the character assigned to a token, if any exist. Otherwise returns notice that no artwork is available --image[number] Pulls indexed image from the bio field of the character assigned to a token, if any exist. --image1 will pull the first image, --image2 the second and so on. Otherwise returns first image if available. If no images are available, returns notice that no artwork is available --tooltip  Pulls the tooltip from a selected token. This option does not require the token to have an associated character. --tokenimage  Pulls all the image from a selected token. This option does not require the token to have an associated character. --notitle This option suppresses the title in the chat output. It is useful for times when the GM might wish to show an image or note to the player without clueing them in wha the note is about. For instance, they may wish to reveal an image of a monster without revealing its name. This parameter can be added to any command. It is the only paramater for which this is true. Example !pcnote --image --notitle will pull the first of any images from the token's associate character sheet and send it to the chat without a title. --notitle may be added to the command in any order. --id  supply this with a token id, and the script will attempt to read the notes associated with a specific token, or the character associate with that token. There is no space between --id and the token id. Only one token id may be passed. --handout|Handout Name|  If this is present in the arguments, the note will be sent to a handout instead of chat. This can allow a note to remain usable without scrolling through the chat. It can also be used as a sort of floating palette. Notes in handouts can be updated. Running the macro again will regenerate the note. The string in between pipes will be used as the name of the note handout. If no handout by that name exists, Supernotes will create one and post a link in chat to open it. The title must be placed between two pipes. --handout|My Handout| will work. --handout|My Handout will fail. A note handout automatically creates a horizontal rule at the top of the handout. Anything typed manually above that rule will be persistent. Supernotes will not overwrite this portion. You can use this area to create Journal Command Buttons to generate new notes or to give some context to the existing note. All updates are live. --help Displays help. --config Returns a configuration dialog box that allows you to set which sheet's roll template to use, and to toggle the 'Send to Players' footer. Examples: !pcnote --bio will send the contents of the selected characters bio to the chat for all players to see. !gmnote --charnote will whisper the character's GMnotes to the GM This script will work well with the following Stupid Tricks (and many more): Invisible Tokens - The Notes Token (API version) Invisible Tokens - The Control Token Invisible Tokens - The Door Control Chat Menus Map Pins Configuration When first installed, Supernotes is configured for the default roll template. It will display a config dialog box at startup that will allow you to choose a roll template based on your character sheet of choice, as well as the option to toggle whether you want the 'Send to Players' footer button to appear. You will need to edit the code of the script if you wish to create a custom configuration, or contact keithcurtis on the Roll20 forum and request an addition. The pre-installed sheets are: Default Template, D&D 5th Edition by Roll20, 5e Shaped, Pathfinder by Roll20, Pathfinder Community, Pathfinder 2e by Roll20, Starfinder For reference, here are the roll templates used for each sheet: Default Template const template = 'default'; const title = 'name'; const theText = ' '; D&D 5th Edition by Roll20 const template = 'npcaction'; const title = 'rname'; const theText = 'description'; 5e Shaped const template = '5e-shaped'; const title = 'title' const theText = 'text_big' Pathfinder Community const template = 'pf_generic'; const title = 'name' const theText = 'description' Pathfinder Official by Roll20 const template = 'npc'; const title = 'name' const theText = 'descflag=1}} {{desc' Pathfinder 2e by Roll20 const template = 'rolls'; const title = 'header' const theText = 'notes_show=[[1]]}} {{notes' Starfinder by Roll20 const template = 'sf_generic'; const title = 'title' const theText = 'buttons0' 0.0.5 Expanded utility of "--image" parameter 0.0.6 Added auto-configuration for most popular sheets 0.0.7 Fixed for breaking of certain accented characters and diacriticals 0.0.8 Added --notitle parameter
Awesome!
1585023972
GiGs
Pro
Sheet Author
API Scripter
It's very nice to see this polished and posted. Having three different scripts for the various editing fucntions, not to mention different versions of each, floating around was 'interesting'.
1585026473
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Aaron is teasing me that I really, really need to learn to use the state object to set configuration. And I agree. It's just a matter of finding the time.
1585027450
GiGs
Pro
Sheet Author
API Scripter
That would be a good idea, then you can submit it to the one-click. Without the ability to edit config settings, it cant be used easily from there.
1585027759
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Exactly. There's a couple of things I'd still like to do with it when I have a day or so. One is doing the config in state. The other is to put the token/character art into chat using the same interface.
1585031651

Edited 1585031674
Unfortunatley it is still crashing the API if the text in the notes section contains letter like ä ö ü ß and the like. URIError: URI malformed URIError: URI malformed at decodeURIComponent (<anonymous>) at map.filter.filter.forEach.o (apiscript.js:5580:39) at Array.forEach (native) at apiscript.js:5576:22 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:1648: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) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) As I can't script, I still do hope that it can be fixed and that someone other than me, can make out any of this gibberish :) Rob
Can't wait to use this -- thanks, Keith! 
keithcurtis said: Exactly. There's a couple of things I'd still like to do with it when I have a day or so. One is doing the config in state. The other is to put the token/character art into chat using the same interface. I would dearly love to see this feature! Just playing around with the Supernotes script tonight and already love it. Thanks, Keith, as usual, for this latest bit of API magic.
Awesome work and idea. Is it possible to be able to send the notes to a single player (i.e. player controlling the token) in addition to all players? Or even to all players except the controlling player? (!pcnote --all; !pcnote --not; !pcnote --control)
1585492467
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
My coding is still in the primitive Unfrozen Caveman Coder stage. I can do it, but it's slow. I'll keep note of the suggestions and do my best to incorporate them when I have a full day to devote to the project.
No worries. It was just a thought to expand the usefulness of what you have put together, Keith. I don't know if it would come up where such tags would be needed; but if they are there, I'm sure someone would come up with a use. Sometimes the best way to learn is to dive in and see how much trouble you can get into. Sometimes you even get lucky.
Thank you, keithcurtis! This makes map pins so easy and intuitive.  The pins can be changed to "is drawing" to avoid the bubble menu popping up, and it still works, even on the map layer. I've also been labeling treasure chests and other loot, to remind me what I was thinking when I placed them.  By assigning something in the nameplate I know there is a token of importance there, but I don't allow players to see the nameplate. There will be so many uses! I like the idea of having the token image show up in the chat.  Ask The Aaron how he did that with the ColorEmote script.
1585575219
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I have the code for inserting the avatar image in chat. It's a matter of finding the time to nicely fit it into all the other existing code.
I am trying to combine Supernotes with Keith's non-API notes method to build useful dungeon keys for myself. Example, drop an invisible token onto the map, call it Room 1. Entrance Way or whatever. In each bar field (1/2/3 and their maxes), I'm putting various pieces of information not for the players, such as any secrets or traps in the room, tactical info for combat, etc., and sending those to chat as menu options with a token macro. I am then reserving the GM notes field of the room token for any read-aloud text and putting a "send to players" command in the same chat menu, and also adding a Rollmaster Audio command to play a specific track (for room-specific music). If anyone has a better way, please let me know!
This is amazing,  Is it possible to add the feature that was in one of the previous iterations that lets you just pull content from a certain line? i tried adding (taken from this forum post              let match=msg.content.match(/^!gmnote-(.*)$/),                 regex;             if(match && match[1]){                 regex = new RegExp(`^${match[1]}`,'i');             }                                              _.chain(msg.selected)                 .map( s => getObj('graphic',s._id))                 .reject(_.isUndefined)                 .reject((o)=>o.get('gmnotes').length===0)                 .each( o => {                     if(regex){                         let lines=_.filter(decodeURIComponent(o.get('gmnotes')).split(/(?:[\n\r]+|<br\/?>)/),(l)=>regex.test(l)).join('\r');                         sendChat(o.get('name'),lines);                     } else {                         sendChat(o.get('name'),decodeURIComponent(o.get('gmnotes')));                     } but honestly I have no clue what I am doing and it didnt work.
1589562368
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I'll look at it tonight or this weekend, and then likely call to The Aaron for help. ;)
1589583019

Edited 1589583251
You know, the reason I want this feature is to be able to store multiple types of text in the notes: A description of the room that outputs as a /desc, my notes on the room. And some notes depending on how high an investigation or perception roll yield.  But I am realizing I can probably just use Chat Macro buttons to output all that, I just need to put the text within the buttons in the gmnotes! It probably would look nicer too and have more options! Edit, ok maybe not. Is there a way to send text to chat through a Marco Menu button? Without having it call and attribute. ei: [Button](text to send to chat)
1589589733

Edited 1589590846
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
This script is adapted from a snippet that the Aaron wrote for me. It basically says "put whatever is after this command into a roll template" There are two commands: !sendtext whispers to GM !sendpc sends to open chat So [Room 1](!sendtext This is an empty room) would be an example roll button. It works within the context of Supernotes (i.e. you can use it in the gm notes of a token.) Sendtext on('ready',()=>{   on('chat:message', (msg) => {     if('api' === msg.type && /^!send(text|pc)\s+/i.test(msg.content)){        let whom = '/w gm ';         if (msg.content.split(/\s/)[0] === '!sendpc') {             whom = '';         }         sendChat(msg.who, whom + `&{template:npcaction} {{description=${         msg.content           .replace(/^!send(text|pc)\s+/i,'')           .replace(/(\{\{([\s\S]*)\}\})/g," $2 ")           .replace(/<br[/]?>/ig,'')       } }}`);     }   }); });
I love you guys
I would LOVE the ability to pull content from a given line or paragraph break of a note. That way, I pull up all my notes for a room just by using Supernotes for, say, the GM field, and then choose to reveal bits of it to players as we go. Right now, I do something like this: I have GM only notes in the token's notes field, and then smaller information chunked in the bar / bar value fields on the token (one bar to play room-specific music, one bar for player read-aloud text, etc.), but the downside is that I can't see all info stored on the token at a single glance. I have to bring up the Chat menu for the token.
Hi Keith. Does the Sendtext snippet allow formatting (bold, italic, etc.) of the content that goes into the roll template? 
1590676706
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
In my experience, yes, using markdown code: !sendtext This is **Bold.** This is *Italic.*
keithcurtis said: In my experience, yes, using markdown code: !sendtext This is **Bold.** This is *Italic.* Thank you, Keith! I'll try that. The combination of Supernotes and Sendtext has allowed me to put all content for my dungeon keys into the token notes field. Much appreciated. Edit: One more question. Would it be possible to apply the !sendpc command to an image? That is, have a Chat menu button with descriptive text for the image (button name would be Blue Dragon or whatever), and then being able to send the associated image to Chat so all players can view it?
1590702666
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I haven't tested it. I use this macro instead: NPC Directory and Slideshow
keithcurtis said: I haven't tested it. I use this macro instead: NPC Directory and Slideshow Hmm. That does seem like a better way to do images. I hadn't looked at that macro in a while, but I'll revisit it. Thanks!
keithcurtis said: In my experience, yes, using markdown code: !sendtext This is **Bold.** This is *Italic.* I should have been more clear! :) I meant inside the parentheses when the command is part of a chat button. I tried it and it doesn't work. Is there a standard way to encode markdown within ( ) that I'm missing?
Maybe using the HTML entities for the asterisks would work? [Button](!sendtext This is **Bold.** This is *Italic.*)
1590738186
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
That seems to do it.
Thank you both. I tried it, and it works when you're sending the button to chat manually. The issue seems to be when I try to call that same !sendtext chat button using the !gmnote --token command from Supernotes. Then it doesn't work.
1590755962
GiGs
Pro
Sheet Author
API Scripter
That'll be because each time the text gets accessed, the html entities get processed and so vanish. So you odnt need html entities when sending to chat. You need one layer for Persephone's suggestion, because there's an extra processing step. It stops working when using !gmnote because there's another layer of processing.  The best way to handle this would be to have some marker that roll20 doesnt process, but that sendtext processes, which removes the markers and turns the text between them the format you want. That's trickier, because you need different markers for each formatting type you want. You also have to find markers that dont conflict with roll20 markdown/dice syntax, nor with any of the scripts it might get sent through.
1590762092
The Aaron
Roll20 Production Team
API Scripter
Try: [Button](!sendtext This is <b>Bold.</b> This is <i>Italic</i>) Since it gets parsed through sendChat(), html should work in this context...
1590762790
GiGs
Pro
Sheet Author
API Scripter
That's the kind of marker I was looking for, lol!
1590764218
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
The Aaron said: Try: [Button](!sendtext This is <b>Bold.</b> This is <i>Italic</i>) Since it gets parsed through sendChat(), html should work in this context... I feel like you've probably told me this before...
The Aaron said: Try: [Button](!sendtext This is <b>Bold.</b> This is <i>Italic</i>) Since it gets parsed through sendChat(), html should work in this context... This one didn't work either way, manually or when called by Supernotes, unfortunately!
1590768496
The Aaron
Roll20 Production Team
API Scripter
Bummer!
1590771972
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Yeah, I just went through about a dozen variations, including some with entity replacement, quote marks and other stuff. I think in a button like that, it's just going to pass text.
keithcurtis said: Yeah, I just went through about a dozen variations, including some with entity replacement, quote marks and other stuff. I think in a button like that, it's just going to pass text. LOL, I was doing the same thing. Curly braces, quote marks, etc. Nothing worked. Oh well.
1590774011

Edited 1590777071
GiGs
Pro
Sheet Author
API Scripter
Here's a quick and dirty tweak to add bold and italic formats. Instead of this [Button](!sendtext This is <b>Bold.</b> This is <i>Italic</i>) do this [Button](!sendtext This is BBBold.BB This is IIItalicII) Basically wherever you want Bold, put BB (bold text here) BB around it, like wise use II (some text) II for italics. The script will replace them with the roll20 markdown. There's is a very slim chance it can match the wrong messages - but its very unlikely to have BB in a message twice, likewise II (thats why I used capitals). Heres the scriptlet: on('ready',()=>{ on('chat:message', (msg) => { if('api' === msg.type && /^!send(text|pc)\s+/i.test(msg.content)){ let whom = '/w gm '; if (msg.content.split(/\s/)[0] === '!sendpc') { whom = ''; } let message = whom + `&{template:default} {{description=${ msg.content .replace(/^!send(text|pc)\s+/i,'') .replace(/(\{\{([\s\S]*)\}\})/g," $2 ") .replace(/<br[/]?>/ig,'') } }}`; const checks = { bolditalic: {what: /B{2}I{2}.*?B{2}I{2}/g, before: /BBII/g, after: '***'}, bold: {what: /B{2}.*?B{2}/g, before: /BB/g, after: '**'}, italic: {what: /I{2}.*?I{2}/g, before: /II/g, after: '*'}, }; Object.keys(checks).forEach(check => { if(checks[check].what.test(message)) message = message.replace(checks[check].before,checks[check].after); }); sendChat(msg.who, message); } }); }); Edited (again)  with a version that makes it easy to add other markdown types later.
1590776689
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I'm envisioning a Tron-style gangster with a gun, pointed at the incoming message. "OK, send the text like you were told to do and no one gets hurt."
1590777133

Edited 1590777173
GiGs
Pro
Sheet Author
API Scripter
hehe, yes. I had errors in the regex earlier, just corrected them. You can also do BoldItalic with BBII some text BBII (notice the order must be the same each time).
Thank you, Gigs! It works! I just had to mod your scriptlet to use the npcaction template (as keith did in the original), but otherwise, many thanks! 
1590779242

Edited 1590779257
GiGs
Pro
Sheet Author
API Scripter
Oh yes, I forget to change the template back. I was using the default template so i could test it.
1591468775

Edited 1591837252
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Minor update to Supernotes. I have added a new parameter: --avatar  Pulls image from the avatar field of the character assigned to a token. In most cases from the compendium, the avatar is the same as the token. Large character art is usually posted within the bio field, which this script already reports. However, this is not the case with most PCs, and certainly need not be the case with any homebrew NPCs. Here is an example:
Oh my god, Keith, this is an amazing new feature! Thank you.
1591837543
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Another update. I have added a the following parameter: --image  Pulls first image from the bio field of the character assigned to a token, if any exists. Otherwise returns notice that no artwork is available In most cases from the compendium, the avatar is the same as the token. Large character art is usually posted within the bio field. The GM may wish to show this artwork to the players without necessarily showing them any of the text. This command pulls the first occurrence of an image from the bio field. If no image exists, it will return a statement to that effect.
Sweet! That is exactly my use case. I want to show that first bio image to my players when they first encounter a monster, without giving them the bio text (which they can obtain later via successful knowledge checks). The avatar image is great to have, but the full bio image, when available, is even better for immersion purposes. Thank you.
Updated to the new version and tried the bio image option. It works great! I finally have a good system for delivering monster knowledge, and it's thanks to this script.
1591917699
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Well, that just makes me happy. :)
1591980134
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I have added the ability for users to choose the configuration from inside the game, without needing to mess with code. Currently if you upgrade or do a fresh install, it will default to the default template, and ask you which sheet/template you would like to use in the future. The current choices are: Default Template, D&D 5th Edition by Roll20, 5e Shaped, Pathfinder by Roll20, Pathfinder Community ,Pathfinder 2e by Roll20, and Starfinder. If anyone has another use case, or would like to test out any of the solutions, please feel free to give me any feedback. I plan to submit this to the One Click repo this weekend.
1592342726
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
I have confirmed that Supernotes is now available for one-click install. The configurations for various sheets have been made user-selectable as detailed in the documentation on the API page and on the first post of this thread. If you would like me to add any roll templates/sheets, please contact me in this thread or by PM.