-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from cancng/master
discord bot
- Loading branch information
Showing
23 changed files
with
1,759 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module.exports = { | ||
env: { | ||
es2021: true, | ||
node: true, | ||
}, | ||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], | ||
parser: "@typescript-eslint/parser", | ||
parserOptions: { | ||
ecmaVersion: "latest", | ||
sourceType: "module", | ||
}, | ||
plugins: ["@typescript-eslint"], | ||
rules: { | ||
"@typescript-eslint/no-explicit-any": "off", | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# Cu.Yemekhane.Bot.Discord | ||
|
||
## Invite URL | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "cu-yemekhane-bot-discord", | ||
"version": "1.0.0", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "ts-node-dev --tree-kill --no-notify --respawn --exit-child src/index.ts", | ||
"start": "node dist/index", | ||
"clean": "rm -rf dist", | ||
"build": "npm -s run clean && tsc" | ||
}, | ||
"dependencies": { | ||
"@discordjs/builders": "^0.12.0", | ||
"@discordjs/rest": "^0.3.0", | ||
"app-root-path": "^3.0.0", | ||
"axios": "^0.26.1", | ||
"dayjs": "^1.10.8", | ||
"discord-api-types": "^0.29.0", | ||
"discord.js": "^13.6.0", | ||
"dotenv": "^16.0.0", | ||
"glob": "^7.2.0" | ||
}, | ||
"devDependencies": { | ||
"@types/app-root-path": "^1.2.4", | ||
"@types/glob": "^7.2.0", | ||
"@types/node": "^17.0.21", | ||
"@typescript-eslint/eslint-plugin": "^5.14.0", | ||
"@typescript-eslint/parser": "^5.14.0", | ||
"eslint": "^8.11.0", | ||
"ts-node": "^10.7.0", | ||
"ts-node-dev": "^1.1.8", | ||
"typescript": "^4.6.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import axios from "axios"; | ||
|
||
export const api = axios.create({ | ||
baseURL: "https://cu-yemekhane.herokuapp.com", | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { EmbedFieldData, MessageEmbed } from "discord.js"; | ||
import { api } from "../../api"; | ||
import { Command } from "../../structure/Command"; | ||
import { IMenuApiResponse } from "../../types/menu"; | ||
|
||
export default new Command({ | ||
name: "menu", | ||
description: "Shows specific date's menu", | ||
options: [ | ||
{ | ||
name: "target_date", | ||
description: "DD.MM.YYYY specific date format", | ||
required: true, | ||
type: "STRING", | ||
}, | ||
], | ||
run: async ({ interaction, client, args }) => { | ||
const specifiedDate = args.data[0].value; | ||
|
||
if (!specifiedDate) { | ||
return interaction.followUp( | ||
"Please give valid date. Example Format: 23.03.2022" | ||
); | ||
} | ||
|
||
try { | ||
const res = await api.get<IMenuApiResponse>(`/Menu/${specifiedDate}`); | ||
|
||
const mappedFoods: EmbedFieldData[] = res.data.data.foods.map((food) => ({ | ||
name: "Food", | ||
value: `${food.name} - ${food.calories.toString()} kalori`, | ||
})); | ||
|
||
const exampleEmbed = new MessageEmbed() | ||
.setTitle(`Menu ${res.data.data.date}`) | ||
.setURL("https://yemekhane.cu.edu.tr") | ||
.setThumbnail( | ||
client.user?.avatarURL() || | ||
"https://www.cu.edu.tr/storage/anamenu_icerikleri/May2018/cukurova_logo.png" | ||
) | ||
.addFields(...mappedFoods) | ||
.setTimestamp(); | ||
|
||
return interaction.followUp({ | ||
embeds: [exampleEmbed], | ||
}); | ||
} catch (error) { | ||
console.log("err :", error.message); | ||
return interaction.followUp("Menu not found"); | ||
} | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { EmbedFieldData, MessageEmbed } from "discord.js"; | ||
import dayjs from "dayjs"; | ||
import { api } from "../../api"; | ||
import { Command } from "../../structure/Command"; | ||
import { IMenuApiResponse } from "../../types/menu"; | ||
|
||
export default new Command({ | ||
name: "menu_today", | ||
description: "Shows today's menu", | ||
run: async ({ interaction, client }) => { | ||
const res = await api.get<IMenuApiResponse>( | ||
`/Menu/${dayjs().format("DD.MM.YYYY")}` | ||
); | ||
|
||
const mappedFoods: EmbedFieldData[] = res.data.data.foods.map((food) => ({ | ||
name: "Food", | ||
value: `${food.name} - ${food.calories.toString()} kalori`, | ||
})); | ||
|
||
const exampleEmbed = new MessageEmbed() | ||
.setTitle(`Menu ${res.data.data.date}`) | ||
.setURL("https://yemekhane.cu.edu.tr") | ||
.setThumbnail( | ||
client.user?.avatarURL() || | ||
"https://www.cu.edu.tr/storage/anamenu_icerikleri/May2018/cukurova_logo.png" | ||
) | ||
.addFields(...mappedFoods) | ||
.setTimestamp(); | ||
|
||
await interaction.followUp({ | ||
embeds: [exampleEmbed], | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { EmbedFieldData, MessageEmbed } from "discord.js"; | ||
import dayjs from "dayjs"; | ||
import { api } from "../../api"; | ||
import { Command } from "../../structure/Command"; | ||
import { IMenuApiResponse } from "../../types/menu"; | ||
|
||
export default new Command({ | ||
name: "menu_tomorrow", | ||
description: "Shows tomorrow's menu", | ||
run: async ({ interaction, client }) => { | ||
const res = await api.get<IMenuApiResponse>( | ||
`/Menu/${dayjs().add(1, "days").format("DD.MM.YYYY")}` | ||
); | ||
|
||
const mappedFoods: EmbedFieldData[] = res.data.data.foods.map((food) => ({ | ||
name: "Food", | ||
value: `${food.name} - ${food.calories.toString()} kalori`, | ||
})); | ||
|
||
const exampleEmbed = new MessageEmbed() | ||
.setTitle(`Menu ${res.data.data.date}`) | ||
.setURL("https://yemekhane.cu.edu.tr") | ||
.setThumbnail( | ||
client.user?.avatarURL() || | ||
"https://www.cu.edu.tr/storage/anamenu_icerikleri/May2018/cukurova_logo.png" | ||
) | ||
.addFields(...mappedFoods) | ||
.setTimestamp(); | ||
|
||
await interaction.followUp({ | ||
embeds: [exampleEmbed], | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { CommandInteractionOptionResolver } from "discord.js"; | ||
import { client } from ".."; | ||
import { ExtendedInteraction } from "../types/Command"; | ||
import { Event } from "../structure/Event"; | ||
|
||
export default new Event("interactionCreate", async (interaction) => { | ||
// Chat Input Commands | ||
if (interaction.isCommand()) { | ||
await interaction.deferReply(); | ||
const command = client.commands.get(interaction.commandName); | ||
if (!command) | ||
return interaction.followUp("You have used a non existent command"); | ||
|
||
return command.run({ | ||
args: interaction.options as CommandInteractionOptionResolver, | ||
client, | ||
interaction: interaction as ExtendedInteraction, | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Event } from "../structure/Event"; | ||
|
||
export default new Event("ready", () => { | ||
console.log("Bot is online"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import "dotenv/config"; | ||
import DiscordClient from "./structure/DiscordClient"; | ||
|
||
export const client = new DiscordClient(); | ||
|
||
client.start(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { CommandType } from "../types/Command"; | ||
|
||
export class Command { | ||
constructor(commandOptions: CommandType) { | ||
Object.assign(this, commandOptions); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { | ||
ApplicationCommandDataResolvable, | ||
Client, | ||
ClientEvents, | ||
Collection, | ||
Intents, | ||
} from "discord.js"; | ||
import glob from "glob"; | ||
import { promisify } from "util"; | ||
import { RegisterCommandsOptions } from "../types/client"; | ||
import { CommandType } from "../types/Command"; | ||
import { Event } from "./Event"; | ||
|
||
const globPromise = promisify(glob); | ||
|
||
class DiscordClient extends Client { | ||
commands: Collection<string, any> = new Collection(); | ||
|
||
constructor() { | ||
if (!process.env.DISCORD_BOT_TOKEN) { | ||
throw new Error("DISCORD_BOT_TOKEN must be defined"); | ||
} | ||
super({ intents: [Intents.FLAGS.GUILDS] }); | ||
} | ||
|
||
start() { | ||
this.login(process.env.DISCORD_BOT_TOKEN); | ||
this.registerModules(); | ||
} | ||
|
||
async importFile(filePath: string) { | ||
return (await import(filePath))?.default; | ||
} | ||
|
||
async registerCommands({ commands, guildId }: RegisterCommandsOptions) { | ||
if (guildId) { | ||
this.guilds.cache.get(guildId)?.commands.set(commands); | ||
console.log(`Registering commands to ${guildId}`); | ||
} else { | ||
this.application?.commands.set(commands); | ||
console.log("Registering global commands"); | ||
} | ||
} | ||
|
||
async registerModules() { | ||
const slashCommands: ApplicationCommandDataResolvable[] = []; | ||
const commandFiles = await globPromise( | ||
`${__dirname}/../commands/*/*{.ts,.js}` | ||
); | ||
commandFiles.forEach(async (filePath) => { | ||
const command: CommandType = await this.importFile(filePath); | ||
if (!command.name) return; | ||
console.log(command); | ||
|
||
this.commands.set(command.name, command); | ||
slashCommands.push(command); | ||
}); | ||
|
||
this.on("ready", () => { | ||
console.log("Bot is ready"); | ||
}); | ||
|
||
this.on("guildCreate", (guild) => { | ||
this.registerCommands({ | ||
commands: slashCommands, | ||
guildId: guild.id, | ||
}); | ||
}); | ||
|
||
// Event | ||
const eventFiles = await globPromise(`${__dirname}/../events/*{.ts,.js}`); | ||
eventFiles.forEach(async (filePath) => { | ||
const event: Event<keyof ClientEvents> = await this.importFile(filePath); | ||
this.on(event.event, event.run); | ||
}); | ||
} | ||
} | ||
|
||
export default DiscordClient; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { ClientEvents } from "discord.js"; | ||
|
||
export class Event<Key extends keyof ClientEvents> { | ||
constructor( | ||
public event: Key, | ||
public run: (...args: ClientEvents[Key]) => any | ||
) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { | ||
ChatInputApplicationCommandData, | ||
CommandInteraction, | ||
CommandInteractionOptionResolver, | ||
GuildMember, | ||
PermissionResolvable, | ||
} from "discord.js"; | ||
import DiscordClient from "../structure/DiscordClient"; | ||
|
||
export interface ExtendedInteraction extends CommandInteraction { | ||
member: GuildMember; | ||
} | ||
|
||
interface RunOptions { | ||
client: DiscordClient; | ||
interaction: ExtendedInteraction; | ||
args: CommandInteractionOptionResolver; | ||
} | ||
|
||
type RunFunction = (options: RunOptions) => any; | ||
|
||
export type CommandType = { | ||
userPermissions?: PermissionResolvable[]; | ||
run: RunFunction; | ||
} & ChatInputApplicationCommandData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { ApplicationCommandDataResolvable } from "discord.js"; | ||
|
||
export interface RegisterCommandsOptions { | ||
guildId?: string; | ||
commands: ApplicationCommandDataResolvable[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
declare namespace NodeJS { | ||
export interface ProcessEnv extends NodeJS.ProcessEnv { | ||
NODE_ENV?: "development" | "production"; | ||
DISCORD_BOT_TOKEN: string; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface IFood { | ||
name: string; | ||
calories: number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { IFood } from "./food"; | ||
|
||
export interface IMenu { | ||
date: string; | ||
foods: IFood[]; | ||
totalCalories: number; | ||
detail: string; | ||
} | ||
|
||
export interface IMenuApiResponse { | ||
success: boolean; | ||
errorMessage: string | null; | ||
data: IMenu; | ||
} | ||
|
||
export interface IMenuListApiResponse { | ||
success: boolean; | ||
errorMessage: string | null; | ||
data: IMenu[]; | ||
} |
Oops, something went wrong.