Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions server/api/services/discord/discord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as dotenv from "dotenv";
import { instanceDiscordAPI } from "../index";

import { ApplicationConfigs, ApplicationCommandParams } from "./interfaces";

// Get the bot's (Application Configurations)
const getApplicationConfigs = async () => {
try {
const applicationResponse = await instanceDiscordAPI.get(
"/applications/@me"
);

return applicationResponse.data;
} catch (error) {
console.error("Error pulling Application Configurations." + error);
}
};

// Update the bot's (Application Configurations)
const updateApplicationConfig = async (data: ApplicationConfigs) => {
try {
const applicationResponse = await instanceDiscordAPI.patch(
"/applications/@me",
data
);

return applicationResponse.data;
} catch (error) {
console.error("Error pulling Application Configurations." + error);
}
};

// Get the Guild Application Commands
const getGuildApplicationCommands = async (applicationId: string) => {
try {
// Assuming we will hard code the guild Id (server)... Making this dynamic for dealing with other guilds(Servers)
const guildId = process.env.discord_bot_guild_id;
const applicationCommands = await instanceDiscordAPI.get(
`applications/${applicationId}/guilds/${guildId}/commands`
);

return applicationCommands.data;
} catch (error) {
console.error("Error pulling Guild Application Commands." + error);
}
};

// Resources:
// https://autocode.com/guides/how-to-build-a-discord-bot/
// Create a Guild Application Command
const createGuildApplicationCommands = async (
applicationId: string,
data: ApplicationCommandParams
) => {
try {
const guildId = process.env.discord_bot_guild_id;
const response = await instanceDiscordAPI.post(
`applications/${applicationId}/guilds/${guildId}/commands`,
data
);

return response.data;
} catch (error) {
console.error("Error creating Guild Application Command " + error);
}
};

// Update a Guild Application Command
const updateGuildApplicationCommands = async (
applicationId: string,
commandId: string,
data: ApplicationCommandParams
) => {
try {
const guildId = process.env.discord_bot_guild_id;
const response = await instanceDiscordAPI.patch(
`applications/${applicationId}/guilds/${guildId}/commands/${commandId}`,
data
);

return response.data;
} catch (error) {
console.error("Error updating Guild Application Command " + error);
}
};

// Delete a Guild Application Command
const deleteGuildApplicationCommands = async (
applicationId: string,
commandId: string
) => {
try {
const guildId = process.env.discord_bot_guild_id;
const response = await instanceDiscordAPI.delete(
`applications/${applicationId}/guilds/${guildId}/commands/${commandId}`
);

return response.data;
} catch (error) {
console.error("Error updating Guild Application Command " + error);
}
};
48 changes: 48 additions & 0 deletions server/api/services/discord/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export interface ApplicationConfigs {
custom_install_url?: string;
description?: string;
role_connections_verification_url?: string;
install_params?: InstallParams;
flags?: ApplicationFlags;
icon?: string;
cover_image?: string;
interactions_endpoint_url?: string;
tags?: string[];
}

export interface ApplicationCommandParams {
name: string;
name_localizations?: LocalizationDictionary;
description?: string;
description_localizations?: LocalizationDictionary;
options?: ApplicationCommandOption[];
default_member_permissions?: string | number;
default_permission?: boolean;
type?: ApplicationCommandType;
nsfw?: boolean;
}

interface InstallParams {
redirect_uri?: string;
scopes?: string[];
}

enum ApplicationFlags {
ExampleFlag = 1,
}

interface LocalizationDictionary {
[locale: string]: string;
}

enum ApplicationCommandType {
CHAT_INPUT = 1, // Slash commands
USER = 2, // User commands
MESSAGE = 3, // Message commands
}

interface ApplicationCommandOption {
type: string;
name: string;
description: string;
}
13 changes: 13 additions & 0 deletions server/api/services/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import axios from "axios";
import * as dotenv from "dotenv";
dotenv.config();

export const instanceDiscordAPI = axios.create({
baseURL: "https://discord.com/api/v10",
timeout: 3000,
headers: {
"User-Agent": `DiscordBot (https://discord.com/api/v10, 10)`,
Authorization: `Bot ${process.env.discord_bot_token}`,
"Content-Type": "application/json",
},
});
5 changes: 3 additions & 2 deletions server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
Imports from Node.js and other libraries defined in package.json
*/
import * as dotenv from "dotenv";
import "dotenv/config";
dotenv.config({ path: "../.env" });
// import "dotenv/config";
// dotenv.config({ path: "../.env" });
dotenv.config();
import createError from "http-errors";
import express, { NextFunction } from "express";
import path from "path";
Expand Down
124 changes: 71 additions & 53 deletions server/commands/change-bot-discord-information.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,80 @@ import { SlashCommandBuilder } from "discord.js";
import BotRepository from "../database/MongoDB/BotRepository";
import IDiscordBotInformation from "../database/MongoDB/IDiscordBotInformation";

