mirror of
https://github.com/xHyroM/bun-discord-bot.git
synced 2024-11-22 14:41:05 +01:00
chore: cleanup
This commit is contained in:
parent
66ed183c13
commit
21b74eb472
6 changed files with 34 additions and 27 deletions
|
@ -6,7 +6,6 @@ import Collection from '@discordjs/collection';
|
||||||
import { CommandContext } from '../structures/contexts/CommandContext';
|
import { CommandContext } from '../structures/contexts/CommandContext';
|
||||||
import { getIssueOrPR, search, formatStatus } from '../utils/githubUtils';
|
import { getIssueOrPR, search, formatStatus } from '../utils/githubUtils';
|
||||||
|
|
||||||
const cooldowns: Collection<string, number> = new Collection();
|
|
||||||
const invalidIssue = (ctx: CommandContext, query: string) => {
|
const invalidIssue = (ctx: CommandContext, query: string) => {
|
||||||
return ctx.editResponse(
|
return ctx.editResponse(
|
||||||
`\`❌\` Invalid issue or pull request \`${query}\`. You can check [github search syntax](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests)`
|
`\`❌\` Invalid issue or pull request \`${query}\`. You can check [github search syntax](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests)`
|
||||||
|
@ -40,22 +39,12 @@ new Command({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
run: async(ctx) => {
|
run: async(ctx) => {
|
||||||
if (cooldowns?.has(ctx.user.id) && cooldowns.get(ctx.user.id) > Date.now()) {
|
ctx.command.runEditResponse(ctx)
|
||||||
return ctx.respond({
|
|
||||||
type: InteractionResponseType.ChannelMessageWithSource,
|
|
||||||
data: {
|
|
||||||
content: `⚠️ You are in cooldown, you will be able to use this command <t:${Math.floor(cooldowns.get(ctx.user.id) / 1000)}:R>.`,
|
|
||||||
flags: MessageFlags.Ephemeral,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ctx.command.runWithoutReturn(ctx)
|
|
||||||
return ctx.respond({
|
return ctx.respond({
|
||||||
type: InteractionResponseType.DeferredChannelMessageWithSource
|
type: InteractionResponseType.DeferredChannelMessageWithSource
|
||||||
})
|
})
|
||||||
}
|
|
||||||
},
|
},
|
||||||
runWithoutReturn: async(ctx) => {
|
runEditResponse: async(ctx) => {
|
||||||
let query: string = (ctx.options[0] as APIApplicationCommandInteractionDataStringOption).value;
|
let query: string = (ctx.options[0] as APIApplicationCommandInteractionDataStringOption).value;
|
||||||
const repository: string = (ctx.options?.[1] as APIApplicationCommandInteractionDataStringOption)?.value || 'oven-sh/bun';
|
const repository: string = (ctx.options?.[1] as APIApplicationCommandInteractionDataStringOption)?.value || 'oven-sh/bun';
|
||||||
|
|
||||||
|
|
13
src/index.ts
13
src/index.ts
|
@ -5,7 +5,7 @@ import { Logger } from './utils/Logger';
|
||||||
// @ts-expect-error Types :(
|
// @ts-expect-error Types :(
|
||||||
import config from '../files/config.toml';
|
import config from '../files/config.toml';
|
||||||
import loadCommands from './utils/loadCommands';
|
import loadCommands from './utils/loadCommands';
|
||||||
import { verifyKey } from './utils/verify';
|
import { verifyGithubKey, verifyKey } from './utils/verify';
|
||||||
import { APIPingInteraction, APIApplicationCommandInteraction, APIMessageComponentInteraction, InteractionType, InteractionResponseType, ApplicationCommandType, APIApplicationCommandAutocompleteInteraction, ApplicationCommandOptionType } from 'discord-api-types/v10';
|
import { APIPingInteraction, APIApplicationCommandInteraction, APIMessageComponentInteraction, InteractionType, InteractionResponseType, ApplicationCommandType, APIApplicationCommandAutocompleteInteraction, ApplicationCommandOptionType } from 'discord-api-types/v10';
|
||||||
import { CommandContext } from './structures/contexts/CommandContext';
|
import { CommandContext } from './structures/contexts/CommandContext';
|
||||||
import { Commands } from './managers/CommandManager';
|
import { Commands } from './managers/CommandManager';
|
||||||
|
@ -13,7 +13,6 @@ import registerCommands from './utils/registerCommands';
|
||||||
import { Option, OptionOptions } from './structures/Option';
|
import { Option, OptionOptions } from './structures/Option';
|
||||||
import { AutocompleteContext } from './structures/contexts/AutocompleteContext';
|
import { AutocompleteContext } from './structures/contexts/AutocompleteContext';
|
||||||
import { deleteIssueOrPR, fetchIssues, fetchPullRequests, setIssue, setPullRequest } from './utils/githubUtils';
|
import { deleteIssueOrPR, fetchIssues, fetchPullRequests, setIssue, setPullRequest } from './utils/githubUtils';
|
||||||
import createHmac from 'create-hmac';
|
|
||||||
|
|
||||||
await fetchIssues();
|
await fetchIssues();
|
||||||
await fetchPullRequests();
|
await fetchPullRequests();
|
||||||
|
@ -88,9 +87,13 @@ app.post('/github_webhook', bodyParse(), (c) => {
|
||||||
typeof c.req?.parsedBody !== 'object'
|
typeof c.req?.parsedBody !== 'object'
|
||||||
) return c.redirect('https://www.youtube.com/watch?v=FMhScnY0dME'); // fireship :D
|
) return c.redirect('https://www.youtube.com/watch?v=FMhScnY0dME'); // fireship :D
|
||||||
|
|
||||||
const githubWebhooksSecret = new TextEncoder().encode(config.api.github_webhooks_secret);
|
if (
|
||||||
const sha256 = `sha256=${createHmac('sha256', githubWebhooksSecret).update(JSON.stringify(c.req.parsedBody)).digest('hex')}`;
|
!verifyGithubKey(
|
||||||
if (sha256 !== c.req.headers.get('X-Hub-Signature-256')) return c.redirect('https://www.youtube.com/watch?v=FMhScnY0dME'); // fireship :D
|
JSON.stringify(c.req.parsedBody),
|
||||||
|
c.req.headers.get('X-Hub-Signature-256'),
|
||||||
|
config.api.github_webhooks_secret
|
||||||
|
)
|
||||||
|
) return c.redirect('https://www.youtube.com/watch?v=FMhScnY0dME'); // fireship :D
|
||||||
|
|
||||||
const issueOrPr = c.req.parsedBody;
|
const issueOrPr = c.req.parsedBody;
|
||||||
if (issueOrPr.action !== 'deleted') {
|
if (issueOrPr.action !== 'deleted') {
|
||||||
|
|
|
@ -16,7 +16,7 @@ export interface CommandOptions {
|
||||||
defaultMemberPermissions?: string;
|
defaultMemberPermissions?: string;
|
||||||
options?: Option[] | OptionOptions[];
|
options?: Option[] | OptionOptions[];
|
||||||
run: (ctx: CommandContext) => Response | Promise<Response>;
|
run: (ctx: CommandContext) => Response | Promise<Response>;
|
||||||
runWithoutReturn?: (ctx: CommandContext) => any;
|
runEditResponse?: (ctx: CommandContext) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Command {
|
export class Command {
|
||||||
|
@ -28,7 +28,7 @@ export class Command {
|
||||||
public defaultMemberPermissions?: string;
|
public defaultMemberPermissions?: string;
|
||||||
public options: Option[] | OptionOptions[];
|
public options: Option[] | OptionOptions[];
|
||||||
public run: (ctx: CommandContext) => Response | Promise<Response>;
|
public run: (ctx: CommandContext) => Response | Promise<Response>;
|
||||||
public runWithoutReturn: (ctx: CommandContext) => any;
|
public runEditResponse: (ctx: CommandContext) => any;
|
||||||
|
|
||||||
public constructor(options: CommandOptions) {
|
public constructor(options: CommandOptions) {
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
|
@ -45,7 +45,7 @@ export class Command {
|
||||||
else return new Option(option);
|
else return new Option(option);
|
||||||
});
|
});
|
||||||
this.run = options.run;
|
this.run = options.run;
|
||||||
this.runWithoutReturn = options.runWithoutReturn;
|
this.runEditResponse = options.runEditResponse;
|
||||||
|
|
||||||
Commands.register(this);
|
Commands.register(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
export default (value: string) => /^-?\d+$/.test(value);
|
|
|
@ -1,2 +0,0 @@
|
||||||
export const githubIssuesAndPullRequests = (owner: string, repository: string) =>
|
|
||||||
new RegExp(`https?:\\\/\\\/github\\\.com\\\/${owner}\\\/${repository}\\\/(?:issues\\\/\\\d+|pull\\\/\d+)`, 'gm');
|
|
|
@ -1,6 +1,7 @@
|
||||||
// from https://github.com/discord/discord-interactions-js/blob/main/src/index.ts
|
// from https://github.com/discord/discord-interactions-js/blob/main/src/index.ts
|
||||||
|
|
||||||
import { sign } from 'tweetnacl';
|
import { sign } from 'tweetnacl';
|
||||||
|
import createHmac from 'create-hmac';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts different types to Uint8Array.
|
* Converts different types to Uint8Array.
|
||||||
|
@ -84,3 +85,20 @@ export const verifyKey = (
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a payload from GitHub against its signature and secret
|
||||||
|
*/
|
||||||
|
export const verifyGithubKey = (
|
||||||
|
body: string,
|
||||||
|
signature: string,
|
||||||
|
secret: string
|
||||||
|
): boolean => {
|
||||||
|
if (!body || !signature || !secret) return false;
|
||||||
|
|
||||||
|
const githubWebhooksSecret = new TextEncoder().encode(secret);
|
||||||
|
const sha256 = `sha256=${createHmac('sha256', githubWebhooksSecret).update(body).digest('hex')}`;
|
||||||
|
if (sha256 !== signature) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in a new issue