-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(discord-bot): Implement Discord Bot Prototype #468
Open
PongDev
wants to merge
14
commits into
beta
Choose a base branch
from
PongDev-Leo/discord-bot
base: beta
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
517dc4c
Initialize Discord Bot Apps
PongDev e6ab576
Add discord.js package
PongDev c68d72f
Scaffolding Discord Bot
PongDev 980d6b0
Implement Ping-Pong
PongDev e6c4005
Implement Basic Database with SQLite
PongDev 15b4d6a
Add Scheduler to Send Message At Specific Time
PongDev eee2558
Add Google Analytic Data API
PongDev bda7fa5
fix: possible crash due to un-awaited save
saengowp 87c8541
remove deploy stage in action
bombnp 5372002
fix gened section data
bombnp f9f6a5c
Add Image Report
PongDev b6461ae
fix: merge commit
PongDev 2cb0093
refactor: as recommended by comment
PongDev 8811d82
refactor: rename hook type file from hook.ts to type.ts
PongDev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,9 @@ | ||
DISCORD_TOKEN= | ||
DISCORD_CLIENT_ID= | ||
|
||
# GOOGLE API | ||
GA4_PROPERTY_ID= | ||
GOOGLE_APPLICATION_CREDENTIALS=./google_application_credentials.json | ||
|
||
# Database | ||
DATABASE_CONNECTION_URL=database.sqlite |
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,18 @@ | ||
{ | ||
"extends": ["../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
} | ||
] | ||
} | ||
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 @@ | ||
.env |
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 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: 'discord-bot', | ||
preset: '../../jest.preset.js', | ||
globals: { | ||
'ts-jest': { | ||
tsconfig: '<rootDir>/tsconfig.spec.json', | ||
}, | ||
}, | ||
testEnvironment: 'node', | ||
transform: { | ||
'^.+\\.[tj]s$': 'ts-jest', | ||
}, | ||
moduleFileExtensions: ['ts', 'js', 'html'], | ||
coverageDirectory: '../../coverage/apps/discord-bot', | ||
} |
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,72 @@ | ||
{ | ||
"name": "discord-bot", | ||
"$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
"sourceRoot": "apps/discord-bot/src", | ||
"projectType": "application", | ||
"targets": { | ||
"build": { | ||
"executor": "@nrwl/webpack:webpack", | ||
"outputs": ["{options.outputPath}"], | ||
"options": { | ||
"target": "node", | ||
"compiler": "tsc", | ||
"outputPath": "dist/apps/discord-bot", | ||
"main": "apps/discord-bot/src/main.ts", | ||
"tsConfig": "apps/discord-bot/tsconfig.app.json" | ||
}, | ||
"configurations": { | ||
"production": { | ||
"optimization": true, | ||
"extractLicenses": true, | ||
"inspect": false, | ||
"fileReplacements": [ | ||
{ | ||
"replace": "apps/discord-bot/src/environments/environment.ts", | ||
"with": "apps/discord-bot/src/environments/environment.prod.ts" | ||
} | ||
] | ||
} | ||
} | ||
}, | ||
"serve": { | ||
"executor": "@nrwl/js:node", | ||
"options": { | ||
"buildTarget": "discord-bot:build" | ||
}, | ||
"configurations": { | ||
"production": { | ||
"buildTarget": "discord-bot:build:production" | ||
} | ||
} | ||
}, | ||
"deploy-commands": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"command": "ts-node --project ./apps/discord-bot/tsconfig.app.json ./apps/discord-bot/src/deploy-commands.ts" | ||
} | ||
}, | ||
"prisma-migrate-dev": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"command": "cd {args.db} && npx prisma migrate dev", | ||
"cwd": "apps/discord-bot/src/database" | ||
} | ||
}, | ||
"lint": { | ||
"executor": "@nrwl/linter:eslint", | ||
"outputs": ["{options.outputFile}"], | ||
"options": { | ||
"lintFilePatterns": ["apps/discord-bot/**/*.ts"] | ||
} | ||
}, | ||
"test": { | ||
"executor": "@nrwl/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], | ||
"options": { | ||
"jestConfig": "apps/discord-bot/jest.config.ts", | ||
"passWithNoTests": true | ||
} | ||
} | ||
}, | ||
"tags": [] | ||
} |
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,9 @@ | ||
import { ChatInputApplicationCommandData, ChatInputCommandInteraction, Client } from 'discord.js' | ||
|
||
import { CUGetReg } from '../core/CUGetReg' | ||
|
||
export interface ICommand extends ChatInputApplicationCommandData { | ||
readonly name: string | ||
readonly description: string | ||
execute: (client: CUGetReg, interaction: ChatInputCommandInteraction) => void | ||
} |
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 { ICommand } from './ICommand' | ||
import { PingCommand } from './ping' | ||
import { RegisterReportChannelCommand } from './registerReportChannel' | ||
|
||
export const commands: ICommand[] = [PingCommand, RegisterReportChannelCommand] |
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,12 @@ | ||
import { ChatInputCommandInteraction, Client } from 'discord.js' | ||
|
||
import { CUGetReg } from '../core/CUGetReg' | ||
import { ICommand } from './ICommand' | ||
|
||
export const PingCommand: ICommand = { | ||
name: 'ping', | ||
description: 'Replies with Pong!', | ||
execute: (client: CUGetReg, interaction: ChatInputCommandInteraction): void => { | ||
interaction.reply('Pong!') | ||
}, | ||
} |
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,14 @@ | ||
import { ChatInputCommandInteraction } from 'discord.js' | ||
|
||
import { CUGetReg } from '../core/CUGetReg' | ||
import { ICommand } from './ICommand' | ||
|
||
export const RegisterReportChannelCommand: ICommand = { | ||
name: 'register_report_channel', | ||
description: 'channel to receive reports', | ||
execute: async (client: CUGetReg, interaction: ChatInputCommandInteraction): Promise<void> => { | ||
await client.db.saveRegisterReportChannel(interaction.guildId, interaction.channelId) | ||
|
||
interaction.reply('Channel Registered!') | ||
}, | ||
} |
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 @@ | ||
export interface Configuration { | ||
discord: { | ||
token: string | ||
clientID: string | ||
} | ||
googleAnalytics: { | ||
GA4_PROPERTY_ID: string | ||
} | ||
database: { | ||
connectionURL: string | ||
} | ||
} | ||
|
||
export const configuration: Configuration = { | ||
discord: { | ||
token: process.env.DISCORD_TOKEN, | ||
clientID: process.env.DISCORD_CLIENT_ID, | ||
}, | ||
googleAnalytics: { | ||
GA4_PROPERTY_ID: process.env.GA4_PROPERTY_ID, | ||
}, | ||
database: { | ||
connectionURL: process.env.DATABASE_CONNECTION_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,61 @@ | ||
import { AttachmentBuilder, Client, GatewayIntentBits, TextChannel } from 'discord.js' | ||
import * as cron from 'node-cron' | ||
|
||
import { commands } from '../command' | ||
import { ICommand } from '../command/ICommand' | ||
import { database } from '../database' | ||
import { IDatabase } from '../database/IDatabase' | ||
import { hooks } from '../hook' | ||
import { HookFunction } from '../hook/type' | ||
import { scheduler } from '../scheduler' | ||
import { IScheduler } from '../scheduler/IScheduler' | ||
|
||
export class CUGetReg extends Client { | ||
private _commandList = new Map<string, ICommand>() | ||
private _database: IDatabase = database | ||
|
||
constructor(token: string) { | ||
super({ intents: [GatewayIntentBits.Guilds] }) | ||
this.login(token) | ||
this.addHook(hooks) | ||
this.registerCommand(commands) | ||
this.registerScheduler(scheduler) | ||
} | ||
|
||
addHook(hookFunctions: HookFunction[]): void { | ||
hookFunctions.forEach((hookFunction) => hookFunction(this)) | ||
} | ||
|
||
registerCommand(commands: ICommand[]): void { | ||
commands.forEach((command) => { | ||
this._commandList.set(command.name, command) | ||
}) | ||
} | ||
|
||
registerScheduler(schedulers: IScheduler[]) { | ||
schedulers.forEach((scheduler) => { | ||
cron.schedule(scheduler.cronTime, () => scheduler.callbackFunction(this)) | ||
}) | ||
} | ||
|
||
sendMessage(channelID: string, message: string): void { | ||
const textChannel = this.channels.cache.get(channelID) as TextChannel | ||
|
||
textChannel.send(message) | ||
} | ||
|
||
sendImage(channelID: string, imgBuffer: Buffer): void { | ||
const textChannel = this.channels.cache.get(channelID) as TextChannel | ||
const attachment = new AttachmentBuilder(imgBuffer) | ||
|
||
textChannel.send({ files: [attachment] }) | ||
} | ||
|
||
get commands(): Map<string, ICommand> { | ||
return this._commandList | ||
} | ||
|
||
get db(): IDatabase { | ||
return this._database | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same goes here |
||
} | ||
} |
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 @@ | ||
export interface IDatabase { | ||
saveRegisterReportChannel(guildId: string, channelId: string): Promise<void> | ||
getRegisterReportChannel(guildId: string): Promise<string[]> | ||
getAllReportChannels(): Promise<Map<string, 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 @@ | ||
import { IDatabase } from './IDatabase' | ||
import { SQLiteDatabaseDriver } from './sqlite/SQLiteDatabaseDriver' | ||
|
||
export const database: IDatabase = new SQLiteDatabaseDriver() |
55 changes: 55 additions & 0 deletions
55
apps/discord-bot/src/database/sqlite/SQLiteDatabaseDriver.ts
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,55 @@ | ||
import { open } from 'sqlite' | ||
import * as sqlite3 from 'sqlite3' | ||
|
||
import { configuration } from '../../config' | ||
import { IDatabase } from '../IDatabase' | ||
|
||
const DB_FILE_NAME = configuration.database.connectionURL | ||
|
||
type ReportChannel = { | ||
guild_id?: string | ||
channel_id: string | ||
} | ||
|
||
export class SQLiteDatabaseDriver implements IDatabase { | ||
constructor() { | ||
new sqlite3.Database(DB_FILE_NAME).run( | ||
'CREATE TABLE IF NOT EXISTS register_report_channel (channel_id TEXT PRIMARY KEY, guild_id TEXT)' | ||
) | ||
} | ||
|
||
async openDB() { | ||
return open({ | ||
driver: sqlite3.Database, | ||
filename: DB_FILE_NAME, | ||
}) | ||
} | ||
|
||
async saveRegisterReportChannel(guildId: string, channelId: string): Promise<void> { | ||
const database = await this.openDB() | ||
|
||
await database.run(`INSERT INTO register_report_channel VALUES ('${channelId}', '${guildId}')`) | ||
return | ||
} | ||
|
||
async getRegisterReportChannel(guildId: string): Promise<string[]> { | ||
const database = await this.openDB() | ||
|
||
const result: ReportChannel[] = await database.all( | ||
`SELECT channel_id FROM register_report_channel WHERE guild_id = '${guildId}'` | ||
) | ||
return result.map((obj: ReportChannel) => { | ||
return obj.channel_id | ||
}) | ||
} | ||
|
||
async getAllReportChannels(): Promise<Map<string, string>> { | ||
const database = await this.openDB() | ||
|
||
const result = await database.all(`SELECT * FROM register_report_channel`) | ||
return result.reduce((map: Map<string, string>, obj: ReportChannel) => { | ||
map.set(obj.guild_id, obj.channel_id) | ||
return map | ||
}, new Map<string, 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,29 @@ | ||
import { REST, Routes, SlashCommandBuilder } from 'discord.js' | ||
|
||
import { commands as CUGetRegCommands } from './command' | ||
import { configuration as config } from './config' | ||
|
||
const commands = CUGetRegCommands.map((command) => { | ||
return new SlashCommandBuilder() | ||
.setName(command.name) | ||
.setDescription(command.description) | ||
.toJSON() | ||
}) | ||
|
||
const rest = new REST({ version: '10' }).setToken(config.discord.token) | ||
|
||
;(async () => { | ||
try { | ||
console.log(`Started refreshing ${commands.length} application (/) commands.`) | ||
|
||
const data = Array( | ||
await rest.put(Routes.applicationCommands(config.discord.clientID), { | ||
body: commands, | ||
}) | ||
) | ||
|
||
console.log(`Successfully reloaded ${data.length} application (/) commands.`) | ||
} catch (error) { | ||
console.error(error) | ||
} | ||
})() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this file here for? doesn't this literally ignore every error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is copy from apps/api/.eslintrc.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you recommend how I should lint this apps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saenyakorn did u add this in api?