Skip to content

Commit e014779

Browse files
feat: enhance GetRepositoryDiscussions to include comments and comment count
1 parent 28729c8 commit e014779

File tree

1 file changed

+122
-58
lines changed

1 file changed

+122
-58
lines changed

pkg/github/discussions.go

Lines changed: 122 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,29 @@ import (
1111
"github.com/shurcooL/githubv4"
1212
)
1313

14+
// Comment represents a comment on a GitHub Discussion
15+
type Comment struct {
16+
ID string `json:"id"`
17+
Body string `json:"body"`
18+
CreatedAt string `json:"createdAt"`
19+
Author string `json:"author"`
20+
}
21+
1422
// Discussion represents a GitHub Discussion with its essential fields
1523
type Discussion struct {
16-
ID string `json:"id"`
17-
Number int `json:"number"`
18-
Title string `json:"title"`
19-
Body string `json:"body"`
20-
CreatedAt string `json:"createdAt"`
21-
UpdatedAt string `json:"updatedAt"`
22-
URL string `json:"url"`
23-
Category string `json:"category"`
24-
Author string `json:"author"`
25-
Locked bool `json:"locked"`
26-
UpvoteCount int `json:"upvoteCount"`
24+
ID string `json:"id"`
25+
Number int `json:"number"`
26+
Title string `json:"title"`
27+
Body string `json:"body"`
28+
CreatedAt string `json:"createdAt"`
29+
UpdatedAt string `json:"updatedAt"`
30+
URL string `json:"url"`
31+
Category string `json:"category"`
32+
Author string `json:"author"`
33+
Locked bool `json:"locked"`
34+
UpvoteCount int `json:"upvoteCount"`
35+
CommentCount int `json:"commentCount"`
36+
Comments []Comment `json:"comments,omitempty"`
2737
}
2838

2939
// GetRepositoryDiscussions creates a tool to fetch discussions from a specific repository.
@@ -68,11 +78,10 @@ func GetRepositoryDiscussions(getGraphQLClient GetGraphQLClientFn, t translation
6878

6979
// Define GraphQL query variables
7080
variables := map[string]interface{}{
71-
"owner": githubv4.String(owner),
72-
"name": githubv4.String(repo),
73-
"first": githubv4.Int(pagination.perPage),
74-
"after": (*githubv4.String)(nil), // For pagination - null means first page
75-
"categoryId": (*githubv4.ID)(nil), // For category ID - null means no filter
81+
"owner": githubv4.String(owner),
82+
"name": githubv4.String(repo),
83+
"first": githubv4.Int(pagination.perPage),
84+
"after": (*githubv4.String)(nil), // For pagination - null means first page
7685
}
7786

7887
// For pagination beyond the first page
@@ -84,11 +93,7 @@ func GetRepositoryDiscussions(getGraphQLClient GetGraphQLClientFn, t translation
8493
variables["after"] = &cursorStr
8594
}
8695

87-
if categoryId != "" {
88-
variables["categoryId"] = githubv4.ID(categoryId)
89-
}
90-
91-
// Define the GraphQL query structure
96+
// Define the GraphQL query structure and query string based on whether categoryId is provided
9297
var query struct {
9398
Repository struct {
9499
Discussions struct {
@@ -109,42 +114,87 @@ func GetRepositoryDiscussions(getGraphQLClient GetGraphQLClientFn, t translation
109114
}
110115
Locked bool
111116
UpvoteCount int
117+
Comments struct {
118+
TotalCount int
119+
Nodes []struct {
120+
ID githubv4.ID
121+
Body string
122+
CreatedAt githubv4.DateTime
123+
Author struct {
124+
Login string
125+
}
126+
}
127+
} `graphql:"comments(first: 10)"`
112128
}
113129
PageInfo struct {
114130
EndCursor githubv4.String
115131
HasNextPage bool
116132
}
117-
} `graphql:"discussions(first: $first, after: $after, categoryId: $categoryId)"`
133+
} `graphql:"discussions(first: $first, after: $after)"`
118134
} `graphql:"repository(owner: $owner, name: $name)"`
119135
}
120136

