This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan
<p>We use Google Chat internally a lot to communicate across our team - it's kinda
like our slack; We also create a lot of content that is accessible via RSS
feeds, we even have a <a href="http://devwebfeed.appspot.com">team feed that you can all
view</a>. It wasn't until recently that I found out
that it was pretty easy to create a <a href="https://developers.google.com/hangouts/chat/how-tos/webhooks">simple post-only bot via
WebHooks</a> and that
gave me the idea, I can create a simple service that polls RSS feeds and then
sends them to our webhook that can post directly in to our team chat.</p>
<p>It was pretty simple in the end, and I've included all the code below. I used
Firebase functions - I suspect that this is just as easy on other
Function-as-a-service sites - and Superfeedr.
<a href="https://superfeedr.com/">Superfeedr</a> is a service that can listen to
Pubsubhubbub pings (now WebSub) and it will also poll RSS feeds that don't have
Pubsub set up. Then when it finds a feed it will ping a configured URL (in my
case my Cloud Function in Firebase) with an XML or JSON representation of the newly found
feed data - all you have to do is parse the data and do something with it.</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-javascript" data-lang="javascript"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">functions</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">'firebase-functions'</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">express</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">'express'</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">cors</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">'cors'</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">fetch</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">'node-fetch'</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">app</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">express</span>();
<span style="color:#75715e">// Automatically allow cross-origin requests
</span><span style="color:#75715e"></span><span style="color:#a6e22e">app</span>.<span style="color:#a6e22e">use</span>(<span style="color:#a6e22e">cors</span>({ <span style="color:#a6e22e">origin</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">true</span> }));
<span style="color:#a6e22e">app</span>.<span style="color:#a6e22e">post</span>(<span style="color:#e6db74">'/'</span>, (<span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">res</span>) => {
<span style="color:#66d9ef">const</span> { <span style="color:#a6e22e">webhook_url</span> } <span style="color:#f92672">=</span> <span style="color:#a6e22e">req</span>.<span style="color:#a6e22e">query</span>;
<span style="color:#66d9ef">const</span> { <span style="color:#a6e22e">body</span> } <span style="color:#f92672">=</span> <span style="color:#a6e22e">req</span>;
<span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">items</span> <span style="color:#f92672">===</span> <span style="color:#66d9ef">undefined</span> <span style="color:#f92672">||</span> <span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">items</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">===</span> <span style="color:#ae81ff">0</span>) {
<span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">send</span>(<span style="color:#e6db74">''</span>);
<span style="color:#66d9ef">return</span>;
}
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">item</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">items</span>[<span style="color:#ae81ff">0</span>];
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">actor</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">actor</span> <span style="color:#f92672">&&</span> <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">actor</span>.<span style="color:#a6e22e">displayName</span>) <span style="color:#f92672">?</span> <span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">actor</span>.<span style="color:#a6e22e">displayName</span> <span style="color:#f92672">:</span> <span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">title</span>;
<span style="color:#a6e22e">fetch</span>(<span style="color:#a6e22e">webhook_url</span>, {
<span style="color:#a6e22e">method</span><span style="color:#f92672">:</span> <span style="color:#e6db74">'POST'</span>,
<span style="color:#a6e22e">headers</span><span style="color:#f92672">:</span> {
<span style="color:#e6db74">"Content-Type"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"application/json; charset=utf-8"</span>,
},
<span style="color:#a6e22e">body</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">JSON</span>.<span style="color:#a6e22e">stringify</span>({
<span style="color:#e6db74">"text"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">`*</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">actor</span><span style="color:#e6db74">}</span><span style="color:#e6db74">* published <</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">permalinkUrl</span><span style="color:#e6db74">}</span><span style="color:#e6db74">|</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">item</span>.<span style="color:#a6e22e">title</span><span style="color:#e6db74">}</span><span style="color:#e6db74">>. Please consider <https://twitter.com/intent/tweet?url=</span><span style="color:#e6db74">${</span>encodeURIComponent(<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">items</span>[<span style="color:#ae81ff">0</span>].<span style="color:#a6e22e">permalinkUrl</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">&text=</span><span style="color:#e6db74">${</span>encodeURIComponent(<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">items</span>[<span style="color:#ae81ff">0</span>].<span style="color:#a6e22e">title</span>)<span style="color:#e6db74">}</span><span style="color:#e6db74">|Sharing it>.`</span>
})
}).<span style="color:#a6e22e">then</span>(() => {
<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">send</span>(<span style="color:#e6db74">'ok'</span>);
}).<span style="color:#66d9ef">catch</span>(() => {
<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">res</span>.<span style="color:#a6e22e">send</span>(<span style="color:#e6db74">'error'</span>)
});
})
<span style="color:#75715e">// Expose Express API as a single Cloud Function:
</span><span style="color:#75715e"></span><span style="color:#a6e22e">exports</span>.<span style="color:#a6e22e">publish</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">functions</span>.<span style="color:#a6e22e">https</span>.<span style="color:#a6e22e">onRequest</span>(<span style="color:#a6e22e">app</span>);
</code></pre></div><p><a href="https://github.com/PaulKinlan/superfeedr-to-chat">Read full post</a>.</p>
<p>I was surprised and delighted about how easy it was to set up.</p>
This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan