@@ -57,7 +57,7 @@ async function fetchAllDiscussions() {
5757 login
5858 }
5959 }
60- replies(first: 100 ) {
60+ replies(first: 20 ) {
6161 nodes {
6262 id
6363 url
@@ -80,31 +80,6 @@ async function fetchAllDiscussions() {
8080 login
8181 }
8282 }
83- replies(first: 100) {
84- nodes {
85- id
86- url
87- createdAt
88- author {
89- login
90- avatarUrl
91- url
92- }
93- bodyHTML
94- reactionGroups {
95- content
96- users {
97- totalCount
98- }
99- }
100- replyTo {
101- id
102- author {
103- login
104- }
105- }
106- }
107- }
10883 }
10984 }
11085 }
@@ -136,7 +111,101 @@ async function fetchAllDiscussions() {
136111 return data . data . repository . discussions . nodes
137112}
138113
139- // 递归函数来处理回复的嵌套结构
114+ // 分页获取更深层的回复
115+ async function fetchDeepReplies ( replyId , discussionId , discussionTitle , level = 3 ) {
116+ const response = await fetch ( 'https://api.github.com/graphql' , {
117+ method : 'POST' ,
118+ headers : {
119+ Authorization : `bearer ${ GITHUB_TOKEN } ` ,
120+ 'Content-Type' : 'application/json'
121+ } ,
122+ body : JSON . stringify ( {
123+ query : `
124+ query($replyId: ID!) {
125+ node(id: $replyId) {
126+ ... on DiscussionComment {
127+ replies(first: 20) {
128+ nodes {
129+ id
130+ url
131+ createdAt
132+ author {
133+ login
134+ avatarUrl
135+ url
136+ }
137+ bodyHTML
138+ reactionGroups {
139+ content
140+ users {
141+ totalCount
142+ }
143+ }
144+ replyTo {
145+ id
146+ author {
147+ login
148+ }
149+ }
150+ }
151+ }
152+ }
153+ }
154+ }
155+ ` ,
156+ variables : {
157+ replyId : replyId
158+ }
159+ } )
160+ } )
161+
162+ const data = await response . json ( )
163+
164+ if ( data . errors ) {
165+ console . error ( `Error fetching deep replies for ${ replyId } :` , data . errors )
166+ return [ ]
167+ }
168+
169+ if ( ! data . data ?. node ?. replies ?. nodes ) {
170+ return [ ]
171+ }
172+
173+ const replies = data . data . node . replies . nodes . map ( ( reply ) => ( {
174+ id : reply . id ,
175+ url : reply . url ,
176+ createdAt : reply . createdAt ,
177+ author : reply . author ,
178+ bodyHTML : reply . bodyHTML ,
179+ reactionGroups : reply . reactionGroups ,
180+ isDiscussion : false ,
181+ title : discussionTitle ,
182+ discussionId : discussionId ,
183+ parentId : replyId ,
184+ replyToId : reply . replyTo ? reply . replyTo . id : null ,
185+ replyToAuthor : reply . replyTo ? reply . replyTo . author . login : null ,
186+ level : level ,
187+ type : 'reply'
188+ } ) )
189+
190+ // 递归获取更深层的回复(但限制最大深度)
191+ const deepReplies = [ ]
192+ if ( level < 5 ) {
193+ // 限制最大深度为5层
194+ for ( const reply of replies ) {
195+ const childReplies = await fetchDeepReplies (
196+ reply . id ,
197+ discussionId ,
198+ discussionTitle ,
199+ level + 1
200+ )
201+ deepReplies . push ( ...childReplies )
202+ }
203+ }
204+
205+ return [ ...replies , ...deepReplies ]
206+ }
207+
208+ // 简化的递归函数,不再使用嵌套查询
140209function processReplies ( replies , parentId , discussionId , discussionTitle , level = 1 ) {
141210 const processedReplies = [ ]
142211
@@ -159,18 +228,6 @@ function processReplies(replies, parentId, discussionId, discussionTitle, level
159228 }
160229
161230 processedReplies . push ( processedReply )
162-
163- // 递归处理子回复
164- if ( reply . replies && reply . replies . nodes && reply . replies . nodes . length > 0 ) {
165- const childReplies = processReplies (
166- reply . replies . nodes ,
167- reply . id ,
168- discussionId ,
169- discussionTitle ,
170- level + 1
171- )
172- processedReplies . push ( ...childReplies )
173- }
174231 }
175232
176233 return processedReplies
@@ -179,7 +236,9 @@ function processReplies(replies, parentId, discussionId, discussionTitle, level
179236async function main ( ) {
180237 try {
181238 const discussions = await fetchAllDiscussions ( )
182- const allComments = discussions . flatMap ( ( discussion ) => {
239+ const allComments = [ ]
240+
241+ for ( const discussion of discussions ) {
183242 // Map the main discussion post
184243 const mainComment = {
185244 id : discussion . id ,
@@ -198,6 +257,8 @@ async function main() {
198257 type : 'discussion'
199258 }
200259
260+ allComments . push ( mainComment )
261+
201262 // 处理顶级评论
202263 const topLevelComments = discussion . comments . nodes . map ( ( comment ) => ( {
203264 id : comment . id ,
@@ -216,22 +277,38 @@ async function main() {
216277 type : 'comment'
217278 } ) )
218279
219- // 处理所有嵌套回复
220- const allReplies = discussion . comments . nodes . flatMap ( ( comment ) => {
280+ allComments . push ( ...topLevelComments )
281+
282+ // 处理第一层回复
283+ for ( const comment of discussion . comments . nodes ) {
221284 if ( comment . replies && comment . replies . nodes && comment . replies . nodes . length > 0 ) {
222- return processReplies (
223- comment . replies . nodes ,
224- comment . id ,
225- discussion . id ,
226- discussion . title ,
227- 2
228- )
229- }
230- return [ ]
231- } )
285+ const firstLevelReplies = comment . replies . nodes . map ( ( reply ) => ( {
286+ id : reply . id ,
287+ url : reply . url ,
288+ createdAt : reply . createdAt ,
289+ author : reply . author ,
290+ bodyHTML : reply . bodyHTML ,
291+ reactionGroups : reply . reactionGroups ,
292+ isDiscussion : false ,
293+ title : discussion . title ,
294+ discussionId : discussion . id ,
295+ parentId : comment . id ,
296+ replyToId : reply . replyTo ? reply . replyTo . id : null ,
297+ replyToAuthor : reply . replyTo ? reply . replyTo . author . login : null ,
298+ level : 2 ,
299+ type : 'reply'
300+ } ) )
232301
233- return [ mainComment , ...topLevelComments , ...allReplies ]
234- } )
302+ allComments . push ( ...firstLevelReplies )
303+
304+ // 获取更深层的回复
305+ for ( const reply of comment . replies . nodes ) {
306+ const deepReplies = await fetchDeepReplies ( reply . id , discussion . id , discussion . title , 3 )
307+ allComments . push ( ...deepReplies )
308+ }
309+ }
310+ }
311+ }
235312
236313 // Sort all comments and replies together by date
237314 allComments . sort ( ( a , b ) => new Date ( b . createdAt ) - new Date ( a . createdAt ) )
0 commit comments