Skip to main content
Glama
github.ts3.38 kB
import { App, Octokit } from 'octokit'; import type { ActionResponse, Feedback } from '@/components/rate'; export const repo = 'fumadocs'; export const owner = 'fuma-nama'; export const DocsCategory = 'Docs Feedback'; let instance: Octokit | undefined; async function getOctokit(): Promise<Octokit> { if (instance) return instance; const appId = process.env.GITHUB_APP_ID; const privateKey = process.env.GITHUB_APP_PRIVATE_KEY; if (!appId || !privateKey) { throw new Error( 'No GitHub keys provided for Github app, docs feedback feature will not work.', ); } const app = new App({ appId, privateKey, }); const { data } = await app.octokit.request( 'GET /repos/{owner}/{repo}/installation', { owner, repo, headers: { 'X-GitHub-Api-Version': '2022-11-28', }, }, ); instance = await app.getInstallationOctokit(data.id); return instance; } interface RepositoryInfo { id: string; discussionCategories: { nodes: { id: string; name: string; }[]; }; } let cachedDestination: RepositoryInfo | undefined; async function getFeedbackDestination() { if (cachedDestination) return cachedDestination; const octokit = await getOctokit(); const { repository, }: { repository: RepositoryInfo; } = await octokit.graphql(` query { repository(owner: "${owner}", name: "${repo}") { id discussionCategories(first: 25) { nodes { id name } } } } `); return (cachedDestination = repository); } export async function onRateAction( url: string, feedback: Feedback, ): Promise<ActionResponse> { 'use server'; const octokit = await getOctokit(); const destination = await getFeedbackDestination(); if (!octokit || !destination) throw new Error('GitHub comment integration is not configured.'); const category = destination.discussionCategories.nodes.find( (category) => category.name === DocsCategory, ); if (!category) throw new Error( `Please create a "${DocsCategory}" category in GitHub Discussion`, ); const title = `Feedback for ${url}`; const body = `[${feedback.opinion}] ${feedback.message}\n\n> Forwarded from user feedback.`; let { search: { nodes: [discussion], }, }: { search: { nodes: { id: string; url: string }[]; }; } = await octokit.graphql(` query { search(type: DISCUSSION, query: ${JSON.stringify(`${title} in:title repo:${owner}/${repo} author:@me`)}, first: 1) { nodes { ... on Discussion { id, url } } } }`); if (discussion) { await octokit.graphql(` mutation { addDiscussionComment(input: { body: ${JSON.stringify(body)}, discussionId: "${discussion.id}" }) { comment { id } } }`); } else { const result: { discussion: { id: string; url: string }; } = await octokit.graphql(` mutation { createDiscussion(input: { repositoryId: "${destination.id}", categoryId: "${category!.id}", body: ${JSON.stringify(body)}, title: ${JSON.stringify(title)} }) { discussion { id, url } } }`); discussion = result.discussion; } return { githubUrl: discussion.url, }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mcpauth/mcpauth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server