From d512e1168219d67247cbcb6663791c1592475330 Mon Sep 17 00:00:00 2001 From: Aster Fialla Date: Sun, 15 Feb 2026 00:23:30 -0500 Subject: [PATCH] WIP import. sort of working except error handling and message is not, and can't convert images --- src/commands.js | 29 +++++++++++++++++++++++++++ src/enums.js | 4 +++- src/helpers/memberHelper.js | 5 ++--- src/import.js | 40 ++++++++++++++++++++++++------------- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/commands.js b/src/commands.js index da91762..19c0f59 100644 --- a/src/commands.js +++ b/src/commands.js @@ -2,6 +2,7 @@ import {messageHelper} from "./helpers/messageHelper.js"; import {enums} from "./enums.js"; import {memberHelper} from "./helpers/memberHelper.js"; import {EmbedBuilder} from "@fluxerjs/core"; +import {importHelper} from "./import.js"; const cmds = new Map(); @@ -39,4 +40,32 @@ cmds.set('help', { }, }) +cmds.set('import', { + description: enums.help.IMPORT, + async execute(message) { + try { + const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null; + + const successfullyAdded = importHelper.pluralKitImport(message.author.id, attachmentUrl); + console.log(successfullyAdded + "added"); + await message.reply(successfullyAdded); + } + catch(error) { + console.log(error.message) + if (error instanceof AggregateError) { + // errors.message can be a list of successfully added members, or say that none were successful. + let errorsText = `${error.message}.\nThese errors occurred: ${error.join('\n')}`; + await message.reply(errorsText); + } + // If just one error was returned. + else { + return await message.reply(error.message); + } + + + } + }, +}) + + export const commands = cmds; \ No newline at end of file diff --git a/src/enums.js b/src/enums.js index 48e2032..0fb5ebe 100644 --- a/src/enums.js +++ b/src/enums.js @@ -17,7 +17,8 @@ helperEnums.err = { NO_MESSAGE_SENT_WITH_PROXY: 'Proxied message has no content.', NO_TEXT_FOR_PROXY: "You need the word 'text' for the bot to detect proxy tags with.\nCorrect usage examples: `pf;member jane proxy J:text`, `pf;member jane [text]`", NO_PROXY_WRAPPER: "You need at least one proxy tag surrounding 'text', either before or after.\nCorrect usage examples: `pf;member jane proxy J:text`, `pf;member jane [text]`", - NOT_JSON: "Please attach a valid JSON file." + NOT_JSON_FILE: "Please attach a valid JSON file.", + NO_MEMBERS_IMPORTED: 'No members were imported.' } helperEnums.help = { @@ -32,6 +33,7 @@ helperEnums.help = { DISPLAY_NAME: "Updates the display name for a specific member based on their name, for example: `pf;member jane \"Jane Doe | ze/hir\"`.This can be up to 32 characters long. If it has spaces, put it in __double quotes__.", PROXY: "Updates the proxy tag for a specific member based on their name. The proxy must be formatted with the tags surrounding the word 'text', for example: `pf;member jane proxy Jane:text` or `pf;member amal proxy [text]` This is so the bot can detect what the proxy tags are.", PROPIC: "Updates the profile picture for the member. Must be in JPG or PNG format. The two options are:\n1. Pass in a direct remote image URL, for example: `pf;member jane propic `. You can upload images on sites like .\n2. Upload an attachment directly.\n\n**NOTE:** Fluxer does not save your attachments forever, so option #1 is recommended.", + IMPORT: "Imports from PluralKit using the JSON file provided by their export command. Importing from other proxy bots is TBD. `pf;import` and attach your JSON file to the message." } export const enums = helperEnums; \ No newline at end of file diff --git a/src/helpers/memberHelper.js b/src/helpers/memberHelper.js index 3f7a305..5de8f91 100644 --- a/src/helpers/memberHelper.js +++ b/src/helpers/memberHelper.js @@ -232,11 +232,11 @@ mh.removeMember = async function(authorId, args) { * @param {string | null} displayName - The display name of the member. * @param {string | null} proxy - The proxy tag of the member. * @param {string | null} propic - The profile picture URL of the member. - * @returns {Promise} A successful addition. + * @returns {Promise} A successful addition. * @throws {Error | RangeError} When the member already exists, there are validation errors, or adding a member doesn't work. */ mh.addFullMember = async function(authorId, memberName, displayName = null, proxy = null, propic= null) { - const member = await mh.getMemberByName(authorId, memberName).catch((e) =>{throw e}); + const member = await mh.getMemberByName(authorId, memberName).catch((e) =>{console.log("Now we can add the member.")}); if (member) { throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`); } @@ -322,7 +322,6 @@ mh.setExpirationWarning = function(expirationString) { */ mh.getMemberInfo = async function(authorId, memberName) { return await mh.getMemberByName(authorId, memberName).then((member) => { - console.log(member); return new EmbedBuilder() .setTitle(member.name) .setDescription(`Details for ${member.name}`) diff --git a/src/import.js b/src/import.js index 745bd80..d60af6e 100644 --- a/src/import.js +++ b/src/import.js @@ -6,24 +6,36 @@ const ih = {}; /** * Tries to import from Pluralkit. * + * @async * @param {string} authorId - The author of the message - * @param {string} attachment - The attached JSON url. - * @returns {string} A successful addition. + * @param {string} attachmentUrl - The attached JSON url. + * @returns {string} A successful addition of all members. * @throws {Error} When the member exists, or creating a member doesn't work. */ -ih.pluralKitImport = function (authorId, attachment) { - try { - const pkData = JSON.parse(attachment); - const pkMembers = pkData.members; - pkMembers.forEach(async(pkMember) => { - const proxy = `${pkMember.proxy_tags.prefix}text${pkMember.proxy_tags.suffix}`; - await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy, avatar_url); - }) - return "All members imported."; - } - catch { - throw new Error(enums.err.NOT_JSON); +ih.pluralKitImport = async function (authorId, attachmentUrl) { + if (!attachmentUrl) { + throw new Error(enums.err.NOT_JSON_FILE); } + return fetch(attachmentUrl).then((res) => res.json()).then(async(pkData) => { + const pkMembers = pkData.members; + const errors = []; + const addedMembers = []; + for (let pkMember of pkMembers) { + const proxy = pkMember.proxy_tags[0] ? `${pkMember.proxy_tags[0].prefix ?? ''}text${pkMember.proxy_tags[0].suffix ?? ''}` : null; + + // can't add profile pic until i figure out how to convert webp + await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy).then((member) => { + addedMembers.push(member.name); + }).catch(e => { + errors.push(`${pkMember.name}: ${e.message}`); + }); + } + const aggregatedText = addedMembers > 0 ? `Successfully added members: ${addedMembers.join(', ')}` : enums.err.NO_MEMBERS_IMPORTED; + if (errors.length > 0) { + throw new AggregateError(errors, aggregatedText); + } + return aggregatedText; + }); } export const importHelper = ih; \ No newline at end of file