84 lines
3.2 KiB
TypeScript
84 lines
3.2 KiB
TypeScript
import { App } from "octokit";
|
|
import { Webhooks } from "@octokit/webhooks";
|
|
import type { EmitterWebhookEvent } from "@octokit/webhooks";
|
|
import { log } from "@/utils/log";
|
|
|
|
let app: App | null = null;
|
|
let webhooks: Webhooks | null = null;
|
|
|
|
export async function initGithub() {
|
|
if (
|
|
process.env.GITHUB_APP_ID &&
|
|
process.env.GITHUB_PRIVATE_KEY &&
|
|
process.env.GITHUB_CLIENT_ID &&
|
|
process.env.GITHUB_CLIENT_SECRET &&
|
|
process.env.GITHUB_REDIRECT_URI &&
|
|
process.env.GITHUB_WEBHOOK_SECRET
|
|
) {
|
|
app = new App({
|
|
appId: process.env.GITHUB_APP_ID,
|
|
privateKey: process.env.GITHUB_PRIVATE_KEY,
|
|
webhooks: {
|
|
secret: process.env.GITHUB_WEBHOOK_SECRET
|
|
}
|
|
});
|
|
|
|
// Initialize standalone webhooks handler for type-safe event processing
|
|
webhooks = new Webhooks({
|
|
secret: process.env.GITHUB_WEBHOOK_SECRET
|
|
});
|
|
|
|
// Register type-safe event handlers
|
|
registerWebhookHandlers();
|
|
}
|
|
}
|
|
|
|
function registerWebhookHandlers() {
|
|
if (!webhooks) return;
|
|
|
|
// Type-safe handlers for specific events
|
|
webhooks.on("push", async ({ id, name, payload }: EmitterWebhookEvent<"push">) => {
|
|
log({ module: 'github-webhook', event: 'push' },
|
|
`Push to ${payload.repository.full_name} by ${payload.pusher.name}`);
|
|
});
|
|
|
|
webhooks.on("pull_request", async ({ id, name, payload }: EmitterWebhookEvent<"pull_request">) => {
|
|
log({ module: 'github-webhook', event: 'pull_request' },
|
|
`PR ${payload.action} on ${payload.repository.full_name}: #${payload.pull_request.number} - ${payload.pull_request.title}`);
|
|
});
|
|
|
|
webhooks.on("issues", async ({ id, name, payload }: EmitterWebhookEvent<"issues">) => {
|
|
log({ module: 'github-webhook', event: 'issues' },
|
|
`Issue ${payload.action} on ${payload.repository.full_name}: #${payload.issue.number} - ${payload.issue.title}`);
|
|
});
|
|
|
|
webhooks.on(["star.created", "star.deleted"], async ({ id, name, payload }: EmitterWebhookEvent<"star.created" | "star.deleted">) => {
|
|
const action = payload.action === 'created' ? 'starred' : 'unstarred';
|
|
log({ module: 'github-webhook', event: 'star' },
|
|
`Repository ${action}: ${payload.repository.full_name} by ${payload.sender.login}`);
|
|
});
|
|
|
|
webhooks.on("repository", async ({ id, name, payload }: EmitterWebhookEvent<"repository">) => {
|
|
log({ module: 'github-webhook', event: 'repository' },
|
|
`Repository ${payload.action}: ${payload.repository.full_name}`);
|
|
});
|
|
|
|
// Catch-all for unhandled events
|
|
webhooks.onAny(async ({ id, name, payload }: EmitterWebhookEvent) => {
|
|
log({ module: 'github-webhook', event: name as string },
|
|
`Received webhook event: ${name}`, { id });
|
|
});
|
|
|
|
webhooks.onError((error: any) => {
|
|
log({ module: 'github-webhook', level: 'error' },
|
|
`Webhook handler error: ${error.event?.name}`, error);
|
|
});
|
|
}
|
|
|
|
export function getWebhooks(): Webhooks | null {
|
|
return webhooks;
|
|
}
|
|
|
|
export function getApp(): App | null {
|
|
return app;
|
|
} |