<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mersiouiunes-sketch</title>
    <description>The latest articles on DEV Community by mersiouiunes-sketch (@mersiouiunessketch).</description>
    <link>https://dev.to/mersiouiunessketch</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3968257%2F1ae98ad7-52b8-4a92-aedb-ecf5763829cd.png</url>
      <title>DEV Community: mersiouiunes-sketch</title>
      <link>https://dev.to/mersiouiunessketch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mersiouiunessketch"/>
    <language>en</language>
    <item>
      <title>Building a real-time disposable email service (Haraka + Redis + WebSockets)</title>
      <dc:creator>mersiouiunes-sketch</dc:creator>
      <pubDate>Thu, 04 Jun 2026 18:19:57 +0000</pubDate>
      <link>https://dev.to/mersiouiunessketch/building-a-real-time-disposable-email-service-haraka-redis-websockets-4m7a</link>
      <guid>https://dev.to/mersiouiunessketch/building-a-real-time-disposable-email-service-haraka-redis-websockets-4m7a</guid>
      <description>&lt;p&gt;Most "temp mail" sites share one annoyance: you sign up for something, switch to the throwaway inbox, and then mash refresh waiting for the verification email. I wanted to build one where messages just &lt;em&gt;appear&lt;/em&gt; the&lt;br&gt;
  instant they arrive — and where developers could drive the whole thing from code for automated testing.&lt;/p&gt;

&lt;p&gt;This is a write-up of how &lt;a href="https://mailboxtemp.com" rel="noopener noreferrer"&gt;MailboxTemp&lt;/a&gt; works under the hood: a disposable email service with a real-time inbox and a small open API. No framework magic, just Node, an SMTP server, a queue, and &lt;br&gt;
  WebSockets.&lt;/p&gt;

&lt;p&gt;## The problem&lt;/p&gt;

&lt;p&gt;A disposable email service has to do something most web apps never touch: &lt;strong&gt;receive real SMTP mail from the public internet&lt;/strong&gt;, parse it safely, and get it onto a user's screen fast. That breaks into four jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Accept inbound mail on port 25 (and reject anything not addressed to a live inbox)&lt;/li&gt;
&lt;li&gt;Parse the message — including extracting one-time codes&lt;/li&gt;
&lt;li&gt;Store it briefly, then auto-delete it&lt;/li&gt;
&lt;li&gt;Push it to the open browser tab in real time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;## The architecture&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Internet (SMTP :25)
        │
     Haraka  ──►  Redis queue  ──►  Worker  ──►  Postgres
        │                              │
     (reject unknown                  └──► WebSocket ──► Browser
      recipients early)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;### 1. Receiving mail with Haraka&lt;/p&gt;

&lt;p&gt;&lt;a href="https://haraka.github.io/" rel="noopener noreferrer"&gt;Haraka&lt;/a&gt; is a fast SMTP server written in Node, which made it a natural fit. A small plugin does two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hook_rcpt&lt;/code&gt;&lt;/strong&gt; — when a sender provides a recipient, we check Redis for a live inbox key (&lt;code&gt;inbox:&amp;lt;address&amp;gt;&lt;/code&gt;). If it doesn't exist, we reject at RCPT time with a &lt;code&gt;550&lt;/code&gt;. This is important: you reject &lt;em&gt;before&lt;/em&gt; accepting 
the message body, so you never waste bandwidth on mail for inboxes that don't exist, and you can't be used as an open relay.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hook_queue&lt;/code&gt;&lt;/strong&gt; — for accepted mail, push the raw message onto a Redis list and return &lt;code&gt;OK&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hook_rcpt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`inbox:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DENY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mailbox not found or expired&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping the "does this inbox exist?" check in Redis (not Postgres) matters — it's on the hot path for every recipient of every connection, including the flood of spam every port-25 server receives.&lt;/p&gt;

&lt;p&gt;### 2. The queue + worker&lt;/p&gt;

&lt;p&gt;Haraka's only job is to accept and enqueue. A separate worker process does the slow work — parsing, OTP extraction, storage, broadcasting — so the SMTP path stays fast and a parsing error can never block mail acceptance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;brpop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email:queue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// blocking pop&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;job&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;processEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parsing uses &lt;a href="https://nodemailer.com/extras/mailparser/" rel="noopener noreferrer"&gt;mailparser&lt;/a&gt;. One-time codes are extracted with a set of heuristics over the text and subject (the classic "your code is 123456" patterns), so the UI can surface&lt;br&gt;
  the code without the user opening the email.&lt;/p&gt;

&lt;p&gt;### 3. The security bit everyone gets wrong: rendering untrusted HTML email&lt;/p&gt;

&lt;p&gt;This is the part I want to flag, because it's where a lot of webmail-style projects quietly introduce an XSS hole. &lt;strong&gt;HTML email is attacker-controlled input.&lt;/strong&gt; If you drop it into the DOM, you've handed every sender&lt;br&gt;
  script execution on your origin.&lt;/p&gt;

&lt;p&gt;Two layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sanitize server-side&lt;/strong&gt; with DOMPurify before storing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render inside a fully sandboxed iframe&lt;/strong&gt; — &lt;code&gt;sandbox=""&lt;/code&gt; with no &lt;code&gt;allow-scripts&lt;/code&gt;, no &lt;code&gt;allow-same-origin&lt;/code&gt; — using &lt;code&gt;srcdoc&lt;/code&gt;. Even if something slipped past sanitization, it executes in a powerless, origin-less sandbox.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyMarkup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bodyHtml&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;iframe sandbox="" srcdoc="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;escapeForAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyHtml&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&amp;lt;/iframe&amp;gt;`&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div class="text"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyText&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Belt and suspenders. Never trust one layer for untrusted markup.&lt;/p&gt;

