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

[Help] Need help with oddness when submitting content from TrackerJacker via sendChat.

1599793316

Edited 1599794977
Chuz
Pro
Sheet Author
API Scripter
Compendium Curator
Hi all, I'm new to roll20 API stuff and a relative novice to js but not completely inexperienced with it.&nbsp; So here is my situation... I wanted to hack into TrackerJacker to make it support custom Token Markers, the first thing I noticed was that it hard codes the token names from the default tokens in.&nbsp;&nbsp; I was able to find the correct values to add the new custom tokens (only a few to start testing with). After some fumbling around, I have them showing up in the Available Markers dialogue !tj -edit_status change %% ... I have noticed that custom token markers have a name and a tag, roll20 seems to use the tag which is a unique identifier in the form of `name::####` When I use this name in the statusMarkers array things show up as one would expect however the hrefs are gone from the images in the output.&nbsp;&nbsp; After many log() calls and slow tracing of the code it seems that everything looks correct up until where TrackerJacker returns the content (I assume back to roll20) to the sendChat() function. This is an exerpt of how the content looks just before it's sent out .... &lt;div style="font-weight: bold; background-color: #FFF; border: 2px solid #000; box-shadow: rgba(0,0,0,0.4) 3px 3px; border-radius: 0.5em; margin-left: 2px; margin-right: 2px; padding-top: 5px; padding-bottom: 5px;"&gt;&lt;div style="text-align: center;&nbsp; border-bottom: 2px solid black;"&gt;&lt;span style="font-weight: bold; font-size: 125%"&gt;Available Markers&lt;/span&gt;&lt;/div&gt; &lt;div style="padding-left: 1px; padding-right: 1px; overflow: hidden;"&gt;&lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123890/TkC_M8_6X-UHy8euEymakQ/thumb.png?1425804412" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123890/TkC_M8_6X-UHy8euEymakQ/thumb.png?1425804412</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker red %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123890/TkC_M8_6X-UHy8euEymakQ/thumb.png?1425804412&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123890/TkC_M8_6X-UHy8euEymakQ/thumb.png?1425804412"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123884/pV7HJJVqORAhrOftpmVHUw/thumb.png?1425804373" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123884/pV7HJJVqORAhrOftpmVHUw/thumb.png?1425804373</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker blue %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123884/pV7HJJVqORAhrOftpmVHUw/thumb.png?1425804373&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123884/pV7HJJVqORAhrOftpmVHUw/thumb.png?1425804373"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123885/sbim5jTRF3XsuSs01ycKrg/thumb.png?1425804385" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123885/sbim5jTRF3XsuSs01ycKrg/thumb.png?1425804385</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker green %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123885/sbim5jTRF3XsuSs01ycKrg/thumb.png?1425804385&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123885/sbim5jTRF3XsuSs01ycKrg/thumb.png?1425804385"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123886/q0axCUI6vBsvDGOwFbsBXw/thumb.png?1425804393" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123886/q0axCUI6vBsvDGOwFbsBXw/thumb.png?1425804393</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker brown %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123886/q0axCUI6vBsvDGOwFbsBXw/thumb.png?1425804393&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123886/q0axCUI6vBsvDGOwFbsBXw/thumb.png?1425804393"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123889/xEOFbIKegEaFgN0vLnzG0g/thumb.png?1425804406" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123889/xEOFbIKegEaFgN0vLnzG0g/thumb.png?1425804406</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker purple %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123889/xEOFbIKegEaFgN0vLnzG0g/thumb.png?1425804406&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123889/xEOFbIKegEaFgN0vLnzG0g/thumb.png?1425804406"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123887/iyJDiq2Ngwuh6Si3-FLztQ/thumb.png?1425804400" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123887/iyJDiq2Ngwuh6Si3-FLztQ/thumb.png?1425804400</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker pink %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123887/iyJDiq2Ngwuh6Si3-FLztQ/thumb.png?1425804400&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123887/iyJDiq2Ngwuh6Si3-FLztQ/thumb.png?1425804400"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8123892/oL21nVVRUpDjGLaHXftstQ/thumb.png?1425804422" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123892/oL21nVVRUpDjGLaHXftstQ/thumb.png?1425804422</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker yellow %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8123892/oL21nVVRUpDjGLaHXftstQ/thumb.png?1425804422&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8123892/oL21nVVRUpDjGLaHXftstQ/thumb.png?1425804422"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/8093499/ca_OFvFT0w_MtJKY6c83Ew/thumb.png?1425688175" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8093499/ca_OFvFT0w_MtJKY6c83Ew/thumb.png?1425688175</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker dead %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/8093499/ca_OFvFT0w_MtJKY6c83Ew/thumb.png?1425688175&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/8093499/ca_OFvFT0w_MtJKY6c83Ew/thumb.png?1425688175"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker blinded::2779958 %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779959/aABGZno5HCNuH-ySLPH3VA/icon.png?1599750471" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779959/aABGZno5HCNuH-ySLPH3VA/icon.png?1599750471</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker absorbelements::2779959 %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779959/aABGZno5HCNuH-ySLPH3VA/icon.png?1599750471&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779959/aABGZno5HCNuH-ySLPH3VA/icon.png?1599750471"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779960/8nQaGrIU40-DF9iFfxbVOQ/icon.png?1599750473" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779960/8nQaGrIU40-DF9iFfxbVOQ/icon.png?1599750473</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker acid::2779960 %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779960/8nQaGrIU40-DF9iFfxbVOQ/icon.png?1599750473&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779960/8nQaGrIU40-DF9iFfxbVOQ/icon.png?1599750473"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779961/72UWes9zIMsrRPntgItYBA/icon.png?1599750474" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779961/72UWes9zIMsrRPntgItYBA/icon.png?1599750474</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker awareness-darkvision::2779961 %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779961/72UWes9zIMsrRPntgItYBA/icon.png?1599750474&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779961/72UWes9zIMsrRPntgItYBA/icon.png?1599750474"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779962/wRXVJuNiun7VWUvGP2RRhQ/icon.png?1599750476" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779962/wRXVJuNiun7VWUvGP2RRhQ/icon.png?1599750476</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker bardsong %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779962/wRXVJuNiun7VWUvGP2RRhQ/icon.png?1599750476&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779962/wRXVJuNiun7VWUvGP2RRhQ/icon.png?1599750476"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779964/M6r5shaNCnj8SsLAfDXKCA/icon.png?1599750479" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779964/M6r5shaNCnj8SsLAfDXKCA/icon.png?1599750479</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker bleeding %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779964/M6r5shaNCnj8SsLAfDXKCA/icon.png?1599750479&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779964/M6r5shaNCnj8SsLAfDXKCA/icon.png?1599750479"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;a style="font-size: 0px; background: url(<a href="https://s3.amazonaws.com/files.d20.io/images/2779965/bI1Y5_WGPecNFDyfOniPDA/icon.png?1599750481" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779965/bI1Y5_WGPecNFDyfOniPDA/icon.png?1599750481</a>) center center no-repeat; width: 21px; height: 21px" href="!tj -marker blessed %% test"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779965/bI1Y5_WGPecNFDyfOniPDA/icon.png?1599750481&quot;&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779965/bI1Y5_WGPecNFDyfOniPDA/icon.png?1599750481"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/div</a>&gt; &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div style="border-top: 2px solid black; border-bottom: 2px solid black;"&gt;&lt;span style="font-weight: bold; font-size: 125%"&gt;Taken Markers&lt;/span&gt;&lt;/div&gt; &lt;div style="padding-left: 1px; padding-right: 1px; overflow: hidden;"&gt;&lt;div style="float: left; padding: 1px 1px 1px 1px; width: 25px; height: 25px;"&gt;&lt;span class="showtip tipsy" title="test" style="width: 21px; height: 21px"&gt;&lt;img style="text-align: center;" src="<a href="https://s3.amazonaws.com/files.d20.io" rel="nofollow">https://s3.amazonaws.com/files.d20.io</a> images/2779963/qWXgDzjLo7Z956vLCvLQ-w/icon.png?1599750478"&gt;&lt;/img&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; You'll notice here everything has an href in it's &lt;a&gt; element, however when inspecting the element as it is output to the browser all of the token markers using the name::#### format lose their hrefs.&nbsp;&nbsp; I'm assuming it's the double colons :: that is causing the problem but I've tried replacing them with entity encoding and even dereferencing to no avail. Am I missing something obvious or is there a way to make roll20 NOT require the unique identifier and use just the names as it does for it's default tokens? Also one more question, do I need to use or include something special to use Campaign(), specifically Campaign().get("token_markers") When I tried to use that to build the tokenMarkers dynamically I get an error TypeError: Cannot read property 'get' of undefined Sorry for the wall of text, Chuz
1599795260

