<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Little helper functions for E-mail notifications (RoomURLescape and GetReplayLink)]]></title><description><![CDATA[<p>For those who want to build your own room links in email notifications here are two useful functions:</p>
<pre><code>function GetReplayLink(roomName, tick = Game.time, msg = &quot;Replay&quot;){
    return &quot;&lt;a href='https://screeps.com/a/#!/history/&quot; +
           Game.shard.name + &quot;/&quot; + RoomURLescape(roomName) +
           &quot;?t=&quot;+ tick +&quot;'&gt;&quot; + msg +&quot;&lt;/a&gt;&quot;;
}

function RoomURLescape(roomName){
    let mapping = {N:&quot;%4E&quot;, S:&quot;%53&quot;, E:&quot;%45&quot;,W:&quot;%57&quot;};
    let out = &quot;&quot;;
    for (var i = 0; i &lt; roomName.length; i++) {
        let c = roomName[i];
        out += mapping[c] || c;
    }
    return out;
}
</code></pre>
<p>If the room names aren't escaped the supposed server side &quot;regex replace&quot; kills your custom HTML links.<br />
However please keep in mind that this function only works for URLs and isn't suitable for anything else.</p>
<p>hf <img
      src="http://screeps.com/forum/plugins/nodebb-plugin-emoji/emoji/android/1f609.png?v=a1k070tfs06"
      class="not-responsive emoji emoji-android emoji--wink"
      title=":wink:"
      alt="😉"
    /></p>
]]></description><link>http://screeps.com/forum/topic/3321/little-helper-functions-for-e-mail-notifications-roomurlescape-and-getreplaylink</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 09:11:41 GMT</lastBuildDate><atom:link href="http://screeps.com/forum/topic/3321.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 18 Aug 2024 15:38:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Little helper functions for E-mail notifications (RoomURLescape and GetReplayLink) on Sun, 18 Aug 2024 15:43:05 GMT]]></title><description><![CDATA[<p>For those who want to build your own room links in email notifications here are two useful functions:</p>
<pre><code>function GetReplayLink(roomName, tick = Game.time, msg = &quot;Replay&quot;){
    return &quot;&lt;a href='https://screeps.com/a/#!/history/&quot; +
           Game.shard.name + &quot;/&quot; + RoomURLescape(roomName) +
           &quot;?t=&quot;+ tick +&quot;'&gt;&quot; + msg +&quot;&lt;/a&gt;&quot;;
}

function RoomURLescape(roomName){
    let mapping = {N:&quot;%4E&quot;, S:&quot;%53&quot;, E:&quot;%45&quot;,W:&quot;%57&quot;};
    let out = &quot;&quot;;
    for (var i = 0; i &lt; roomName.length; i++) {
        let c = roomName[i];
        out += mapping[c] || c;
    }
    return out;
}
</code></pre>
<p>If the room names aren't escaped the supposed server side &quot;regex replace&quot; kills your custom HTML links.<br />
However please keep in mind that this function only works for URLs and isn't suitable for anything else.</p>
<p>hf <img
      src="http://screeps.com/forum/plugins/nodebb-plugin-emoji/emoji/android/1f609.png?v=a1k070tfs06"
      class="not-responsive emoji emoji-android emoji--wink"
      title=":wink:"
      alt="😉"
    /></p>
]]></description><link>http://screeps.com/forum/post/16823</link><guid isPermaLink="true">http://screeps.com/forum/post/16823</guid><dc:creator><![CDATA[MrFaul]]></dc:creator><pubDate>Sun, 18 Aug 2024 15:43:05 GMT</pubDate></item><item><title><![CDATA[Reply to Little helper functions for E-mail notifications (RoomURLescape and GetReplayLink) on Invalid Date]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="http://screeps.com/forum/uid/85">@mrfaul</a> It's really helpful! Thank you sooo much</p>
]]></description><link>http://screeps.com/forum/post/16913</link><guid isPermaLink="true">http://screeps.com/forum/post/16913</guid><dc:creator><![CDATA[Harabi]]></dc:creator><pubDate>Invalid Date</pubDate></item><item><title><![CDATA[Reply to Little helper functions for E-mail notifications (RoomURLescape and GetReplayLink) on Sat, 18 Jan 2025 11:46:33 GMT]]></title><description><![CDATA[<p>Ran into a wee issue when I tried to incorporate this into my rooms' general toString() which is then used in both logs &amp; notifications - the game's notifier ended up malforming my links. Ended up just doing the same URL escape logic for HTML entities which prevents the game's notifier from automatically turning room names into links:</p>
<pre><code class="language-typescript">// to-string.ts
function roomToString(this: Room): string {
  return `&lt;a href=&quot;${this.replayLink()}&quot; style=&quot;color:#9c05a6ff&quot;&gt;${this.htmlName}&lt;/a&gt;`;
}

// replay-link.ts
interface Ext {
  replayLink: typeof replayLink;

  /** Room name with HTML entities replacements to avoid it getting broken in notifications */
  get htmlName(): string;
}

declare global {
  interface Room extends Ext {
  }
}

Object.defineProperties(Room.prototype, {
  htmlName: lazyGetter('htmlName' satisfies keyof Room, function htmlName(this: Pick&lt;Room, 'name' | 'htmlName'&gt;): string {
    return escapeName(this.name, HTML_MAPPINGS);
  }),
  replayLink: confValue(replayLink),
} satisfies TypeDescriptorMap&lt;Ext&gt;);

function replayLink(this: Pick&lt;Room, 'name'&gt;, tick = Game.time): string {
  return `https://screeps.com/a/#!/history/${Game.shard.name}/${escapeName(this.name, URL_MAPPINGS)}?t=${tick}`;
}

const URL_MAPPINGS: Record&lt;string, string&gt; = {N: '%4E', S: '%53', E: '%45', W: '%57'};
const HTML_MAPPINGS: Record&lt;string, string&gt; = {N: '&amp;#78;', S: '&amp;#83;', E: '&amp;#69;', W: '&amp;#87;'};

function escapeName(roomName: string, mappings: Record&lt;string, string&gt;): string {
  let out = '';

  for (let i = 0, c: string; i &lt; roomName.length; i++) {
    c = roomName[i]!;
    out += mappings[c] || c;
  }

  return out;
}
</code></pre>
]]></description><link>http://screeps.com/forum/post/16914</link><guid isPermaLink="true">http://screeps.com/forum/post/16914</guid><dc:creator><![CDATA[Alorel]]></dc:creator><pubDate>Sat, 18 Jan 2025 11:46:33 GMT</pubDate></item></channel></rss>