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,
+};