Skip to content

Commit

Permalink
Channel Archiver
Browse files Browse the repository at this point in the history
### Notes
This WIP PR focuses on building a channel archiver function into Valkyrie. So that you can easily dump channel logs from a specific channel at point of archive.

Due to Discord APIs message rate limit of 100 messages, we run a loop depending on the total number of messages in the channel, then combine into a file which is sent back to the channel.

### WIP
This is just the initial test setup of this, some things we need to add still are:

- Better storage for the archival message file (dotenv is temp)
- Message headers specifying date of archive, channel name, etc
- Permission flags, access to archive
- Introduction of a command, valkyrie interface, etc
  • Loading branch information
zuuring committed Apr 10, 2024
1 parent 15a23ec commit 653294e
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
80 changes: 80 additions & 0 deletions discord-scripts/channel-management.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Robot } from "hubot"
import {
Client,
AttachmentBuilder,
TextChannel,
Message,
Collection,
} from "discord.js"
import { writeFile, unlink } from "fs/promises"
import dotenv from "dotenv"

dotenv.config()

async function fetchAllMessages(
channel: TextChannel,
before?: string,
): Promise<Collection<string, Message<true>>> {
const limit = 100
const options = before ? { limit, before } : { limit }
const fetchedMessages = await channel.messages.fetch(options)

if (fetchedMessages.size === 0) {
return new Collection<string, Message<true>>()
}

const lastId = fetchedMessages.lastKey()
const olderMessages = await fetchAllMessages(channel, lastId)

return new Collection<string, Message<true>>().concat(
fetchedMessages,
olderMessages,
)
}

export default async function archiveChannel(
discordClient: Client,
robot: Robot,
) {
const { application } = discordClient

if (application) {
// Dump all messages from a channel into an array after "!archive"
discordClient.on("messageCreate", async (message) => {
if (
message.content.toLowerCase() === "!archive" &&
message.channel instanceof TextChannel
) {
try {
const allMessages = await fetchAllMessages(message.channel)

robot.logger.info(`Total messages fetched: ${allMessages.size}`)

const messagesArray = Array.from(allMessages.values()).reverse()
const messagesContent = messagesArray
.map(
(m) =>
`${m.createdAt.toLocaleString()}: ${m.author.username}: ${
m.content
}`,
)
.join("\n")

const filePath = "./messages.txt"
await writeFile(filePath, messagesContent, "utf-8")

const fileAttachment = new AttachmentBuilder(filePath)
await message.channel
.send({
content: "Here are the archived messages:",
files: [fileAttachment],
})
.then(() => unlink(filePath))
.catch(robot.logger.error)
} catch (error) {
robot.logger.error(`An error occurred: ${error}`)
}
}
})
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"cronstrue": "^1.68.0",
"decode-html": "^2.0.0",
"discord.js": "^14.8.0",
"dotenv": "^16.4.5",
"express": "^4.18.2",
"figma-api": "^1.11.0",
"github-api": "^3.4.0",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2363,6 +2363,11 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"

dotenv@^16.4.5:
version "16.4.5"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==

double-ended-queue@^2.1.0-0:
version "2.1.0-0"
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
Expand Down

0 comments on commit 653294e

Please sign in to comment.