在trilium博客中同步网易云音乐、豆瓣观影记录的方法

-
-
2024-04-17

前言

不少朋友注意到本站新增了一个「现在」页面,其中可以自动同步网易云、豆瓣等信息,有些朋友对这个功能有兴趣,于是此处分享一下实现方法。

准备工作

  • 安装并部署了Ankia博客主题
  • Ankia - Theme 更新到 v1.7 版本以上

在博客中新增一个页面

使用本博客系统新增一个界面十分简单,初次部署时你需要在「Ankia - Theme.ejs」下新建一个名为「now」的ejs类型笔记(该笔记不允许空白,你可以添加一段无关紧要的代码,比如添加一个<hr>标签),然后在「DIY 导航栏」笔记下方新建一个名为「现在」的文字笔记,并且在此笔记中添加以下属性:

#categoryName=现在 #shareAlias=now

本页面与其他页面一致,同样支持显示评论等功能,如果需要增加额外功能,详见: Trilium博客主题:Ankia 使用指南

一个空白的网页就建立完成了,你所有在「现在」笔记中写下的内容都会同步至此页面,其内容是你可以自由 DIY 的,尽情发挥创意吧!

注:此页面必须填写一些内容,否则无法正常显示后文的豆瓣、网易云等信息

接下来将介绍一下如何同步豆瓣和网易云信息,在 Ankia - Theme 的 v1.7 版本中已经内置了相应的样式,你需要「now」笔记中按照以下格式添加一个板块,比如添加豆瓣观影记录板块:

<p><span class="text-huge">📚最近看的电影和书籍</span></p>
<div class="fLinkContainer">
  <% const filmRecord = JSON.parse(note.getLabelValue('filmRecord').replace(/<\/?pre>/g, '').replace(/[\n\s]/g, "")); 
     for (let key in filmRecord) {%>
  <a class="filmBox">
    <img src="<%= filmRecord[key]['img'] %>" alt="<%= filmRecord[key]['title'] %>">
    <div class="filmTitle"><%= filmRecord[key]['type'] %><br><%= filmRecord[key]['title'] %></div>
    <div class="watchDate"><%= filmRecord[key]['pubDate'] %></div>
  </a>
  <% }%>
</div>

其中,filmRecord 是你在下文中自定义的属性名

现在在浏览器中打开此页面应该会报错,不用着急,我们还没有配置完成。

同步豆瓣观影信息

获取个人 RSS 地址

在网页版的豆瓣中打开个人主页,找到这个位置:

点击它,将地址栏中的地址记下来。

解析 RSS 并储存到笔记

在任何你想存放此笔记的地方建立一个 JS backend 类型的笔记,粘贴以下代码,并修改代码中的 RSSURL  和 NOTEID 为实际的值:

const RSSURL = "rss"; //你的个人豆瓣 RSS 地址
const NOTEID = ""; //上一步中建立的「现在」笔记的 NoteID
async function fetchRSSData(url) {
    const response = await api.axios.get(url);
    const data = response.data;
    const jsonData = await api.xml2js.parseStringPromise(data);
    const keyWord = ["看过","在看","想看","读过","在读","想读"];
    const items = {};
    let num = 0;

    function splitStringByKeywords(str) {
        const regex = new RegExp(keyWord.join('|'));
        const match = str.match(regex);
        if (match) {
            const index = str.indexOf(match[0]);
            const prefix = str.substring(0, index + match[0].length);
            const suffix = str.substring(index + match[0].length);
            return [prefix, suffix];
        }
        return [str];
    }
    if (jsonData.rss && jsonData.rss.channel && jsonData.rss.channel[0].item) {
      for (const item of jsonData.rss.channel[0].item) {
        const date = api.dayjs(item.pubDate[0]);
        const formattedDate = date.locale('zh-cn').format('YYYY 年 MM 月 DD 日');
          
        const updatedText = splitStringByKeywords(item.title[0]);
        items[num] = {
            type : updatedText[0],
            title : `《${updatedText[1]}》`,
            link : item.link[0],
            img:item.description[0].match(/<img[^>]+src="([^">]+)"/)[1],
            pubDate : formattedDate
          };
          num+=1;
      }
    }

    return items;
}
fetchRSSData(RSSURL).then((items) => {
    const note = api.getNote(NOTEID);
    note.setLabel("filmRecord",JSON.stringify(items));
});

