Skip to content

Commit

Permalink
feat: octokit
Browse files Browse the repository at this point in the history
  • Loading branch information
whilefoo committed Jan 21, 2024
1 parent 06fc88c commit 9e70be5
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/context.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { EmitterWebhookEvent as WebhookEvent, EmitterWebhookEventName as WebhookEventName } from "@octokit/webhooks";
import { customOctokit } from "./octokit";

export class Context<T extends WebhookEventName = WebhookEventName> {
public key: WebhookEventName;
public name: WebhookEventName;
public id: string;
public payload: WebhookEvent<T>["payload"];
public octokit: InstanceType<typeof customOctokit>;

constructor(event: WebhookEvent<T>) {
constructor(event: WebhookEvent<T>, octokit: InstanceType<typeof customOctokit>) {
this.name = event.name;
this.id = event.id;
this.payload = event.payload;
Expand All @@ -15,6 +17,7 @@ export class Context<T extends WebhookEventName = WebhookEventName> {
} else {
this.key = this.name;
}
this.octokit = octokit;
}
}

Expand Down
51 changes: 48 additions & 3 deletions src/event-handler.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,64 @@
import { Webhooks } from "@octokit/webhooks";
import { Context, SimplifiedContext } from "./context";
import { customOctokit } from "./octokit";

export type Options = {
webhookSecret: string;
appId: string | number;
privateKey: string;
};

export class EventHandler {
public webhooks: Webhooks<SimplifiedContext>;
public on: Webhooks<SimplifiedContext>["on"];
public onAny: Webhooks<SimplifiedContext>["onAny"];
public onError: Webhooks<SimplifiedContext>["onError"];

constructor(secret: string) {
private _webhookSecret: string;
private _privateKey: string;
private _appId: number;

constructor(options: Options) {
this._privateKey = options.privateKey;
this._appId = Number(options.appId);
/*const key = crypto.subtle
.importKey(
"pkcs8",
new TextEncoder().encode(this.privateKey),
{
name: "RSASSA-PKCS1-v1_5",
hash: "SHA-256",
},
true,
[]
)
.then((key) => {
crypto.subtle.exportKey("s", key).then((keydata) => {
console.log(keydata);
});
});*/

this._webhookSecret = options.webhookSecret;

this.webhooks = new Webhooks<SimplifiedContext>({
secret,
secret: this._webhookSecret,
transform: (event) => {
return new Context(event);
let installationId: number | undefined = undefined;
if ("installation" in event.payload) {
installationId = event.payload.installation?.id;
}
const octokit = new customOctokit({
auth: {
appId: this._appId,
privateKey: this._privateKey,
installationId: installationId,
},
});

return new Context(event, octokit);
},
});

this.on = this.webhooks.on;
this.onAny = this.webhooks.onAny;
this.onError = this.webhooks.onError;
Expand Down
7 changes: 7 additions & 0 deletions src/handlers/issue/comment_created.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@ import { Context } from "../../context";

export async function handleIssueCommentCreated(event: Context<"issue_comment.created">) {
console.log(event);

await event.octokit.issues.createComment({
owner: event.payload.repository.owner.login,
repo: event.payload.repository.name,
issue_number: event.payload.issue.number,
body: "Hello from the worker!",
});
}
53 changes: 53 additions & 0 deletions src/octokit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Octokit } from "@octokit/core";
import { RequestOptions } from "@octokit/types";
import { paginateRest } from "@octokit/plugin-paginate-rest";
import { legacyRestEndpointMethods } from "@octokit/plugin-rest-endpoint-methods";
import { retry } from "@octokit/plugin-retry";
import { throttling } from "@octokit/plugin-throttling";
import { createAppAuth } from "@octokit/auth-app";

const defaultOptions = {
authStrategy: createAppAuth,
throttle: {
onAbuseLimit: (retryAfter: number, options: RequestOptions, octokit: Octokit) => {
octokit.log.warn(`Abuse limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
return true;
},
onRateLimit: (retryAfter: number, options: RequestOptions, octokit: Octokit) => {
octokit.log.warn(`Rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
return true;
},
onSecondaryRateLimit: (retryAfter: number, options: RequestOptions, octokit: Octokit) => {
octokit.log.warn(`Secondary rate limit hit with "${options.method} ${options.url}", retrying in ${retryAfter} seconds.`);
return true;
},
},
};

function requestLogging(octokit: Octokit) {
octokit.hook.error("request", (error, options) => {
if ("status" in error) {
const { method, url, body } = octokit.request.endpoint.parse(options);
const msg = `GitHub request: ${method} ${url} - ${error.status}`;

// @ts-expect-error log.debug is a pino log method and accepts a fields object
octokit.log.debug(body || {}, msg);
}

throw error;
});

octokit.hook.after("request", (result, options) => {
const { method, url, body } = octokit.request.endpoint.parse(options);
const msg = `GitHub request: ${method} ${url} - ${result.status}`;

// @ts-expect-error log.debug is a pino log method and accepts a fields object
octokit.log.debug(body || {}, msg);
});
}

export const customOctokit = Octokit.plugin(throttling, retry, paginateRest, legacyRestEndpointMethods, requestLogging).defaults(
(instanceOptions: object) => {
return Object.assign({}, defaultOptions, instanceOptions);
}
);
2 changes: 1 addition & 1 deletion src/types/env.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Type as T, type Static } from "@sinclair/typebox";

export const envSchema = T.Object({ WEBHOOK_SECRET: T.String() });
export const envSchema = T.Object({ WEBHOOK_SECRET: T.String(), APP_ID: T.String(), PRIVATE_KEY: T.String() });
export type Env = Static<typeof envSchema>;
2 changes: 1 addition & 1 deletion src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default {
});
}

const eventHandler = new EventHandler(env.WEBHOOK_SECRET);
const eventHandler = new EventHandler({ webhookSecret: env.WEBHOOK_SECRET, appId: env.APP_ID, privateKey: env.PRIVATE_KEY });
bindHandlers(eventHandler);

try {
Expand Down

0 comments on commit 9e70be5

Please sign in to comment.