Edited 1599795372
timmaugh
Pro
API Scripter
You're probably running into the same problem I was running into a while back, where the Roll20 parser sees the ':' and thinks you are trying to pass a URL, so it parses it out. You can try encoding those (with a replace() operation) and replacing them with... &amp;#58; Or, if necessary, double-encoding them... &amp;amp;#58; if that doesn't work, you can try some custom encoding where you replace them on the outbound side with a unicode character unlikely to be otherwise used, then prepare trackerjacker to catch that input and decode them back to colons.
1599796090

Edited 1599796245
Chuz
Pro
Sheet Author
API Scripter
Compendium Curator
Thanks for the reply!&nbsp; I had not thought of double encoding, that prevents roll20 from eating the href however it then makes the href broken and non-functioning.&nbsp;&nbsp; I'm starting to think this is actually a bug related to how roll20 treats custom token markers vs how it treats the built ins but I'm too new to the system to be confident in that. Here is the output after converting :: to &amp;amp;#58;&amp;amp;#58; &lt;a style="font-size: 0px ; background: url(&amp;quot;<a href="https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469&amp;quot" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469&amp;quot</a>;) center center no-repeat ; width: 21px ; height: 21px" href="!tj -marker blinded&amp;amp;#58;&amp;amp;#58;2779958 %% blind"&gt;&lt;img style="text-align: center" src="<a href="https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469&quot;&gt;&lt;/a" rel="nofollow">https://s3.amazonaws.com/files.d20.io/images/2779958/6J52OirwFlsN9_2aZnC4pA/icon.png?1599750469"&gt;&lt;/a</a>&gt; Maybe I'll try replacing :: with something else that isn't a special character and as you suggest try to re-replace it inside TrackerJacker everywhere marker token names are used.&nbsp;&nbsp; I just wish there was a better solution that fixed the issue with roll20 mistakenly eating the :: in the first place since roll20 is forcing the :: on us. timmaugh said: You're probably running into the same problem I was running into a while back, where the Roll20 parser sees the ':' and thinks you are trying to pass a URL, so it parses it out. You can try encoding those (with a replace() operation) and replacing them with... &amp;#58; Or, if necessary, double-encoding them... &amp;amp;#58; if that doesn't work, you can try some custom encoding where you replace them on the outbound side with a unicode character unlikely to be otherwise used, then prepare trackerjacker to catch that input and decode them back to colons.
1599797191