你可以立即运行一次试试,现在在浏览器中查看此界面应该能够看到效果了,如果你需要定时更新的话,请在刚刚创建的脚本笔记中设置 #run=hourly 属性实现每小时更新一次。

小提示:在添加了以上属性的基础上,你可以继续添加 #runAtHour=3 属性将更新时间变更为每天 3 点,或者添加 #runOnInstance=xxx 属性让其只在某个特定实例上运行。

同步网易云音乐

注:此方法目前还存在一定的不稳定性,比如需要定期更换 cookie,偶尔会获取失败等问题。

与上一步类似,我们需要先在「now」中添加一个用于显示的板块:

<p><span class="text-huge">🎶最近喜欢的音乐</span></p>
<div class="fLinkContainer">
  <% const musicRecord = JSON.parse(note.getLabelValue('musicRecord').replace(/<\/?pre>/g, '').replace(/[\n\s]/g, "")); 
     for (let key in musicRecord) {%>
  <a class="filmBox">
    <img src="<%= musicRecord[key]['imgUrl'] %>" alt="<%= musicRecord[key]['musicName'] %>">
    <div class="filmTitle"><%= musicRecord[key]['musicName'] %></div>
    <!-- 此处为播放按钮的样式,点击可自动播放音乐(只可以播放免费音源),如果需要此功能可以取消注释
    <svg class="playMusicButton" musicid="<%= musicRecord[key]['musicId'] %>" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-play-circle">
      <circle cx="12" cy="12" r="10"></circle>
      <polygon points="10 8 16 12 10 16 10 8"></polygon>
    </svg>
    -->
    <div class="watchDate"><%= musicRecord[key]['artists'] %></div>
  </a>
  <% }%>
</div>

然后通过脚本定时获取数据:

const NOTEID = "" //上一步中建立的「现在」笔记的 NoteID
const USERID = "" //网易云的歌单 ID
const cookie = "" //网易云登录 cookie

async function fetchMusicDetails() {
    const headers = {
        'Cookie': cookie
    }
    var musicDetails = {}
    let num = 0
    let success = false
    let retryCount = 0

    while (!success && retryCount < 4) {
        try {
            const response = await api.axios.get(`https://music.163.com/api/playlist/detail?id=${USERID}`, {
                headers: headers
            })
            const tracks = response.data.result.tracks.slice(0, 10)
            tracks.forEach((track) => {
                musicDetails[num] = {
                    musicName: track.name,
                    musicId: track.id,
                    artists: track.artists.map(artist => artist.name).join('/'),
                    imgUrl: track.album.picUrl
                }
                num += 1
            })
            success = true
        } catch (error) {
            retryCount++
        }
    }
    return musicDetails
}

fetchMusicDetails().then((musicDetails) => {
    const note = api.getNote(NOTEID);
    note.setLabel("musicRecord",JSON.stringify(musicDetails));
});

歌单 ID 的获取方式很简单,登录网页版网易云后,点击「我喜欢的音乐」页面,地址栏中的数字就是歌单 ID;cookie 则需要打开 F12,在请求的 Cookie 中找到包含MUSIC_U 字段的数据。

结语

总结以下,添加一个板块需要进行以下几个步骤:

  • 在「now」笔记中添加一个模板;
  • 获取需要的信息源;
  • 将获取的数据保存在「现在」笔记的属性中;

通过以上步骤,你可以同步任何你喜欢的信息源。


关联阅读:

“您的支持是我持续分享的动力”

微信收款码
微信
支付宝收款码
支付宝

目录