20 lines of code - RSS in SharePoint Online with your own RSS Proxy Azure Function
Hi Guys! So lets go back a couple of months.
I had implemented a RSS-feed as a SharePoint web part at one of my smaller clients, when I developed the webpart I was inspired by the awesome RSS-feed Oliver Wirkus had published and everything just worked.
I was surprised, that everything went that smoothly without any CORS issues and understood that some Proxy API needed to be the middle hand. I Did my homework (I thought) and found out that the Yahoo-API (Yahoo Query Language) implemented in Jquery plugin feedEK was the little helper. I Just made peace with that a big player like Yahoo probably will have that little sucker up for decades, I did not investigate enough it appeared :).
In the beginning of January the Yahoo Query Language was retired and this was actually a good reminder for me how important it is to investigate 3:rd party scripts. Avoid it if you can, use it if you must.
So I started to investigate and try to fix my RSS web part as fast as I could. The issue we have with fetching and reading data from RSS feeds from a website such as sites in SharePoint online is that we are not allowed to make requests that break the Same Origin Policy in browsers. This is a good policy to implement to avoid and prevent security issues when developing for the web, but it might also prevent legitimate interactions and requests with other services or trusted origins. To avoid any issues with CORS the requested resource needs to allow CORS.
So I started checking out what proxy services that was available on the market for RSS. An example of what I found was RSS2Json. A solid service it seems, it has different plans for subscription depending on estimated load and caching. I also found a lot of other proxy services that felt little shaky.
In my case I just thought about the dependency I was putting up with a 3:rd party service, once again. Will this service be up for long? Is this ok for my customer? etc...
I went to their Twitter and found this, so I just wanted to see if I could do something quick and neat myself.
So what if I could setup a proxy in my customers own Azure Environment with minimal cost and minimal effort that allowed CORS against my customers SharePoint Online environment?
I decided to kick of a new Azure Function project with JS in my VS Code. See my previous post about Visual Studio Code - Azure Function Extension
I started to browse NPM for a good rss parser package and found rss-parser.
To append package.json files to your bare project simply run
npm init
Then let NPM add the rss-parser module for you as a dependency
npm install rss-parser
I then implemented rss-parser in my function code
I deployed the Azure Function.
Took the functionality for a spin, The result, a small and handy working RSS-ATOM Proxy returning me beautiful JSON Objects.
Now we want the function to serve our RSS-webpart in our SharePoint environment, to make an example i try to use my source RSS feed in my simple rss web part, as you can see we still got the issue with missing CORS-rules:
I Enabled CORS in the Azure Function Settings - allowed origin: URL to my sharePoint environment
Then I could simply use my RSS Proxy service as I pleased and implement the feed without any CORS issues.
example URL: https://yourfunctionappurl.azurewebsites.net/api/functionName?feedUrl=https://feeds.bbci.co.uk/news/rss.xml
I think this is a pretty neat and simple implementation that may suit the paranoid people that don't want to involve 3:rd party services outside of MS.
Think about the following if you want to try to use your own Azure Function as a proxy:
- Use Client Side Cache in your webpart to mitigate high server load and keep request count low
- Use a warm-up function if using consumption plan to mitigate cold-starts of your function and deliver low response time for the end-user
- Setup Function Authorization and Authentication if needed
- Use application insight to track performance
You can find my simple implementation of the RSS proxy at my GitHub. No warranties :)