export default function() {
const change_bot_discord_information_object: Object = {
data: new SlashCommandBuilder()
.setName(`change-bot-information`)
.setDescription(`Use this command to change the Discord information that is associated with the bot`)
.addStringOption(options =>
options.setName(`bot-command-channel-id`)
.setDescription(`(Optional) command channel id`)
.setRequired(false)
)
.addStringOption(options =>
options.setName(`bot-database-responses-channel`)
.setDescription(`(Optional) database responses channel id`)
.setRequired(false)
)
.addStringOption(options =>
options.setName(`bot-github-responses-channel`)
.setDescription(`(Optional) github commits responses channel id`)
.setRequired(false)
)
.addStringOption(options =>
options.setName(`bot-information-messages-channel`)
.setDescription(`(Optional) command usage information messages channel id`)
.setRequired(false)
)
.addStringOption(options =>
options.setName(`bot-information-errors-channel`)
.setDescription(`(Optional) command usage error message channel id`)
.setRequired(false)
),
export default function () {
const change_bot_discord_information_object: Object = {
data: new SlashCommandBuilder()
.setName(`change-bot-information`)
.setDescription(
`Use this command to change the Discord information that is associated with the bot`
)
.addStringOption((options) =>
options
.setName(`bot-command-channel-id`)
.setDescription(`(Optional) command channel id`)
.setRequired(false)
)
.addStringOption((options) =>
options
.setName(`bot-database-responses-channel`)
.setDescription(`(Optional) database responses channel id`)
.setRequired(false)
)
.addStringOption((options) =>
options
.setName(`bot-github-responses-channel`)
.setDescription(`(Optional) github commits responses channel id`)
.setRequired(false)
)
.addStringOption((options) =>
options
.setName(`bot-information-messages-channel`)
.setDescription(
`(Optional) command usage information messages channel id`
)
.setRequired(false)
)
.addStringOption((options) =>
options
.setName(`bot-information-errors-channel`)
.setDescription(`(Optional) command usage error message channel id`)
.setRequired(false)
),

authorization_role_name: ["Discord admin"],
authorization_role_name: ["Discord admin"],

async execute(interaction) {
const bot_repository: BotRepository = new BotRepository();
/*
async execute(interaction) {
const bot_repository: BotRepository = new BotRepository();
/*
Falsy values do not need to be checked for, because the upsert function that is used to update the Discord bot data
will not replace the existing value in the database with a falsy value.
*/
const bot_repository_discord_data: IDiscordBotInformation = {
bot_commands_channel_id: interaction.options.getString('bot-command-channel-id'),
bot_database_responses_channel_id: interaction.options.getString('bot-database-responses-channel'),
bot_github_commits_channel_id: interaction.options.getString('bot-github-responses-channel'),
bot_command_usage_information_channel_id: interaction.options.getString('bot-information-messages-channel'),
bot_command_usage_errors_channel_id: interaction.options.getString('bot-information-errors-channel')
};

try {
await bot_repository.createBot(bot_repository_discord_data);
await interaction.reply({ content: `The Discord data in the MongoDB database has been updated`, ephemeral: true});
} catch (error) {
await interaction.reply({ content: `There was an error when attempting to insert the updated Discord channel data to the database. Please inform the server administrator of this error: ${error}`});
throw error;
}
}
}
const bot_repository_discord_data: any = {
bot_commands_channel_id: interaction.options.getString(
"bot-command-channel-id"
),
bot_command_usage_information_channel_id: interaction.options.getString(
"bot-information-messages-channel"
),
bot_command_usage_errors_channel_id: interaction.options.getString(
"bot-information-errors-channel"
),
};

return change_bot_discord_information_object;
}
try {
await bot_repository.createBot(bot_repository_discord_data);
await interaction.reply({
content: `The Discord data in the MongoDB database has been updated`,
ephemeral: true,
});
} catch (error) {
await interaction.reply({
content: `There was an error when attempting to insert the updated Discord channel data to the database. Please inform the server administrator of this error: ${error}`,
});
throw error;
}
},
};

return change_bot_discord_information_object;
}
22 changes: 11 additions & 11 deletions server/database/MongoDB/IDiscordBotInformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import { UUID } from "crypto";

/**
* Implemented an interface to represent the data object that will be passed to the createBot database function in the BotRepository class.
* This interface defines all of the properties that exist for that object.
* This interface defines all of the properties that exist for that object.
*/
export default interface IDiscordBotInformation {
bot_id?: UUID;
bot_username?: string;
bot_password?: string;
bot_email?: string;
bot_guild_id?: string;
bot_commands_channel_id?: string;
bot_button_channel_id?: string;
bot_command_usage_information_channel_id?: string;
bot_command_usage_errors_channel_id?: string;
}
bot_id?: UUID;
bot_username?: string;
bot_password?: string;
bot_email?: string;
bot_commands_channel_id: string;
bot_database_responses_channel_id: string;
bot_github_commits_channel_id: string;
bot_command_usage_information_channel_id: string;
bot_command_usage_errors_channel_id: string;
}