diff --git a/docs/social-media.md b/docs/social-media.md
index 5edd71f27..ad0413024 100644
--- a/docs/social-media.md
+++ b/docs/social-media.md
@@ -296,6 +296,12 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性
| ---- | ---- | ---- | ----- | ----- |
| 最新 | 日榜 | 周榜 | 月榜 | 总榜 |
+## Mastodon
+
+### 实例公共时间线
+
+
+
## pixiv
### 用户收藏
diff --git a/lib/router.js b/lib/router.js
index df5f79e3a..fc1bd32cd 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -2023,4 +2023,7 @@ router.get('/bahamut/creation_index/:category?/:subcategory?/:type?', require('.
// CentBrowser
router.get('/centbrowser/history', require('./routes/centbrowser/history'));
+// Mastodon
+router.get('/mastodon/timeline/:site/:only_media?', require('./routes/mastodon/timeline'));
+
module.exports = router;
diff --git a/lib/routes/mastodon/timeline.js b/lib/routes/mastodon/timeline.js
new file mode 100644
index 000000000..f9fcc3c08
--- /dev/null
+++ b/lib/routes/mastodon/timeline.js
@@ -0,0 +1,49 @@
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const site = ctx.params.site;
+ const only_media = ctx.params.only_media ? 'true' : 'false';
+
+ const url = `http://${site}/api/v1/timelines/public?local=true&only_media=${only_media}`;
+
+ const response = await got.get(url);
+ const list = response.data;
+
+ const ProcessFeed = (data) =>
+ data.map((item) => {
+ const title = item.content
+ .replace(/|<\/span.*?>/gm, '')
+ .replace(/<(?:.|\n)*?>/gm, '\n')
+ .split('\n')
+ .filter((s) => s !== '')[0];
+
+ const media = item.media_attachments
+ .map((item) => {
+ switch (item.type) {
+ case 'gifv':
+ return `
`;
+ case 'video':
+ return `
`;
+ case 'image':
+ return `
`;
+ default:
+ return '';
+ }
+ })
+ .join('');
+
+ return {
+ title: title,
+ author: item.account.display_name,
+ description: item.content + media,
+ pubDate: new Date(item.created_at).toUTCString(),
+ link: item.uri,
+ };
+ });
+
+ ctx.state.data = {
+ title: `Local Public${ctx.params.only_media ? ' Media' : ''} Timeline on ${site}`,
+ link: `http://${site}`,
+ item: ProcessFeed(list),
+ };
+};