Skip to content

add upload photos context menu command #28

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

Open
wants to merge 4 commits into
base: v2
Choose a base branch
from
Open

add upload photos context menu command #28

wants to merge 4 commits into from

Conversation

ktm19
Copy link

@ktm19 ktm19 commented Mar 25, 2025

This feature allows users to right click a Discord message, click an "upload photos" button, and upload the photo attachments of that message to a Google Drive folder (the folder should be shared with the service account's email and the folder id should be specified in uploadphotos.js).

Copy link
Member

@burturt burturt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start! Just some suggested changes.

@@ -6,12 +6,19 @@ A Discord bot made for ACM Cyber & Psi Beta Rho. :)
0. Install Node and make sure corepack is enabled (`corepack enable`).
1. Download and copy `.env.example` as `.env`
2. Run `pnpm install` to install dependencies
3. Either ask me for your own discord bot user OR Create your own discord bot application: https://discordjs.guide/preparations/setting-up-a-bot-application.html
4. [Invite your discord bot to our shared testing discord server](https://discordjs.guide/preparations/adding-your-bot-to-servers.html#creating-and-using-your-invite-link). If you need admin, let me (Alec) know.
3. Either ask me (Alec or Andrew) for your own discord bot user OR Create your own discord bot application: https://discordjs.guide/preparations/setting-up-a-bot-application.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably avoid hard-coded names here - maybe like "the infrastructure lead?"


let auth = await authorize()
const drive = google.drive({ version: "v3", auth })
const folderId = "[FOLDER ID]" // replace this with the id of the desired folder (the part of the url after "folders/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we should not hardcode config values - use an environment variable instead, which can be set in the .env file


export const data = new ContextMenuCommandBuilder().setName("upload photos").setType(ApplicationCommandType.Message)

export async function execute(interaction) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit dangerous to allow anyone to run - I would recommend adding a check to only allow those with Administrator permission (basically the officers) as otherwise anyone could cause the bot to download arbitrary files into our disk and then into drive.

await fs.promises.unlink(filePath)
count++
} catch (error) {
console.error(`Failed to process file ${value["name"]}:`, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an error occurs, we could be left with the file in our file system. I would recommend adding the fs.promises.unlink call inside of a finally clause.

let auth = await authorize()
const drive = google.drive({ version: "v3", auth })
const folderId = "[FOLDER ID]" // replace this with the id of the desired folder (the part of the url after "folders/")
const downloadDir = path.join(import.meta.dirname, "..", "downloads")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't want to save the files, we should probably save the files in a temporary directory, which can be created using tmpdir() + mkdtemp()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, you can look at streaming the data directly, which is probably the more ideal solution though it'll be a bit harder to get working - create a file read stream pointing to the remote attachment download url and stream it to Google Drive. Something like https://stackoverflow.com/questions/65976322/how-to-create-a-readable-stream-from-a-remote-url-in-nodejs would probably work - you might have to play around a bit.

await fs.promises.unlink(filePath)
count++
} catch (error) {
console.error(`Failed to process file ${value["name"]}:`, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we could send the list of files that failed to upload to the user?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants