diff --git a/docs/en/programming.md b/docs/en/programming.md
index a8c203aee..b7294ef3f 100644
--- a/docs/en/programming.md
+++ b/docs/en/programming.md
@@ -113,6 +113,10 @@ For instance, the `/github/topics/framework/l=php&o=desc&s=stars` route will gen
+### Issues / Pull Requests comments
+
+
+
## GitLab
### Explore
diff --git a/docs/programming.md b/docs/programming.md
index 05d8a16c6..1175479d5 100644
--- a/docs/programming.md
+++ b/docs/programming.md
@@ -191,6 +191,10 @@ GitHub 官方也提供了一些 RSS:
+### Issues / Pull Requests 评论
+
+
+
## GitLab
### Explore
diff --git a/lib/v2/github/comments.js b/lib/v2/github/comments.js
new file mode 100644
index 000000000..7c79c59c8
--- /dev/null
+++ b/lib/v2/github/comments.js
@@ -0,0 +1,64 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+const typeDict = {
+ issues: {
+ typeRootUrl: '/issues',
+ },
+ pull: {
+ typeRootUrl: '/pulls',
+ },
+};
+
+module.exports = async (ctx) => {
+ const user = ctx.params.user;
+ const repo = ctx.params.repo;
+ const type = ctx.params.type ?? 'issues';
+ const number = ctx.params.number ?? '1';
+
+ const rootUrl = 'https://github.com';
+
+ const response = await got({
+ method: 'get',
+ url: `${rootUrl}/${user}/${repo}/${type}/${number}`,
+ header: {
+ Referer: `${rootUrl}/${user}/${repo}${typeDict[type].typeRootUrl}`,
+ },
+ });
+
+ const $ = cheerio.load(response.data);
+
+ const list = $('div.timeline-comment-group.js-minimizable-comment-group.js-targetable-element.TimelineItem-body.my-0')
+ .map((_, item) => {
+ item = $(item);
+ return {
+ title: item.find('div.edit-comment-hide').text().trim(),
+ description: art(path.join(__dirname, 'templates/comments-description.art'), {
+ desc: item.find('div.edit-comment-hide').html(),
+ }),
+ author: item.find('strong.css-truncate').text().trim(),
+ pubDate: parseDate(item.find('relative-time.no-wrap').attr('datetime')),
+ link: `${rootUrl}/${user}/${repo}/${type}/${number}` + item.find('a.Link--secondary.js-timestamp').attr('href'),
+ };
+ })
+ .get();
+
+ const items = await Promise.all(list && list.map((item) => ctx.cache.tryGet(item.link, () => item)));
+
+ ctx.state.data = {
+ title: $('span.author.flex-self-stretch').text().trim() + '/' + $('strong.mr-2.flex-self-stretch').text().trim() + `: ${type} #${number}`,
+ description: $('span.author.flex-self-stretch').text().trim() + '/' + $('strong.mr-2.flex-self-stretch').text().trim() + ': ' + $('h1.gh-header-title.mb-2.lh-condensed.f1.mr-0.flex-auto.break-word').text().trim(),
+ link: `${rootUrl}/${user}/${repo}/${type}/${number}`,
+ item: items,
+ };
+
+ ctx.state.json = {
+ title: $('span.author.flex-self-stretch').text().trim() + '/' + $('strong.mr-2.flex-self-stretch').text().trim() + `: ${type} #${number}`,
+ description: $('span.author.flex-self-stretch').text().trim() + '/' + $('strong.mr-2.flex-self-stretch').text().trim() + ': ' + $('h1.gh-header-title.mb-2.lh-condensed.f1.mr-0.flex-auto.break-word').text().trim(),
+ link: `${rootUrl}/${user}/${repo}/${type}/${number}`,
+ item: items,
+ };
+};
diff --git a/lib/v2/github/maintainer.js b/lib/v2/github/maintainer.js
new file mode 100644
index 000000000..318341638
--- /dev/null
+++ b/lib/v2/github/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/comments/:user/:repo/:type/:number': ['TonyRL'],
+};
diff --git a/lib/v2/github/radar.js b/lib/v2/github/radar.js
new file mode 100644
index 000000000..12d3ec05c
--- /dev/null
+++ b/lib/v2/github/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'github.com': {
+ _name: 'GitHub',
+ '.': [
+ {
+ title: 'Issues / Pull Requests 评论',
+ docs: 'https://docs.rsshub.app/programming.html#github',
+ source: ['/:user/:repo/:type/:number'],
+ target: '/github/comments/:user/:repo/:type/:number',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/github/router.js b/lib/v2/github/router.js
new file mode 100644
index 000000000..dad53ce62
--- /dev/null
+++ b/lib/v2/github/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/comments/:user/:repo/:type/:number', require('./comments'));
+};
diff --git a/lib/v2/github/templates/comments-description.art b/lib/v2/github/templates/comments-description.art
new file mode 100644
index 000000000..7755ee9f6
--- /dev/null
+++ b/lib/v2/github/templates/comments-description.art
@@ -0,0 +1 @@
+{{@ desc }}