Hey, Alex... apologies if this info aims below you, but just as a starting point: Roll20 listeners aren't like standard DOM listeners in the wild. In fact, in the sandbox we don't have access to the DOM at all. You're limited to the Roll20 events, most of which are add/change/delete of some object: on('add:character', (o,p) => { //... }); on('change:attribute', (o,p) => { //... }); The functions take arguments of the Roll20 event type as well as a call back. For these sort of events, you typically get 2 objects, the current object and the previous object. The current object is a Roll20 object (requiring the retrieval of most properties via get(), for example), where the previous object is a standard js object. Two other events that are quite often used are the 'ready' event, and the standard chat event: on('ready', () => { // ... }); on('chat:message', msg => { // ... }); The ready event makes sure that the sandbox is up and all objects have been initialized before you take actions in your code. A simple scriptlet might just be: on('ready', () => { on('chat:message', (msg) => { if (msg.type !== 'api' || !/^!scripthandle\b/.test(msg.content)) return; // take actions here... let args = msg.content.split(/\s+--/).slice(1); // ... }); }); Note: the above is generally a good way to organize the chat registration (in the 'ready' event)... it preserves the ability of metascripts to be useful. Since you don't have access to the sheet, you're in a bit of a pickle. Generally, you'd want to either have the button send a command to the Moditorium (the sandbox) that your script will pick up, or you want to catch what the button is already sending in order to take action on it. Since your button is sending a message to chat, you can't intercept it to change what is happening. The message sent by clicking the button will automatically hit the chat output, whether or not you take action based on detecting it. In that case, you might be better off coding up your own, more-complete script in order to handle all of the functionality of an attack, and skip using that particular button on the character sheet altogether. If you go this route, I would strongly suggest using a modern, revealing module pattern template floating around the forums. As for whether the attribute is on the character sheet or not, inspect the button to see what you can find. Send the command through chat, then use the up-arrow to see what it sent. If you still can't determine where the value is stored (I'm sure it will be an attribute) or what it is named, you can use the XRay script (part of InsertArg ) to examine the character sheet -- just because you don't see it on the sheet doesn't mean it's not there! The one caveat is that calc-fields don't show to the XRay script, but you can still use them. Another option would be, as practice, to set up a listener for when an attribute is changed and log the information. Click the button to trigger the attack, and see what you get out of your listener.