diff --git a/breadbot_test.db b/breadbot_test.db index c7e3fc3..5dbfce2 100644 Binary files a/breadbot_test.db and b/breadbot_test.db differ diff --git a/src/breadbot.ts b/src/breadbot.ts index 2d7ab8f..c24cba1 100644 --- a/src/breadbot.ts +++ b/src/breadbot.ts @@ -8,7 +8,8 @@ export const client : Client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, - GatewayIntentBits.DirectMessages + GatewayIntentBits.GuildMembers, + GatewayIntentBits.MessageContent ] }) @@ -21,6 +22,9 @@ if (config.DB_MODE == "sqlite") { utilities.tables.makeTables(db) utilities.tables.makeConstraints(db) + + //I really don't want this to be here. + utilities.events.messages.setupMessageCapture(client, db) } client.once(Events.ClientReady, () => { @@ -58,4 +62,6 @@ client.on(Events.InteractionCreate, async (interaction: Interaction) => { } }) + + client.login(config.DISCORD_TOKEN) \ No newline at end of file diff --git a/src/utilties/discord/channels.ts b/src/utilties/discord/channels.ts index ebc340f..af6b482 100644 --- a/src/utilties/discord/channels.ts +++ b/src/utilties/discord/channels.ts @@ -1,17 +1,26 @@ import { SQLCommon } from "../storage/interfaces"; -import { GuildBasedChannel } from "discord.js"; +import { DMChannel, GuildBasedChannel, PartialDMChannel } from "discord.js"; import { SQLResult } from "../storage/enumerations"; -export async function doesChannelExist(db: SQLCommon, channel : GuildBasedChannel) : Promise { +export async function doesChannelExistByID(db: SQLCommon, channelID: string) : Promise { const queryResult : Object[] = await db.getAllParameterized( - "SELECT * FROM channels WHERE server_snowflake = ? AND channel_snowflake = ?", - [channel.guild.id, channel.id] + "SELECT * FROM channels WHERE channel_snowflake = ?", + [channelID] ) return queryResult.length != 0 } -export async function insertChannel(db: SQLCommon, channel: GuildBasedChannel) : Promise { +export async function doesChannelExist(db: SQLCommon, channel : GuildBasedChannel | DMChannel | PartialDMChannel) : Promise { + const queryResult : Object[] = await db.getAllParameterized( + "SELECT * FROM channels WHERE channel_snowflake = ?", + [channel.id] + ) + + return queryResult.length != 0 +} + +export async function insertChannel(db: SQLCommon, channel: GuildBasedChannel | DMChannel | PartialDMChannel) : Promise { const alreadyExists: boolean = await doesChannelExist(db, channel) if(alreadyExists) { @@ -19,10 +28,18 @@ export async function insertChannel(db: SQLCommon, channel: GuildBasedChannel) : } try { - await db.runParameterized( - "INSERT INTO channels VALUES (?, ?, ?, ?)", - [channel.id, channel.guild.id, channel.name, channel.isThread()] - ) + if (channel.isDMBased()) { + await db.runParameterized( + "INSERT INTO channels VALUES (?, ?, ?, ?, ?)", + [channel.id, null, channel.recipient?.username, channel.isThread(), channel.isDMBased()] + ) + } else { + await db.runParameterized( + "INSERT INTO channels VALUES (?, ?, ?, ?, ?)", + [channel.id, channel.guild.id, channel.name, channel.isThread(), channel.isDMBased()] + ) + } + return SQLResult.CREATED } catch (err) { diff --git a/src/utilties/discord/messages.ts b/src/utilties/discord/messages.ts new file mode 100644 index 0000000..fe01049 --- /dev/null +++ b/src/utilties/discord/messages.ts @@ -0,0 +1,34 @@ +import { Message, OmitPartialGroupDMChannel } from "discord.js"; +import { SQLCommon } from "../storage/interfaces"; +import { SQLResult } from "../storage/enumerations"; + +export async function doesMessageExist(db: SQLCommon, message: OmitPartialGroupDMChannel>) : Promise { + const queryResult: Object[] = await db.getAllParameterized( + "SELECT * FROM messages WHERE message_snowflake = ?", + [message.id] + ) + + return queryResult.length != 0 +} + +export async function insertMessage(db: SQLCommon, message: OmitPartialGroupDMChannel>) : Promise { + const alreadyExists: boolean = await doesMessageExist(db, message) + + if(alreadyExists) { + return SQLResult.ALREADYEXISTS + } + + try { + await db.runParameterized( + "INSERT INTO messages VALUES (?, ?, ?, ?, ?, ?)", + [message.id, message.channel.id, message.author.id, + message.content, message.createdTimestamp, 0] + ) + + return SQLResult.CREATED + } catch (err) { + //TODO Winston should handle this + console.log(err) + return SQLResult.FAILED + } +} \ No newline at end of file diff --git a/src/utilties/discord/users.ts b/src/utilties/discord/users.ts new file mode 100644 index 0000000..c8a0694 --- /dev/null +++ b/src/utilties/discord/users.ts @@ -0,0 +1,33 @@ +import { User } from "discord.js"; +import { SQLCommon } from "../storage/interfaces"; +import { SQLResult } from "../storage/enumerations"; + +export async function doesUserExist(db: SQLCommon, user: User): Promise { + const queryResult: Object[] = await db.getAllParameterized( + "SELECT * FROM users WHERE user_snowflake = ?", + [user.id] + ) + + return queryResult.length != 0 +} + +export async function insertUser(db: SQLCommon, user: User): Promise { + const alreadyExists: boolean = await doesUserExist(db, user) + + if(alreadyExists) { + return SQLResult.ALREADYEXISTS + } + + try { + await db.runParameterized( + "INSERT INTO users VALUES (?, ?, ?)", + [user.id, user.username, user.displayName] + ) + + return SQLResult.CREATED + } catch (err) { + //TODO Winston should handle this + console.log(err) + return SQLResult.FAILED + } +} \ No newline at end of file diff --git a/src/utilties/events/messages.ts b/src/utilties/events/messages.ts new file mode 100644 index 0000000..d9ed299 --- /dev/null +++ b/src/utilties/events/messages.ts @@ -0,0 +1,23 @@ +import { Client, Events, Message, OmitPartialGroupDMChannel } from "discord.js"; +import { SQLResult } from "../storage/enumerations"; +import { SQLCommon } from "../storage/interfaces"; +import { insertChannel } from "../discord/channels"; +import { insertUser } from "../discord/users"; +import { insertMessage } from "../discord/messages"; + +export function setupMessageCapture(client: Client, db: SQLCommon) { + client.on(Events.MessageCreate, async (message) => { + processMessageCreate(db, message) + }) +} + +async function processMessageCreate(db: SQLCommon, message: OmitPartialGroupDMChannel>) { + const channelOk: SQLResult = await insertChannel(db, message.channel) + const userOk: SQLResult = await insertUser(db, message.author) + + if (channelOk == SQLResult.ALREADYEXISTS || channelOk == SQLResult.CREATED || + userOk == SQLResult.ALREADYEXISTS || userOk == SQLResult.CREATED) { + + await insertMessage(db, message) + } +} \ No newline at end of file diff --git a/src/utilties/index.ts b/src/utilties/index.ts index 6f9e2ca..3c15413 100644 --- a/src/utilties/index.ts +++ b/src/utilties/index.ts @@ -3,11 +3,19 @@ import * as sqlite from "./storage/sqlite" import * as tables from "./storage/tables" import * as guilds from "./discord/guilds" import * as channels from "./discord/channels" +import * as users from "./discord/users" +import * as messages from "./events/messages" + +const events = { + messages +} export const utilities = { commands, sqlite, tables, guilds, - channels + channels, + users, + events } \ No newline at end of file diff --git a/src/utilties/storage/tables.ts b/src/utilties/storage/tables.ts index ddb07fb..1d87112 100644 --- a/src/utilties/storage/tables.ts +++ b/src/utilties/storage/tables.ts @@ -2,7 +2,8 @@ import { SQLCommon } from "./interfaces"; const tables: string[] = [ "CREATE TABLE IF NOT EXISTS servers (server_snowflake bigint NOT NULL PRIMARY KEY,server_name text NOT NULL,server_description mediumtext);", - "CREATE TABLE IF NOT EXISTS channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint NOT NULL,channel_name text NOT NULL,is_thread bit NOT NULL);", + "CREATE TABLE channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint,channel_name text,is_thread bit NOT NULL,is_dm bit NOT NULL);", + "CREATE TABLE users (user_snowflake bigint NOT NULL PRIMARY KEY,user_name text NOT NULL,user_displayname text);", "CREATE TABLE IF NOT EXISTS messages (message_snowflake bigint NOT NULL PRIMARY KEY,channel_snowflake bigint NOT NULL,user_snowflake bigint NOT NULL,message_content longtext NOT NULL,message_timestamp datetime NOT NULL,message_deleted bit NOT NULL);", "CREATE TABLE IF NOT EXISTS message_content_changes (message_change_id bigint NOT NULL PRIMARY KEY,message_snowflake bigint NOT NULL,message_change_old_timestamp datetime NOT NULL,message_change_old_content longtext NOT NULL);", "CREATE TABLE IF NOT EXISTS message_attachments (attachment_snowflake bigint NOT NULL PRIMARY KEY,message_snowflake bigint NOT NULL,attachment_name text NOT NULL,attachment_description text,attachment_timestamp datetime NOT NULL,attachment_mime_type text,attachment_url text NOT NULL,attachment_downloaded bit NOT NULL);"