Edited 1599797258
timmaugh
Pro
API Scripter
Try the custom replacement, then. If you reformat your href target on the way out, you can change TJ to handle the change on the way in. I don't know what the code looks like at the point that you are building your output, but let's say you have the api call of each line (the target of your href), in a variable named 'api'. It's in the middle of a map or reduce operation since you are obviously dealing with many at once. In that case, building the output would look like: api =api.replace(/:/g, '|colon|'); Then when TJ gets the message object, have it immediately search the content for that string or character (whatever you chose as the character replacement for ':'): msg.content = msg.content.replace(/\|colon\|/g, ':'); You won't have to replace it everywhere in TJ, then. Only if it receives it in the command line will it care, and it will replace it. Let it exist as ':' everywhere else and you should be good.
1599832009
Chuz
Pro
Sheet Author
API Scripter
Compendium Curator
That's exactly how I was foreseeing it, it's not the best solution but it's a solution that will work and that's what I needed. Thanks for the responses! Chuz timmaugh said: Try the custom replacement, then. If you reformat your href target on the way out, you can change TJ to handle the change on the way in. I don't know what the code looks like at the point that you are building your output, but let's say you have the api call of each line (the target of your href), in a variable named 'api'. It's in the middle of a map or reduce operation since you are obviously dealing with many at once. In that case, building the output would look like: api =api.replace(/:/g, '|colon|'); Then when TJ gets the message object, have it immediately search the content for that string or character (whatever you chose as the character replacement for ':'): msg.content = msg.content.replace(/\|colon\|/g, ':'); You won't have to replace it everywhere in TJ, then. Only if it receives it in the command line will it care, and it will replace it. Let it exist as ':' everywhere else and you should be good.
1599839497
Chuz
Pro
Sheet Author
API Scripter
Compendium Curator
This worked perfectly for that problem, thanks again for the help. Part two will be dynamically loading the token marker list instead of using the hardcoded ones.&nbsp; I think that deserves it's own thread. Chuz timmaugh said: Try the custom replacement, then. If you reformat your href target on the way out, you can change TJ to handle the change on the way in. I don't know what the code looks like at the point that you are building your output, but let's say you have the api call of each line (the target of your href), in a variable named 'api'. It's in the middle of a map or reduce operation since you are obviously dealing with many at once. In that case, building the output would look like: api =api.replace(/:/g, '|colon|'); Then when TJ gets the message object, have it immediately search the content for that string or character (whatever you chose as the character replacement for ':'): msg.content = msg.content.replace(/\|colon\|/g, ':'); You won't have to replace it everywhere in TJ, then. Only if it receives it in the command line will it care, and it will replace it. Let it exist as ':' everywhere else and you should be good.