イントラネットのWebサイトをWin8ライブタイルに対応させる

WebサイトをWindows8のライブタイルに対応させるには、そのサイトがRSSを出力しているのであれば、

を使えばほんの数分で可能ですが、これで生成されるbrowserconfig.xmlのNotificationは

<notification>
<polling-uri src="http://notifications.buildmypinnedsite.com/?feed=http://www.example.jp/rss.xml&amp;id=0"/>
<polling-uri2 src="http://notifications.buildmypinnedsite.com/?feed=http://www.example.jp/rss.xml&amp;id=1"/>
...

という感じで、サイトのRSSフィードがnotifications.buildmypinnedsite.comからアクセス可能であることが前提です。

つまり、社内LAN等のイントラネットのサイトではこのサービスを使ってのライブタイル対応は不可能ですので、C#でnotifications.buildmypinnedsite.comで出力されるものと同等のスキーマ(XML)を出力するASP.NETのプログラムを書きました。

パラメータの書き方も合わせましたので、Build My Pinned Siteで生成したbrowserconfig.xmlのpolling-uriの部分だけをこのプログラムが動作するASP.NETのサイトに置換するだけで動作するはずです。

それにしても初めからライブタイルにおいてRSSが直接使えるようにすればよいものを、何でわざわざ別のスキーマを使うなどという「車輪の再発明」をするんですかねぇ…

[Notification.ashx]

using System.Linq;
using System.Web;
using System.Xml;
using System.ServiceModel.Syndication;

namespace Notification
{
    // Compatible with http://notifications.buildmypinnedsite.com/
    // Usage: http://~/Nofitication.ashx?feed=http://www.example.jp/rss.xml&amp;id=0
    public class Notification : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var querys = HttpUtility.ParseQueryString(HttpUtility.HtmlDecode(context.Request.Url.Query));
            string url = querys["feed"];
            int n;
            int.TryParse(querys["id"], out n);

            SyndicationFeed feed;
            using (var reader = XmlReader.Create(url))
            {
                feed = SyndicationFeed.Load(reader);
            }
            var items = feed.Items.ToArray();

            string response = "<tile><visual lang=\"en-US\" version=\"2\">"
                + "<binding template=\"TileSquare150x150Text04\" branding=\"logo\" fallback=\"TileSquareImage\">"
                + "<text id=\"1\">" + items[n].Title.Text + "</text></binding>"
            
                + "<binding template=\"TileWide310x150Text03\" branding=\"logo\" fallback=\"TileWideImage\">"
                + "<text id=\"1\">" + items[n].Title.Text + "</text></binding>"
            
                + "<binding template=\"TileSquare310x310TextList02\" branding=\"logo\" contentId=\""
                + items[0].Links.ElementAt(0).Uri.AbsoluteUri + "\">";
            for (int i = 0; i < 3; ++i)
            {
                response += "<text id=\"" + (i + 1) + "\">" + items[i].Title.Text + "</text>";
            }
            response += "</binding></visual></tile>";

            context.Response.ContentType = "application/xml";
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.Write(response);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}