A various number of fixes related to ensuring message content is captured, and adding downloading of attachments
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
media
|
||||||
breadbot.db
|
breadbot.db
|
||||||
.env
|
.env
|
||||||
tools/profanity_filter/bin/Words.json
|
tools/profanity_filter/bin/Words.json
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { DBCall } from "./utilties/storage/entities/DBCall"
|
|||||||
import { DBCallTranscriptions } from "./utilties/storage/entities/DBCallTranscriptions"
|
import { DBCallTranscriptions } from "./utilties/storage/entities/DBCallTranscriptions"
|
||||||
import { DBCallUsers } from "./utilties/storage/entities/DBCallUsers"
|
import { DBCallUsers } from "./utilties/storage/entities/DBCallUsers"
|
||||||
import { DBMessageRegex } from "./utilties/storage/entities/DBMessageRegex"
|
import { DBMessageRegex } from "./utilties/storage/entities/DBMessageRegex"
|
||||||
|
import { DBMessageRegexMatches } from "./utilties/storage/entities/DBMessageRegexMatches"
|
||||||
|
|
||||||
console.log(__dirname + path.sep + "utilities" + path.sep + "storage" + path.sep + "entities" + path.sep + "*.ts")
|
console.log(__dirname + path.sep + "utilities" + path.sep + "storage" + path.sep + "entities" + path.sep + "*.ts")
|
||||||
|
|
||||||
@@ -38,10 +39,11 @@ export const dataSource = new DataSource({
|
|||||||
DBCall,
|
DBCall,
|
||||||
DBCallTranscriptions,
|
DBCallTranscriptions,
|
||||||
DBCallUsers,
|
DBCallUsers,
|
||||||
DBMessageRegex
|
DBMessageRegex,
|
||||||
|
DBMessageRegexMatches
|
||||||
],
|
],
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
logging: true
|
logging: false
|
||||||
})
|
})
|
||||||
|
|
||||||
export const client : Client = new Client({
|
export const client : Client = new Client({
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import dotenv from "dotenv"
|
|||||||
|
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|
||||||
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DB_MODE, MEDIA_VOICE_FOLDER } = process.env
|
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DB_MODE, MEDIA_VOICE_FOLDER, MEDIA_ATTACHMENT_FOLDER } = process.env
|
||||||
|
|
||||||
if (!DISCORD_TOKEN || !DISCORD_CLIENT_ID || !DB_MODE || !MEDIA_VOICE_FOLDER) {
|
if (!DISCORD_TOKEN || !DISCORD_CLIENT_ID || !DB_MODE || !MEDIA_VOICE_FOLDER || !MEDIA_ATTACHMENT_FOLDER) {
|
||||||
throw new Error("Missing environment variables")
|
throw new Error("Missing environment variables")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,5 +12,6 @@ export const config = {
|
|||||||
DISCORD_TOKEN,
|
DISCORD_TOKEN,
|
||||||
DISCORD_CLIENT_ID,
|
DISCORD_CLIENT_ID,
|
||||||
DB_MODE,
|
DB_MODE,
|
||||||
MEDIA_VOICE_FOLDER
|
MEDIA_VOICE_FOLDER,
|
||||||
|
MEDIA_ATTACHMENT_FOLDER
|
||||||
}
|
}
|
||||||
@@ -68,6 +68,8 @@ export async function updateMessageContentHistory(messageDB: Repository<DBMessag
|
|||||||
dbMessage.message_content = message.content
|
dbMessage.message_content = message.content
|
||||||
dbMessage.message_timestamp = message.editedAt ?? message.createdAt
|
dbMessage.message_timestamp = message.editedAt ?? message.createdAt
|
||||||
|
|
||||||
|
console.log(dbMessage)
|
||||||
|
|
||||||
// TODO This should really be a transaction
|
// TODO This should really be a transaction
|
||||||
// TODO Changes to attachments aren't captured
|
// TODO Changes to attachments aren't captured
|
||||||
return await mccDB.save(contentChange).then(async (dbmcc: DBMessageContentChanges) => {
|
return await mccDB.save(contentChange).then(async (dbmcc: DBMessageContentChanges) => {
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ import { DBMessageContentChanges } from "../storage/entities/DBMessageContentCha
|
|||||||
import { DBMessageAttachments } from "../storage/entities/DBMessageAttachment";
|
import { DBMessageAttachments } from "../storage/entities/DBMessageAttachment";
|
||||||
import { DBChannel } from "../storage/entities/DBChannel";
|
import { DBChannel } from "../storage/entities/DBChannel";
|
||||||
import { DBUser } from "../storage/entities/DBUser";
|
import { DBUser } from "../storage/entities/DBUser";
|
||||||
|
import { mkdirSync, createWriteStream } from "fs";
|
||||||
|
import { config } from "../../config";
|
||||||
|
import path from "path";
|
||||||
|
import { Readable } from "stream"
|
||||||
|
import { finished } from "stream/promises";
|
||||||
|
|
||||||
export function setupMessageCapture(client: Client,
|
export function setupMessageCapture(client: Client,
|
||||||
channelDB: Repository<DBChannel>,
|
channelDB: Repository<DBChannel>,
|
||||||
@@ -17,16 +22,57 @@ export function setupMessageCapture(client: Client,
|
|||||||
maDB: Repository<DBMessageAttachments>
|
maDB: Repository<DBMessageAttachments>
|
||||||
) {
|
) {
|
||||||
client.on(Events.MessageCreate, async (message) => {
|
client.on(Events.MessageCreate, async (message) => {
|
||||||
|
console.log("MESSAGE CREATE")
|
||||||
await processMessageCreate(channelDB, userDB, messageDB, maDB, message)
|
await processMessageCreate(channelDB, userDB, messageDB, maDB, message)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on(Events.MessageUpdate, async (oldMessage, newMessage) => {
|
client.on(Events.MessageUpdate, async (oldMessage, newMessage) => {
|
||||||
|
console.log("MESSAGE EDITED")
|
||||||
|
console.log(`Old Message ID: ${oldMessage.id}`)
|
||||||
|
console.log(`New Message ID: ${newMessage.id}`)
|
||||||
await processMessageModify(messageDB, mccDB, maDB, newMessage)
|
await processMessageModify(messageDB, mccDB, maDB, newMessage)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on(Events.MessageDelete, async (deletedMessage) => {
|
client.on(Events.MessageDelete, async (deletedMessage) => {
|
||||||
await processMessageDeleted(messageDB, deletedMessage)
|
await processMessageDeleted(messageDB, deletedMessage)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
console.log("STARTING DOWNLOAD CYCLE")
|
||||||
|
mkdirSync(config.MEDIA_ATTACHMENT_FOLDER, {recursive: true})
|
||||||
|
|
||||||
|
let attachmentsToProcess: DBMessageAttachments[] | null = await maDB.find({
|
||||||
|
relations: {
|
||||||
|
message: true
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
attachment_downloaded: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (attachmentsToProcess != null) {
|
||||||
|
attachmentsToProcess.forEach(async (attachment: DBMessageAttachments) => {
|
||||||
|
|
||||||
|
mkdirSync(config.MEDIA_ATTACHMENT_FOLDER + path.sep + attachment.message.message_snowflake, {recursive: true})
|
||||||
|
|
||||||
|
const response = await fetch(attachment.attachment_url)
|
||||||
|
|
||||||
|
if (response.body !== null) {
|
||||||
|
const fileStream = createWriteStream(
|
||||||
|
config.MEDIA_ATTACHMENT_FOLDER + path.sep + attachment.message.message_snowflake +
|
||||||
|
path.sep + attachment.attachment_snowflake + '_' + attachment.attachment_name,
|
||||||
|
{ flags: "wx" }
|
||||||
|
)
|
||||||
|
|
||||||
|
await finished(Readable.fromWeb(response.body).pipe(fileStream))
|
||||||
|
|
||||||
|
attachment.attachment_downloaded = true
|
||||||
|
|
||||||
|
maDB.save(attachment)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 30000)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processMessageCreate(
|
async function processMessageCreate(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DBCall } from "./DBCall";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBChannel {
|
export class DBChannel {
|
||||||
@PrimaryColumn({type: "bigint"})
|
@PrimaryColumn({type: "text"})
|
||||||
channel_snowflake: string
|
channel_snowflake: string
|
||||||
|
|
||||||
@ManyToOne(() => DBServer, (server: DBServer) => server.channels, {nullable: true})
|
@ManyToOne(() => DBServer, (server: DBServer) => server.channels, {nullable: true})
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { DBMessageRegexMatches } from "./DBMessageRegexMatches";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBMessage {
|
export class DBMessage {
|
||||||
@PrimaryColumn({type: "bigint"})
|
@PrimaryColumn({type: "text"})
|
||||||
message_snowflake: string
|
message_snowflake: string
|
||||||
|
|
||||||
@ManyToOne(() => DBChannel, (channel: DBChannel) => channel.messages)
|
@ManyToOne(() => DBChannel, (channel: DBChannel) => channel.messages)
|
||||||
@@ -16,7 +16,7 @@ export class DBMessage {
|
|||||||
@ManyToOne(() => DBUser, (user: DBUser) => user.messages)
|
@ManyToOne(() => DBUser, (user: DBUser) => user.messages)
|
||||||
user: DBUser
|
user: DBUser
|
||||||
|
|
||||||
@Column({type: "longtext"})
|
@Column()
|
||||||
message_content: string
|
message_content: string
|
||||||
|
|
||||||
@Column({type: "datetime"})
|
@Column({type: "datetime"})
|
||||||
@@ -28,7 +28,7 @@ export class DBMessage {
|
|||||||
@OneToMany(() => DBMessageContentChanges, (mcc: DBMessageContentChanges) => mcc.message, {nullable: true})
|
@OneToMany(() => DBMessageContentChanges, (mcc: DBMessageContentChanges) => mcc.message, {nullable: true})
|
||||||
changes: DBMessageContentChanges[] | null
|
changes: DBMessageContentChanges[] | null
|
||||||
|
|
||||||
@OneToMany(() => DBMessageAttachments, (ma: DBMessageAttachments) => ma.attachment_snowflake, {nullable: true})
|
@OneToMany(() => DBMessageAttachments, (ma: DBMessageAttachments) => ma.attachment_snowflake, {nullable: true, cascade: true})
|
||||||
attachments: DBMessageAttachments[] | null
|
attachments: DBMessageAttachments[] | null
|
||||||
|
|
||||||
@OneToOne(() => DBMessageRegexMatches, (mrm: DBMessageRegexMatches) => mrm.message, {nullable: true})
|
@OneToOne(() => DBMessageRegexMatches, (mrm: DBMessageRegexMatches) => mrm.message, {nullable: true})
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { DBMessage } from "./DBMessage";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBMessageAttachments {
|
export class DBMessageAttachments {
|
||||||
@PrimaryColumn({"type": "bigint"})
|
@PrimaryColumn({"type": "text"})
|
||||||
attachment_snowflake: string
|
attachment_snowflake: string
|
||||||
|
|
||||||
@ManyToOne(() => DBMessage, (message: DBMessage) => message.attachments)
|
@ManyToOne(() => DBMessage, (message: DBMessage) => message.attachments)
|
||||||
@@ -12,18 +12,18 @@ export class DBMessageAttachments {
|
|||||||
@Column()
|
@Column()
|
||||||
attachment_name: string
|
attachment_name: string
|
||||||
|
|
||||||
@Column({nullable: true})
|
@Column({type: 'text', nullable: true})
|
||||||
attachment_description: string | null
|
attachment_description: string | null
|
||||||
|
|
||||||
@Column({type: "datetime"})
|
@Column({type: "datetime"})
|
||||||
attachment_timestamp: Date
|
attachment_timestamp: Date
|
||||||
|
|
||||||
@Column({nullable: true})
|
@Column({type: 'text', nullable: true})
|
||||||
attachment_mime_type: string | null
|
attachment_mime_type: string | null
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
attachment_url: string
|
attachment_url: string
|
||||||
|
|
||||||
@Column({default: false})
|
@Column({default: false})
|
||||||
attachment_download: boolean
|
attachment_downloaded: boolean
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,6 @@ export class DBMessageContentChanges {
|
|||||||
@Column({type: "datetime"})
|
@Column({type: "datetime"})
|
||||||
message_change_old_timestamp: Date
|
message_change_old_timestamp: Date
|
||||||
|
|
||||||
@Column({type: "longtext"})
|
@Column()
|
||||||
message_change_old_content: string
|
message_change_old_content: string
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import { DBServer } from "./DBServer";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBRole {
|
export class DBRole {
|
||||||
@PrimaryColumn({type: "bigint"})
|
@PrimaryColumn({type: "text"})
|
||||||
role_snowflake: string
|
role_snowflake: string
|
||||||
|
|
||||||
@ManyToOne(() => DBServer, (server: DBServer) => server.roles)
|
@ManyToOne(() => DBServer, (server: DBServer) => server.roles)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DBMessageRegex } from "./DBMessageRegex";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBServer {
|
export class DBServer {
|
||||||
@PrimaryColumn({type: "bigint"})
|
@PrimaryColumn({type: "text"})
|
||||||
server_snowflake: string
|
server_snowflake: string
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DBCallUsers } from "./DBCallUsers";
|
|||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class DBUser {
|
export class DBUser {
|
||||||
@PrimaryColumn({type: "bigint"})
|
@PrimaryColumn({type: "text"})
|
||||||
user_snowflake: string
|
user_snowflake: string
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
|
|||||||
Reference in New Issue
Block a user