121-
// Only include categoryId in the query if it was provided
122-
if categoryId == "" {
123-
// Redefine the query without the categoryId filter
124-
query.Repository.Discussions = struct {
125-
TotalCount int
126-
Nodes []struct {
127-
ID githubv4.ID
128-
Number int
129-
Title string
130-
Body string
131-
CreatedAt githubv4.DateTime
132-
UpdatedAt githubv4.DateTime
133-
URL githubv4.URI
134-
Category struct {
135-
Name string
136-
}
137-
Author struct {
138-
Login string
139-
}
140-
Locked bool
141-
UpvoteCount int
137+
// Define a type for the Discussions GraphQL query to avoid duplication
138+
type discussionQueryType struct {
139+
TotalCount int
140+
Nodes []struct {
141+
ID githubv4.ID
142+
Number int
143+
Title string
144+
Body string
145+
CreatedAt githubv4.DateTime
146+
UpdatedAt githubv4.DateTime
147+
URL githubv4.URI
148+
Category struct {
149+
Name string
142150
}
143-
PageInfo struct {
144-
EndCursor githubv4.String
145-
HasNextPage bool
151+
Author struct {
152+
Login string
146153
}
147-
}{}
154+
Locked bool
155+
UpvoteCount int
156+
Comments struct {
157+
TotalCount int
158+
Nodes []struct {
159+
ID githubv4.ID
160+
Body string
161+
CreatedAt githubv4.DateTime
162+
Author struct {
163+
Login string
164+
}
165+
}
166+
} `graphql:"comments(first: 10)"`
167+
}
168+
PageInfo struct {
169+
EndCursor githubv4.String
170+
HasNextPage bool
171+
}
172+
}
173+
174+
// Add categoryId to query if it was provided
175+
if categoryId != "" {
176+
variables["categoryId"] = githubv4.ID(categoryId)
177+
// Use a separate query structure that includes the categoryId parameter
178+
var queryWithCategory struct {
179+
Repository struct {
180+
Discussions discussionQueryType `graphql:"discussions(first: $first, after: $after, categoryId: $categoryId)"`
181+
} `graphql:"repository(owner: $owner, name: $name)"`
182+
}
183+
184+
// Execute the query with categoryId
185+
err = client.Query(ctx, &queryWithCategory, variables)
186+
if err != nil {
187+
return nil, fmt.Errorf("failed to query discussions with category: %w", err)
188+
}
189+
190+
// Copy the results to our main query structure
191+
query.Repository.Discussions = queryWithCategory.Repository.Discussions
192+
} else {
193+
// Execute the original query without categoryId
194+
err = client.Query(ctx, &query, variables)
195+
if err != nil {
196+
return nil, fmt.Errorf("failed to query discussions: %w", err)
197+
}
148198
}
149199

150200
// Execute the GraphQL query
@@ -156,18 +206,32 @@ func GetRepositoryDiscussions(getGraphQLClient GetGraphQLClientFn, t translation
156206
// Convert the GraphQL response to our Discussion type
157207
discussions := make([]Discussion, 0, len(query.Repository.Discussions.Nodes))
158208
for _, node := range query.Repository.Discussions.Nodes {
209+
// Process comments for this discussion
210+
comments := make([]Comment, 0, len(node.Comments.Nodes))
211+
for _, commentNode := range node.Comments.Nodes {
212+
comment := Comment{
213+
ID: fmt.Sprintf("%v", commentNode.ID),
214+
Body: commentNode.Body,
215+
CreatedAt: commentNode.CreatedAt.String(),
216+
Author: commentNode.Author.Login,
217+
}
218+
comments = append(comments, comment)
219+
}
220+
159221
discussion := Discussion{
160-
ID: fmt.Sprintf("%v", node.ID),
161-
Number: node.Number,
162-
Title: node.Title,
163-
Body: node.Body,
164-
CreatedAt: node.CreatedAt.String(),
165-
UpdatedAt: node.UpdatedAt.String(),
166-
URL: node.URL.String(),
167-
Category: node.Category.Name,
168-
Author: node.Author.Login,
169-
Locked: node.Locked,
170-
UpvoteCount: node.UpvoteCount,
222+
ID: fmt.Sprintf("%v", node.ID),
223+
Number: node.Number,
224+
Title: node.Title,
225+
Body: node.Body,
226+
CreatedAt: node.CreatedAt.String(),
227+
UpdatedAt: node.UpdatedAt.String(),
228+
URL: node.URL.String(),
229+
Category: node.Category.Name,
230+
Author: node.Author.Login,
231+
Locked: node.Locked,
232+
UpvoteCount: node.UpvoteCount,
233+
CommentCount: node.Comments.TotalCount,
234+
Comments: comments,
171235
}
172236
discussions = append(discussions, discussion)
173237
}

0 commit comments

Comments
 (0)