&lt;p&gt;### 4. Real-time delivery with WebSockets&lt;/p&gt;

&lt;p&gt;When the worker stores a message, it broadcasts to anyone subscribed to that inbox over a WebSocket. The browser tab subscribed to &lt;code&gt;inbox:&amp;lt;address&amp;gt;&lt;/code&gt; gets the new message pushed and renders it immediately — no polling, no&lt;br&gt;
  refresh. There's a polling fallback for when the socket drops, but the happy path is instant.&lt;/p&gt;

&lt;p&gt;### 5. Auto-expiry&lt;/p&gt;

&lt;p&gt;Every inbox has a TTL. A scheduled job purges expired inboxes, their messages, and any stored attachments. Crucially it deletes the &lt;strong&gt;attachment blobs from object storage before&lt;/strong&gt; the DB rows cascade away — otherwise you&lt;br&gt;
  orphan files forever. (That ordering bug is easy to write and annoying to notice.)&lt;/p&gt;

&lt;p&gt;## The developer angle: an API for email testing&lt;/p&gt;

&lt;p&gt;Here's the part I think is genuinely useful beyond "throwaway signups." If your app sends email — welcome messages, verification codes, password resets — testing those flows usually means a human checking a shared&lt;br&gt;
  mailbox. That's slow, flaky, and impossible to parallelize.&lt;/p&gt;

&lt;p&gt;With a disposable inbox per test, runs are isolated and self-cleaning. So I published a tiny zero-dependency client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  npm &lt;span class="nb"&gt;install &lt;/span&gt;mailboxtemp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MailboxTemp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mailboxtemp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MailboxTemp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signup sends a verification code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createInbox&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                 &lt;span class="c1"&gt;// your code under test&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForOtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;timeoutMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\d{6}&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;waitForOtp&lt;/code&gt; just polls the inbox until an email with a detected code arrives, then returns the code. No shared mailbox, no manual checking, no cross-test collisions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/mailboxtemp" rel="noopener noreferrer"&gt;mailboxtemp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🛠 source: &lt;a href="https://github.com/mersiouiunes-sketch/mailboxtemp-node" rel="noopener noreferrer"&gt;github.com/mersiouiunes-sketch/mailboxtemp-node&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;### A side effect: detecting disposable domains&lt;/p&gt;

&lt;p&gt;Building this meant keeping a list of disposable domains around, which is also the exact thing the &lt;em&gt;other&lt;/em&gt; side wants — people running signups who'd rather &lt;em&gt;not&lt;/em&gt; accept throwaway inboxes. So I put together a small free&lt;br&gt;
  &lt;a href="https://mailboxtemp.com/tools/disposable-email-domain-checker/" rel="noopener noreferrer"&gt;disposable email domain checker&lt;/a&gt; that matches an address (or a whole pasted list) against the public-domain &lt;code&gt;disposable-email-domains&lt;/code&gt; list — entirely&lt;br&gt;
  client-side, nothing uploaded. It's the mirror image of the service: one hands out throwaway inboxes, the other flags them.&lt;/p&gt;

&lt;p&gt;## Honest limitations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's &lt;strong&gt;receive-only&lt;/strong&gt; — inboxes accept mail but can't send (this also keeps the service from being abused for spam).&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;won't bypass phone verification&lt;/strong&gt; — that's a different signal entirely.&lt;/li&gt;
&lt;li&gt;Brand-new domains occasionally get blocked by big sites, which is why there's a &lt;strong&gt;pool of domains&lt;/strong&gt; to rotate through.&lt;/li&gt;
&lt;li&gt;It's not anonymity in the network sense — it hides your email address, not your IP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;## Takeaways&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reject unknown recipients &lt;strong&gt;at RCPT time&lt;/strong&gt;, from a fast store (Redis), not after accepting the body.&lt;/li&gt;
&lt;li&gt;Keep SMTP acceptance and message processing in &lt;strong&gt;separate processes&lt;/strong&gt; so parsing can't block mail.&lt;/li&gt;
&lt;li&gt;Treat HTML email as hostile: &lt;strong&gt;sanitize + fully sandboxed iframe&lt;/strong&gt;, both layers.&lt;/li&gt;
&lt;li&gt;Delete object-storage blobs &lt;strong&gt;before&lt;/strong&gt; the DB rows that reference them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to poke at it, the live service is at &lt;a href="https://mailboxtemp.com" rel="noopener noreferrer"&gt;mailboxtemp.com&lt;/a&gt;, and there's a deeper developer writeup on &lt;a href="https://mailboxtemp.com/blog/disposable-email-for-developers/" rel="noopener noreferrer"&gt;using disposable email for automated &lt;br&gt;
  testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy to answer questions about the SMTP/queue side in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
