Skip to content

Commit

Permalink
Add comments count endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
typeofweb committed Oct 19, 2021
1 parent c017707 commit fcc6fcc
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/types/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ export interface GRepositoryDiscussion {
};
}

export interface GRepositoryDiscussionCount {
comments: {
totalCount: number;
}
}

export interface GDiscussionCategory {
id: string;
name: string;
Expand Down
71 changes: 71 additions & 0 deletions pages/api/discussions/comments-count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { NextApiRequest, NextApiResponse } from "next";
import { IError } from "../../../lib/types/adapter";
import { DiscussionQuery } from "../../../lib/types/common";
import { getAppAccessToken } from "../../../services/github/getAppAccessToken";
import { getDiscussionCommentsCount } from "../../../services/github/getDiscussionCommentsCount";

export default async function get(req: NextApiRequest, res: NextApiResponse<number | IError>) {
const params: DiscussionQuery = {
repo: req.query.repo as string,
term: req.query.term as string,
number: +req.query.number,
category: req.query.category as string
};

const userToken = req.headers.authorization?.split('Bearer ')[1];
let token = userToken;
if (!token) {
try {
token = await getAppAccessToken(params.repo);
} catch (error) {
res.status(403).json({ error: error.message });
return;
}
}

const response = await getDiscussionCommentsCount(params, token);

if ('message' in response) {
if (response.message.includes('Bad credentials')) {
res.status(403).json({ error: response.message });
return;
}
res.status(500).json({ error: response.message });
return;
}

if ('errors' in response) {
const error = response.errors[0];
if (error?.message?.includes('API rate limit exceeded')) {
let message = `API rate limit exceeded for ${params.repo}`;
if (!userToken) {
message += '. Sign in to increase the rate limit';
}
res.status(429).json({ error: message });
return;
}

console.error(response);
const message = response.errors.map?.(({ message }) => message).join('. ') || 'Unknown error';
res.status(500).json({ error: message });
return;
}

const { data } = response;
if (!data) {
console.error(response);
res.status(500).json({ error: 'Unable to fetch discussion' });
return;
}

const discussion = 'search' in data ? data.search.nodes[0] ?? null : data.repository.discussion;

if (!discussion) {
res.status(404).json({ error: 'Discussion not found' });
return;
}


res.setHeader('Cache-Control', 'public, s-maxage=3600, stale-while-revalidate=900, stale-if-error=86400');
res.status(200).json(discussion.comments.totalCount);
}
82 changes: 82 additions & 0 deletions services/github/getDiscussionCommentsCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { DiscussionQuery } from '../../lib/types/common';
import { GError, GMultipleErrors, GRepositoryDiscussionCount } from '../../lib/types/github';
import { parseRepoWithOwner } from '../../lib/utils';
import { GITHUB_GRAPHQL_API_URL } from '../config';

const DISCUSSION_QUERY = `
comments {
totalCount
}`;

const SEARCH_QUERY = `
search(type: DISCUSSION last: 1 query: $query) {
nodes {
... on Discussion {
${DISCUSSION_QUERY}
}
}
}`;

const SPECIFIC_QUERY = `
repository(owner: $owner, name: $name) {
discussion(number: $number) {
${DISCUSSION_QUERY}
}
}
`;

const GET_DISCUSSION_QUERY = (type: 'term' | 'number') => `
query(${
type === 'term' ? '$query: String!' : '$owner: String! $name: String! $number: Int!'
}) {
${type === 'term' ? SEARCH_QUERY : SPECIFIC_QUERY}
}`;

export interface GetDiscussionCommentsCountParams extends DiscussionQuery {}

interface SearchResponse {
data: {
search: {
nodes: Array<GRepositoryDiscussionCount>;
};
};
}

interface SpecificResponse {
data: {
repository: {
discussion: GRepositoryDiscussionCount;
};
};
}

type GetDiscussionCommentsCountResponse = SearchResponse | SpecificResponse;

export async function getDiscussionCommentsCount(
params: GetDiscussionCommentsCountParams,
token: string,
): Promise<GetDiscussionCommentsCountResponse | GError | GMultipleErrors> {
const { repo: repoWithOwner, term, number, category, ...pagination } = params;

// Force repo to lowercase to prevent GitHub's bug when using category in query.
// https://github.com/giscus/giscus/issues/118
const repo = repoWithOwner.toLowerCase();
const categoryQuery = category ? `category:${JSON.stringify(category)}` : '';
const query = `repo:${repo} ${categoryQuery} in:title ${term}`;
const gql = GET_DISCUSSION_QUERY(number ? 'number' : 'term');

return fetch(GITHUB_GRAPHQL_API_URL, {
method: 'POST',
headers: { Authorization: `Bearer ${token}` },

body: JSON.stringify({
query: gql,
variables: {
repo,
query,
number,
...parseRepoWithOwner(repo),
},
}),
}).then((r) => r.json());
}

1 comment on commit fcc6fcc

@vercel
Copy link

@vercel vercel bot commented on fcc6fcc Oct 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.