Add github webhook and mapping
This commit is contained in:
@@ -2,6 +2,7 @@ DISCORD_TOKEN=
|
|||||||
DISCORD_CLIENT_SECRET=
|
DISCORD_CLIENT_SECRET=
|
||||||
DISCORD_CLIENT_ID=
|
DISCORD_CLIENT_ID=
|
||||||
DISCORD_GUILD_ID=
|
DISCORD_GUILD_ID=
|
||||||
|
RELEASE_SECRET=
|
||||||
LINK_SECRET=super_secret_for_url_discord
|
LINK_SECRET=super_secret_for_url_discord
|
||||||
E621_BASE_URL=https://e621.net
|
E621_BASE_URL=https://e621.net
|
||||||
E926_BASE_URL=https://e926.net
|
E926_BASE_URL=https://e926.net
|
||||||
|
|||||||
Generated
+2
@@ -6,6 +6,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redis/client": "^5.1.0",
|
"@redis/client": "^5.1.0",
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
"discord-oauth2": "^2.12.1",
|
"discord-oauth2": "^2.12.1",
|
||||||
"discord.js": "^14.19.3",
|
"discord.js": "^14.19.3",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
@@ -1792,6 +1793,7 @@
|
|||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||||
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
"content-type": "^1.0.5",
|
"content-type": "^1.0.5",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redis/client": "^5.1.0",
|
"@redis/client": "^5.1.0",
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
"discord-oauth2": "^2.12.1",
|
"discord-oauth2": "^2.12.1",
|
||||||
"discord.js": "^14.19.3",
|
"discord.js": "^14.19.3",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import { ApplicationIntegrationType, BitFieldResolvable, ChatInputCommandInteraction, Client, GuildBasedChannel, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||||
|
import { channelIsInStaffCategory, handleWhoIsInteraction } from '../utils';
|
||||||
|
import { Database } from '../shared/Database';
|
||||||
|
|
||||||
|
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'github-mapping',
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('github-mapping')
|
||||||
|
.setDescription('Maps github users to discord ids for releases.')
|
||||||
|
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||||
|
.setContexts(InteractionContextType.Guild)
|
||||||
|
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('add')
|
||||||
|
.setDescription('Add a user mapping.')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName('discord-user')
|
||||||
|
.setDescription('The discord user id, or mention, of the user.')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName('github-name')
|
||||||
|
.setDescription('The github username of the user (case sensitive).')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('remove')
|
||||||
|
.setDescription('Remove a user mapping.')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName('discord-user')
|
||||||
|
.setDescription('The discord user id, or mention, of the user.')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('list')
|
||||||
|
.setDescription('List all github-discord mappings.')
|
||||||
|
),
|
||||||
|
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||||
|
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||||
|
|
||||||
|
const subcommand = await interaction.options.getSubcommand(true);
|
||||||
|
|
||||||
|
if (subcommand == 'add') {
|
||||||
|
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||||
|
|
||||||
|
const matches = mentionRegex.exec(discordUserInput);
|
||||||
|
mentionRegex.lastIndex = 0;
|
||||||
|
|
||||||
|
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||||
|
|
||||||
|
const githubName = interaction.options.getString('github-name', true);
|
||||||
|
|
||||||
|
const existingMappingId = await Database.getGithubFromDiscordId(idToUse);
|
||||||
|
const existingMappingName = await Database.getDiscordIdFromGithub(githubName);
|
||||||
|
|
||||||
|
if (existingMappingId) return interaction.editReply(`Discord user id is already mapped to ${existingMappingId}`);
|
||||||
|
if (existingMappingName) return interaction.editReply(`Github username is already mapped to <@${existingMappingName}> (${existingMappingName})`);
|
||||||
|
|
||||||
|
Database.putGithubUserMapping(idToUse, githubName);
|
||||||
|
|
||||||
|
return interaction.editReply('Mapping added.');
|
||||||
|
} else if (subcommand == 'remove') {
|
||||||
|
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||||
|
|
||||||
|
const matches = mentionRegex.exec(discordUserInput);
|
||||||
|
mentionRegex.lastIndex = 0;
|
||||||
|
|
||||||
|
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||||
|
|
||||||
|
Database.removeGithubUserMapping(idToUse);
|
||||||
|
return interaction.editReply('Mapping removed.');
|
||||||
|
} else if (subcommand == 'list') {
|
||||||
|
const allMappings = await Database.getAllGithubUserMappings();
|
||||||
|
|
||||||
|
return interaction.editReply(allMappings.map(m => `- <@${m.discord_id}> (${m.discord_id}) - ${m.github_username}`).join('\n'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -93,6 +93,12 @@ export default {
|
|||||||
.setName('remove-link-skip-channel')
|
.setName('remove-link-skip-channel')
|
||||||
.setDescription('Remove a link skip channel.')
|
.setDescription('Remove a link skip channel.')
|
||||||
.setRequired(false)
|
.setRequired(false)
|
||||||
|
)
|
||||||
|
.addChannelOption(option =>
|
||||||
|
option
|
||||||
|
.setName('github-release-channel')
|
||||||
|
.setDescription('Set the github release channel.')
|
||||||
|
.setRequired(false)
|
||||||
),
|
),
|
||||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||||
@@ -241,6 +247,14 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const githubReleaseChannel = interaction.options.getChannel('github-release-channel');
|
||||||
|
|
||||||
|
if (githubReleaseChannel) {
|
||||||
|
await Database.setGuildGithubReleaseChannel(interaction.guildId!, githubReleaseChannel.id);
|
||||||
|
|
||||||
|
response += `Github releases channel set to ${githubReleaseChannel}.\n`;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.length == 0) return interaction.editReply({ content: 'No settings provided.' });
|
if (response.length == 0) return interaction.editReply({ content: 'No settings provided.' });
|
||||||
|
|
||||||
interaction.editReply({ content: response });
|
interaction.editReply({ content: response });
|
||||||
|
|||||||
+2
-1
@@ -2,13 +2,14 @@ import dotenv from 'dotenv';
|
|||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_GUILD_ID, LINK_SECRET, E621_BASE_URL, E926_BASE_URL, REDIS_URL, PORT } = process.env;
|
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_GUILD_ID, RELEASE_SECRET, LINK_SECRET, E621_BASE_URL, E926_BASE_URL, REDIS_URL, PORT } = process.env;
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
DISCORD_TOKEN,
|
DISCORD_TOKEN,
|
||||||
DISCORD_CLIENT_ID,
|
DISCORD_CLIENT_ID,
|
||||||
DISCORD_CLIENT_SECRET,
|
DISCORD_CLIENT_SECRET,
|
||||||
DISCORD_GUILD_ID,
|
DISCORD_GUILD_ID,
|
||||||
|
RELEASE_SECRET,
|
||||||
LINK_SECRET,
|
LINK_SECRET,
|
||||||
E621_BASE_URL,
|
E621_BASE_URL,
|
||||||
E926_BASE_URL,
|
E926_BASE_URL,
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import { Client as DiscordClient, GatewayIntentBits, Guild, MessageFlags, Partia
|
|||||||
import { config } from './config';
|
import { config } from './config';
|
||||||
import { Handler } from './types';
|
import { Handler } from './types';
|
||||||
import { checkExpiredBans, initIfNecessary, loadHandlersFrom, refreshCommands } from './utils';
|
import { checkExpiredBans, initIfNecessary, loadHandlersFrom, refreshCommands } from './utils';
|
||||||
import { initializeDiscordJoiner } from './discord-joiner';
|
import { initializeWebserver } from './webserver';
|
||||||
import { Database } from './shared/Database';
|
import { Database } from './shared/Database';
|
||||||
import { handleAuditLogCreate, handleBanRemove, handleBulkMessageDelete, handleGuildCreate, handleMemberJoin, handleMessageCreate, handleMessageDelete, handleMessageUpdate, handleThreadCreate, handleVoiceStateUpdate } from './events';
|
import { handleAuditLogCreate, handleBanRemove, handleBulkMessageDelete, handleGuildCreate, handleMemberJoin, handleMessageCreate, handleMessageDelete, handleMessageUpdate, handleThreadCreate, handleVoiceStateUpdate } from './events';
|
||||||
import { pruneOldTickets, ticketCooldownMap } from './shared/ticket-cooldown';
|
import { pruneOldTickets, ticketCooldownMap } from './shared/ticket-cooldown';
|
||||||
@@ -135,7 +135,7 @@ client.on('ready', async () => {
|
|||||||
await Database.open('./data/discord-main.db');
|
await Database.open('./data/discord-main.db');
|
||||||
await openRedisClient(config.REDIS_URL!, client);
|
await openRedisClient(config.REDIS_URL!, client);
|
||||||
|
|
||||||
await initializeDiscordJoiner();
|
await initializeWebserver(client);
|
||||||
|
|
||||||
// Prune ticket cooldowns that are expired every day
|
// Prune ticket cooldowns that are expired every day
|
||||||
setInterval(pruneOldTickets, 8.64e+7);
|
setInterval(pruneOldTickets, 8.64e+7);
|
||||||
|
|||||||
+42
-2
@@ -3,7 +3,7 @@ import { open, Database as SqliteDatabase } from 'sqlite';
|
|||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
import DiscordOAuth2 from 'discord-oauth2';
|
import DiscordOAuth2 from 'discord-oauth2';
|
||||||
import { serializeMessage, wait } from '../utils';
|
import { serializeMessage, wait } from '../utils';
|
||||||
import { GuildSettings, LoggedMessage, TicketMessage, TicketPhrase, Note, Ban, GuildArraySetting } from '../types';
|
import { GuildSettings, LoggedMessage, TicketMessage, TicketPhrase, Note, Ban, GuildArraySetting, GithubUserMapping } from '../types';
|
||||||
import { Message } from '../events';
|
import { Message } from '../events';
|
||||||
|
|
||||||
const DB_SCHEMA = `
|
const DB_SCHEMA = `
|
||||||
@@ -27,7 +27,8 @@ const DB_SCHEMA = `
|
|||||||
private_help_role_id TEXT,
|
private_help_role_id TEXT,
|
||||||
staff_categories TEXT,
|
staff_categories TEXT,
|
||||||
safe_channels TEXT,
|
safe_channels TEXT,
|
||||||
link_skip_channels TEXT
|
link_skip_channels TEXT,
|
||||||
|
github_release_channel TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS messages (
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
@@ -68,6 +69,12 @@ const DB_SCHEMA = `
|
|||||||
user_id TEXT,
|
user_id TEXT,
|
||||||
expires_at datetime
|
expires_at datetime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS github_user_mapping (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
discord_id TEXT,
|
||||||
|
github_username TEXT
|
||||||
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export class Database {
|
export class Database {
|
||||||
@@ -167,6 +174,10 @@ export class Database {
|
|||||||
await Database.db.run('UPDATE settings SET private_help_role_id = ? WHERE guild_id = ?', id, guildId);
|
await Database.db.run('UPDATE settings SET private_help_role_id = ? WHERE guild_id = ?', id, guildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async setGuildGithubReleaseChannel(guildId: string, id: string) {
|
||||||
|
await Database.db.run('UPDATE settings SET github_release_channel = ? WHERE guild_id = ?', id, guildId);
|
||||||
|
}
|
||||||
|
|
||||||
// Since "setting" has guaranteed values and is never set by the user, this shouldn't cause any security issues.
|
// Since "setting" has guaranteed values and is never set by the user, this shouldn't cause any security issues.
|
||||||
// But it does allow me to skip rewriting this a bunch.
|
// But it does allow me to skip rewriting this a bunch.
|
||||||
static async getGuildArraySetting(setting: GuildArraySetting, guildId: string): Promise<string[]> {
|
static async getGuildArraySetting(setting: GuildArraySetting, guildId: string): Promise<string[]> {
|
||||||
@@ -322,4 +333,33 @@ export class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -- END BANS --
|
// -- END BANS --
|
||||||
|
|
||||||
|
// -- START GITHUB USER MAPPING --
|
||||||
|
|
||||||
|
// github_user_mapping
|
||||||
|
static async putGithubUserMapping(discordId: string, githubUsername: string) {
|
||||||
|
await Database.db.run('INSERT INTO github_user_mapping(discord_id, github_username) VALUES (?, ?)', discordId, githubUsername);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getDiscordIdFromGithub(githubUsername: string): Promise<string | null> {
|
||||||
|
const mapping = await Database.db.get<Pick<GithubUserMapping, 'discord_id'>>('SELECT discord_id FROM github_user_mapping WHERE github_username = ?', githubUsername);
|
||||||
|
|
||||||
|
return mapping?.discord_id ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getGithubFromDiscordId(discordId: string): Promise<string | null> {
|
||||||
|
const mapping = await Database.db.get<Pick<GithubUserMapping, 'github_username'>>('SELECT github_username FROM github_user_mapping WHERE discord_id = ?', discordId);
|
||||||
|
|
||||||
|
return mapping?.github_username ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getAllGithubUserMappings(): Promise<GithubUserMapping[]> {
|
||||||
|
return await Database.db.all<GithubUserMapping[]>('SELECT * from github_user_mapping');
|
||||||
|
}
|
||||||
|
|
||||||
|
static async removeGithubUserMapping(discordId: string) {
|
||||||
|
await Database.db.run('DELETE from github_user_mapping WHERE discord_id = ?', discordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- END GITHUB USER MAPPING --
|
||||||
}
|
}
|
||||||
Vendored
+7
@@ -21,6 +21,7 @@ export type GuildSettings = {
|
|||||||
staff_categories?: string
|
staff_categories?: string
|
||||||
safe_channels?: string
|
safe_channels?: string
|
||||||
link_skip_channels?: string
|
link_skip_channels?: string
|
||||||
|
github_release_channel?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GuildArraySetting = 'staff_categories' | 'safe_channels' | 'link_skip_channels';
|
export type GuildArraySetting = 'staff_categories' | 'safe_channels' | 'link_skip_channels';
|
||||||
@@ -48,4 +49,10 @@ export type Ban = {
|
|||||||
id: number
|
id: number
|
||||||
user_id: string
|
user_id: string
|
||||||
expires_at: string
|
expires_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GithubUserMapping = {
|
||||||
|
id: number
|
||||||
|
discord_id: string
|
||||||
|
github_username: string
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Database } from '../shared/Database';
|
||||||
|
|
||||||
|
const mentionRegex = new RegExp('@([\\S]+)', 'gi');
|
||||||
|
|
||||||
|
export async function fixPings(body: string): Promise<string> {
|
||||||
|
const mappings = await Database.getAllGithubUserMappings();
|
||||||
|
|
||||||
|
return body.replaceAll(mentionRegex, (match, username) => {
|
||||||
|
const mapping = mappings.find(m => m.github_username == username);
|
||||||
|
|
||||||
|
return mapping ? `<@${mapping.discord_id}>` : match;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -7,6 +7,9 @@ import session from 'express-session';
|
|||||||
import MemoryStore from 'memorystore';
|
import MemoryStore from 'memorystore';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { Client } from 'discord.js';
|
||||||
|
import bodyParser from 'body-parser';
|
||||||
|
import { fixPings } from '../utils/github-user-utils';
|
||||||
|
|
||||||
declare module 'express-session' {
|
declare module 'express-session' {
|
||||||
interface SessionData {
|
interface SessionData {
|
||||||
@@ -15,6 +18,7 @@ declare module 'express-session' {
|
|||||||
oauthState: string;
|
oauthState: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const GITHUB_REPO_ID = 852534222;//169334303;
|
||||||
|
|
||||||
const DEV_BASE_URL = `http://localhost:${config.PORT}`;
|
const DEV_BASE_URL = `http://localhost:${config.PORT}`;
|
||||||
const PROD_BASE_URL = 'https://discord.e621.net';
|
const PROD_BASE_URL = 'https://discord.e621.net';
|
||||||
@@ -72,7 +76,7 @@ async function handleInitial(req: Request, res: Response): Promise<any> {
|
|||||||
|
|
||||||
const digest = crypto.createHash('sha256').update(authString).digest('hex');
|
const digest = crypto.createHash('sha256').update(authString).digest('hex');
|
||||||
|
|
||||||
if (hash != digest) {
|
if (hash !== digest) {
|
||||||
console.error(`Bad auth: ${hash} ${digest}`);
|
console.error(`Bad auth: ${hash} ${digest}`);
|
||||||
return sendForbidden(res, 'Bad auth');
|
return sendForbidden(res, 'Bad auth');
|
||||||
}
|
}
|
||||||
@@ -147,7 +151,38 @@ function render(res: Response, code: number, title: string = '', message: string
|
|||||||
res.status(code).setHeader('Content-Type', 'text/html').send(PAGE_TEMPLATE.replaceAll('{{ title }}', title).replaceAll('{{ message }}', message));
|
res.status(code).setHeader('Content-Type', 'text/html').send(PAGE_TEMPLATE.replaceAll('{{ title }}', title).replaceAll('{{ message }}', message));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initializeDiscordJoiner() {
|
async function handleGithubRelease(client: Client, req: Request, res: Response): Promise<any> {
|
||||||
|
const signature = (req.headers['x-hub-signature-256'] as string).split('=')[1];
|
||||||
|
const computedSignature = crypto.createHmac('sha256', config.RELEASE_SECRET!).update(req.body).digest('hex');
|
||||||
|
|
||||||
|
if (signature !== computedSignature) {
|
||||||
|
return res.sendStatus(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.sendStatus(200);
|
||||||
|
|
||||||
|
const data = JSON.parse(req.body);
|
||||||
|
if (data.action != 'published' || data.repository.id != GITHUB_REPO_ID) return;
|
||||||
|
|
||||||
|
const settings = await Database.getGuildSettings(config.DISCORD_GUILD_ID!);
|
||||||
|
|
||||||
|
if (!settings || !settings.github_release_channel) return;
|
||||||
|
|
||||||
|
const channel = await client.channels.fetch(settings.github_release_channel);
|
||||||
|
|
||||||
|
if (!channel || !channel.isSendable()) return;
|
||||||
|
|
||||||
|
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
const message = `## [${months[date.getUTCMonth()]} ${date.getUTCDate()}, ${date.getUTCFullYear()}](<${data.release.html_url}>)\n\n${await fixPings(data.release.body)}`;
|
||||||
|
|
||||||
|
const sentMessage = await channel.send(message);
|
||||||
|
await sentMessage.startThread({ name: data.release.tag_name });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initializeWebserver(client: Client) {
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
const Store = MemoryStore(session);
|
const Store = MemoryStore(session);
|
||||||
@@ -172,6 +207,9 @@ export function initializeDiscordJoiner() {
|
|||||||
app.get('/', handleInitial);
|
app.get('/', handleInitial);
|
||||||
app.get('/callback', handleCallback);
|
app.get('/callback', handleCallback);
|
||||||
|
|
||||||
|
app.use(bodyParser.raw({ type: 'application/json' }));
|
||||||
|
app.post('/release', handleGithubRelease.bind(null, client));
|
||||||
|
|
||||||
app.listen(config.PORT, (error) => {
|
app.listen(config.PORT, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
throw error;
|
throw error;
|
||||||
Reference in New Issue
Block a user