title author date CreateTime categories
dotnet 给MatterMost订阅RSS博客
lindexi
2019-10-19 08:12:36 +0800
2019-10-18 14:37:48 +0800
dotnet

其实MatterMost是有插件可以用来订阅RSS博客的,但是这个订阅插件需要一个个网址输入,而不是一次性输入很多个,于是我去就自己写了一个控制台程序做订阅

这个工具用到 Microsoft.SyndicationFeed.ReaderWriter 库,通过这个库可以用来解析RSS内容,所以开发的代码十分少

先通过 NuGet 安装或修改 csproj 代码

    <PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />

在使用RSS之前需要知道有两个通用的格式,一个是 RSSFeed 格式,一个是 AtomFeed 格式,这两个格式需要分别使用两个不同的方式读取

先用 HttpClient 获取 RSS 内容,定义参数 feedUri 表示需要获取的博客链接

            var xml = await httpClient.GetStringAsync(feedUri);

如我的博客是 https://blog.lindexi.com/ 我的订阅地址是 https://blog.lindexi.com/ 也就是在 feedUri 里面写的是订阅地址

读取到的内容是 xml 内容,通过下面方法判断当前博客使用的是哪个格式,分别返回不同的读取

        private XmlFeedReader GetXmlFeedReader(string xml, XmlReader xmlReader)
        {
            var xDocument = XDocument.Load(new StringReader(xml));
            var rootName = xDocument.Root.Name;
            if (rootName.Namespace.NamespaceName.Contains("Atom", StringComparison.OrdinalIgnoreCase))
            {
                return new AtomFeedReader(xmlReader);
            }

            if (rootName.LocalName.Contains("feed", StringComparison.OrdinalIgnoreCase))
            {
                return new AtomFeedReader(xmlReader);
            }

            if (rootName.ToString().Contains("rss", StringComparison.OrdinalIgnoreCase))
            {
                return new RssFeedReader(xmlReader);
            }

            return new AtomFeedReader(xmlReader);
        }

上面判断方法是用逗比代码写的,其实 AtomFeedReader 的判断不用那么复杂

判断完成之后就可以使用 feedReader.Read 方法不断读取,因为我只需要博客的内容,所以只获取内容

            using (var xmlReader = XmlReader.Create(new StringReader(xml)))
            {
                XmlFeedReader feedReader = GetXmlFeedReader(xml, xmlReader);
                Console.WriteLine("Read");
                while (await feedReader.Read())
                {
                    try
                    {
                        if (feedReader.ElementType == SyndicationElementType.Item)
                        {
                            ISyndicationItem item = await feedReader.ReadItem();
                            rssNewsItems.Add(item);
                        }
                    }
                    catch (Exception e)
                    {
                    }
                }
            }

在 ISyndicationItem 里面就包括了博客的标题,描述和发布时间,可以定义另一个类做封装

    public class Blog
    {
        public string Title { get; set; }

        public string Url { get; set; }

        public string Description { get; set; }

        public DateTime Time { set; get; }

        /// <inheritdoc />
        public override string ToString()
        {
            return $"{Title} {Time}\n{Url}";
        }
    }

这个做法很逗比

                var blogList = new List<Blog>();
                foreach (var syndicationItem in syndicationItems)
                {
                    var description =
                        syndicationItem.Description.Substring(0, Math.Min(200, syndicationItem.Description.Length));
                    var time = syndicationItem.Published;
                    var uri = syndicationItem.Links.FirstOrDefault()?.Uri;

                    if (time < syndicationItem.LastUpdated)
                    {
                        time = syndicationItem.LastUpdated;
                    }

                    blogList.Add(new Blog()
                    {
                        Title = syndicationItem.Title,
                        Description = description,
                        Time = time.DateTime,
                        Url = uri?.AbsoluteUri
                    });
                }

现在就拿到了 blogList 可以给 MatterMost 发送信息,发送的方法请看 dotnet core 集成到 Mattermost 聊天工具

做出来的效果是这样

dotnet给MatterMost订阅RSS博客_dotnet

我将这个项目代码放在 github 欢迎小伙伴下载,如果觉得好像在哪看过这个代码,那么证明你看过dotnet 代码调试方法 我在这个博客将这个代码作为例子演示如何调试

用这个方法做的RSS订阅没有 RSS Stalker 好用