diff --git a/docs/en/social-media.md b/docs/en/social-media.md index edc9f07622..fe0ecf5166 100644 --- a/docs/en/social-media.md +++ b/docs/en/social-media.md @@ -179,6 +179,12 @@ These feed do not include boosts (a.k.a. reblogs). RSSHub provides a feed for us +## Misskey + +### Featured Notes + + + ## piapro ### User latest works diff --git a/docs/social-media.md b/docs/social-media.md index cd7a3ea13e..34d44f97ac 100644 --- a/docs/social-media.md +++ b/docs/social-media.md @@ -527,6 +527,12 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性 +## Misskey + +### 精选笔记 + + + ## piapro ### 用户最新作品 diff --git a/lib/v2/misskey/featured-notes.js b/lib/v2/misskey/featured-notes.js new file mode 100644 index 0000000000..3830d43567 --- /dev/null +++ b/lib/v2/misskey/featured-notes.js @@ -0,0 +1,29 @@ +const got = require('@/utils/got'); +const utils = require('./utils'); +const config = require('@/config').value; + +module.exports = async (ctx) => { + const site = ctx.params.site; + if (!config.feature.allow_user_supply_unsafe_domain && !utils.allowSiteList.includes(site)) { + ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`); + } + + // docs on: https://misskey-hub.net/docs/api/endpoints/notes/featured.html + const url = `https://${site}/api/notes/featured`; + const response = await got({ + method: 'post', + url, + json: { + limit: 10, + offset: 0, + }, + }); + + const list = response.data; + + ctx.state.data = { + title: `Featured Notes on ${site}`, + link: `https://${site}/explore`, + item: utils.parseNotes(list, site), + }; +}; diff --git a/lib/v2/misskey/maintainer.js b/lib/v2/misskey/maintainer.js new file mode 100644 index 0000000000..6327c156af --- /dev/null +++ b/lib/v2/misskey/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/notes/featured/:site': ['Misaka13514'], +}; diff --git a/lib/v2/misskey/radar.js b/lib/v2/misskey/radar.js new file mode 100644 index 0000000000..cce1a2d8bf --- /dev/null +++ b/lib/v2/misskey/radar.js @@ -0,0 +1,35 @@ +module.exports = { + 'misskey.io': { + _name: 'Misskey', + '.': [ + { + title: 'Featured Notes', + docs: 'https://docs.rsshub.app/social-media.html#misskey', + source: ['/explore'], + target: '/misskey/notes/featured/misskey.io', + }, + ], + }, + 'madost.one': { + _name: 'Misskey', + '.': [ + { + title: 'Featured Notes', + docs: 'https://docs.rsshub.app/social-media.html#misskey', + source: ['/explore'], + target: '/misskey/notes/featured/madost.one', + }, + ], + }, + 'mk.nixnet.social': { + _name: 'Misskey', + '.': [ + { + title: 'Featured Notes', + docs: 'https://docs.rsshub.app/social-media.html#misskey', + source: ['/explore'], + target: '/misskey/notes/featured/mk.nixnet.social', + }, + ], + }, +}; diff --git a/lib/v2/misskey/router.js b/lib/v2/misskey/router.js new file mode 100644 index 0000000000..205a403a5c --- /dev/null +++ b/lib/v2/misskey/router.js @@ -0,0 +1,3 @@ +module.exports = function (router) { + router.get('/notes/featured/:site', require('./featured-notes')); +}; diff --git a/lib/v2/misskey/templates/note.art b/lib/v2/misskey/templates/note.art new file mode 100644 index 0000000000..34f553e560 --- /dev/null +++ b/lib/v2/misskey/templates/note.art @@ -0,0 +1,21 @@ +{{ text.replace(/\n/g, '
') }} + +{{ each files file }} +
+ {{ if file.type.includes('image') }} + + {{ else if file.type.includes('video') }} + + {{ else if file.type.includes('audio') }} + + {{ else }} + {{ file.name }} + {{ /if }} + {{ if file.comment }} +

{{ file.comment }}

+ {{ /if }} +{{ /each }} diff --git a/lib/v2/misskey/utils.js b/lib/v2/misskey/utils.js new file mode 100644 index 0000000000..4f64633485 --- /dev/null +++ b/lib/v2/misskey/utils.js @@ -0,0 +1,31 @@ +const { art } = require('@/utils/render'); +const { parseDate } = require('@/utils/parse-date'); +const path = require('path'); + +const allowSiteList = ['misskey.io', 'madost.one', 'mk.nixnet.social']; + +// docs on: https://misskey-hub.net/docs/api/entity/note.html +const parseNotes = (data, site) => + data.map((item) => { + const host = item.user.host === null ? site : item.user.host; + const author = `${item.user.name} (@${item.user.username}@${host})`; + const description = art(path.join(__dirname, 'templates/note.art'), { + text: item.text, + files: item.files, + }); + const title = `${author}: "${description}"`; + const link = `https://${host}/notes/${item.id}`; + const pubDate = parseDate(item.createdAt); + return { + title, + description, + pubDate, + link, + author, + }; + }); + +module.exports = { + parseNotes, + allowSiteList, +};