forked from PluralFlux/PluralFlux
refactor: Removing then/catch from async/await calls (#22)
* refactored async/await for import helper to not also use then/catch * added enum * refactor webhookHelper and tests to not use then/catch * changed docstring * refactoring bot and tests to not use then/catch * refactoring commands.js and tests to not use then/catch * refactoring memberHelper.js and tests to not use then/catch * removing then/catch from messageHelper.test.js * fixed set up for commands tests * edited bot to have top level main function * one more test in commands.js, and removed console.error * fixed typo in webhookHelper * forgot to switch over some tests in bot.test and commands.test * removed console.log from import helper * put console.error in commands * converted utils.js to not use then/catch * tested utils checkImageFormatValidity * removed jest-fetch-mock since it turns out I was just manually mocking it anyway * refactored database to not use then/catch * added dash to commands.js and test to pass * added the remaining webhook tests * changed utils to check for 10MB size not 1MB * removed unnecessary try/catch from utils * Simplify getWebhook to use .find() instead of foreach logic * make memberCommand exit when error occurs with parseMemberCommand * changed commands.js to not have user interaction within the catch * updated console.error message in database.js * made importHelper mock throw error instead of "resolve" error * replaced "pk;" with "pf;" in test * Got rid of unnecessary check for empty message from user (Fluxer doesn't allow this to happen) Removed export of token * getAllMembersInfo checks for fields.length * added default case to memberCommandHandler to throw error if command is not recognized * reversed check for valid proxy (was returning valid if the proxy existed and invalid if it didn't) * pushes e.message instead of full error object to errors array in importHelper * adjusted tests to properly use mockRejectedValue for async rejections * changed getAllMembersInfo map to say `index` not `name` as it actually gets the index of a member and then the member object * adjusted importHelper to properly test throwing of aggregate error * revamped setting of expiration warning (moved to utils and changed logic, wrote tests) --------- Co-authored-by: Aster Fialla <asterfialla@gmail.com>
This commit is contained in:
@@ -9,35 +9,50 @@ const ih = {};
|
||||
* @async
|
||||
* @param {string} authorId - The author of the message
|
||||
* @param {string | null} [attachmentUrl] - The attached JSON url.
|
||||
* @returns {string} A successful addition of all members.
|
||||
* @returns {Promise<string>} A successful addition of all members.
|
||||
* @throws {Error} When the member exists, or creating a member doesn't work.
|
||||
*/
|
||||
ih.pluralKitImport = async function (authorId, attachmentUrl= null) {
|
||||
let fetchResult, pkData;
|
||||
if (!attachmentUrl) {
|
||||
throw new Error(enums.err.NOT_JSON_FILE);
|
||||
}
|
||||
return fetch(attachmentUrl).then((res) => res.json()).then(async(pkData) => {
|
||||
const pkMembers = pkData.members;
|
||||
let 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;
|
||||
await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy, pkMember.avatar_url).then((memberObj) => {
|
||||
addedMembers.push(memberObj.member.name);
|
||||
if (memberObj.errors.length > 0) {
|
||||
errors.push(`\n**${pkMember.name}:** `)
|
||||
errors = errors.concat(memberObj.errors);
|
||||
}
|
||||
}).catch(e => {
|
||||
errors.push(e.message);
|
||||
});
|
||||
try {
|
||||
fetchResult = await fetch(attachmentUrl);
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(enums.err.CANNOT_FETCH_RESOURCE, { cause: e });
|
||||
}
|
||||
|
||||
try {
|
||||
pkData = await fetchResult.json();
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(enums.err.NOT_JSON_FILE, { cause: e })
|
||||
}
|
||||
|
||||
const pkMembers = pkData.members;
|
||||
let errors = [];
|
||||
let addedMembers = [];
|
||||
for (let pkMember of pkMembers) {
|
||||
const proxy = pkMember.proxy_tags[0] ? `${pkMember.proxy_tags[0].prefix ?? ''}text${pkMember.proxy_tags[0].suffix ?? ''}` : null;
|
||||
try {
|
||||
const memberObj = await memberHelper.addFullMember(authorId, pkMember.name, pkMember.display_name, proxy, pkMember.avatar_url);
|
||||
addedMembers.push(memberObj.member.name);
|
||||
if (memberObj.errors.length > 0) {
|
||||
errors.push(`\n**${pkMember.name}:** `);
|
||||
errors = errors.concat(memberObj.errors);
|
||||
}
|
||||
const aggregatedText = addedMembers.length > 0 ? `Successfully added members: ${addedMembers.join(', ')}` : `${enums.err.NO_MEMBERS_IMPORTED}`;
|
||||
if (errors.length > 0) {
|
||||
throw new AggregateError(errors, aggregatedText);
|
||||
}
|
||||
return aggregatedText;
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
errors.push(e.message);
|
||||
}
|
||||
}
|
||||
const aggregatedText = addedMembers.length > 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;
|
||||
@@ -22,7 +22,6 @@ const newAndRemoveCommands = ['new', 'remove'];
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, string[], string}>} A member info embed + info/errors.
|
||||
* @throws {Error}
|
||||
*/
|
||||
mh.parseMemberCommand = async function (authorId, authorFull, args, attachmentUrl = null, attachmentExpiration = null) {
|
||||
let memberName, command, isHelp = false;
|
||||
@@ -72,7 +71,7 @@ mh.parseMemberCommand = async function (authorId, authorFull, args, attachmentUr
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors.
|
||||
* @throws {Error}
|
||||
* @throws {Error} When there's no member or a command is not recognized.
|
||||
*/
|
||||
mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command = null, memberName = null, args = [], attachmentUrl = null, attachmentExpiration = null) {
|
||||
if (!command && !memberName && !isHelp) {
|
||||
@@ -93,10 +92,10 @@ mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command
|
||||
|
||||
// ex: pf;member blah blah
|
||||
if (command && memberName && (values.length > 0 || newAndRemoveCommands.includes(command) || attachmentUrl)) {
|
||||
return await mh.memberCommandHandler(authorId, command, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
return await mh.memberCommandHandler(authorId, command, memberName, values, attachmentUrl, attachmentExpiration);
|
||||
}
|
||||
else if (memberName && values.length === 0) {
|
||||
return await mh.sendCurrentValue(authorId, memberName, command).catch((e) => {throw e});
|
||||
return await mh.sendCurrentValue(authorId, memberName, command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,12 +110,11 @@ mh.memberArgumentHandler = async function(authorId, authorFull, isHelp, command
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, string[], string}>} A member info embed + info/errors.
|
||||
* @throws {Error} When there's no member
|
||||
*/
|
||||
mh.sendCurrentValue = async function(authorId, memberName, command= null) {
|
||||
const member = await mh.getMemberByName(authorId, memberName).then((m) => {
|
||||
if (!m) throw new Error(enums.err.NO_MEMBER);
|
||||
return m;
|
||||
});
|
||||
const member = await mh.getMemberByName(authorId, memberName);
|
||||
if (!member) throw new Error(enums.err.NO_MEMBER);
|
||||
|
||||
if (!command) {
|
||||
return mh.getMemberInfo(member);
|
||||
@@ -173,22 +171,23 @@ mh.sendHelpEnum = function(command) {
|
||||
* @returns {Promise <EmbedBuilder>} A list of 25 members as an embed.
|
||||
* @returns {Promise <EmbedBuilder>} A list of member commands and descriptions.
|
||||
* @returns {Promise<{EmbedBuilder, [string], string}>} A member info embed + info/errors.
|
||||
* @throws {Error}
|
||||
*/
|
||||
mh.memberCommandHandler = async function(authorId, command, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
switch (command) {
|
||||
case 'new':
|
||||
return await mh.addNewMember(authorId, memberName, values, attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
return await mh.addNewMember(authorId, memberName, values, attachmentUrl, attachmentExpiration);
|
||||
case 'remove':
|
||||
return await mh.removeMember(authorId, memberName).catch((e) => {throw e});
|
||||
return await mh.removeMember(authorId, memberName);
|
||||
case 'name':
|
||||
return await mh.updateName(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
return await mh.updateName(authorId, memberName, values[0]);
|
||||
case 'displayname':
|
||||
return await mh.updateDisplayName(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
return await mh.updateDisplayName(authorId, memberName, values[0]);
|
||||
case 'proxy':
|
||||
return await mh.updateProxy(authorId, memberName, values[0]).catch((e) => {throw e});
|
||||
return await mh.updateProxy(authorId, memberName, values[0]);
|
||||
case 'propic':
|
||||
return await mh.updatePropic(authorId, memberName, values[0], attachmentUrl, attachmentExpiration).catch((e) => {throw e});
|
||||
return await mh.updatePropic(authorId, memberName, values[0], attachmentUrl, attachmentExpiration);
|
||||
default:
|
||||
throw new Error(enums.err.COMMAND_NOT_RECOGNIZED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,20 +201,15 @@ mh.memberCommandHandler = async function(authorId, command, memberName, values,
|
||||
* @param {string | null} [attachmentUrl] - The attachment URL, if any
|
||||
* @param {string | null} [attachmentExpiration] - The attachment expiry date, if any
|
||||
* @returns {Promise<{EmbedBuilder, string[], string}>} A successful addition.
|
||||
* @throws {Error} When creating a member doesn't work.
|
||||
*/
|
||||
mh.addNewMember = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
const displayName = values[0];
|
||||
const proxy = values[1];
|
||||
const propic = values[2] ?? attachmentUrl;
|
||||
|
||||
return await mh.addFullMember(authorId, memberName, displayName, proxy, propic, attachmentExpiration).then((response) => {
|
||||
const memberInfoEmbed = mh.getMemberInfo(response.member);
|
||||
return {embed: memberInfoEmbed, errors: response.errors, success: `${memberName} has been added successfully.`};
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
throw e;
|
||||
})
|
||||
const memberObj = await mh.addFullMember(authorId, memberName, displayName, proxy, propic, attachmentExpiration);
|
||||
const memberInfoEmbed = mh.getMemberInfo(memberObj.member);
|
||||
return {embed: memberInfoEmbed, errors: memberObj.errors, success: `${memberName} has been added successfully.`}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,9 +227,7 @@ mh.updateName = async function (authorId, memberName, name) {
|
||||
if (trimmedName === '') {
|
||||
throw new RangeError(`Name ${enums.err.NO_VALUE}`);
|
||||
}
|
||||
return await mh.updateMemberField(authorId, memberName, "name", trimmedName).catch((e) => {
|
||||
throw e
|
||||
});
|
||||
return await mh.updateMemberField(authorId, memberName, "name", trimmedName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,9 +249,7 @@ mh.updateDisplayName = async function (authorId, membername, displayname) {
|
||||
else if (trimmedName === '') {
|
||||
throw new RangeError(`Display name ${enums.err.NO_VALUE}`);
|
||||
}
|
||||
return await mh.updateMemberField(authorId, membername, "displayname", trimmedName).catch((e) => {
|
||||
throw e
|
||||
});
|
||||
return await mh.updateMemberField(authorId, membername, "displayname", trimmedName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,13 +260,12 @@ mh.updateDisplayName = async function (authorId, membername, displayname) {
|
||||
* @param {string} memberName - The member to update
|
||||
* @param {string} proxy - The proxy to set
|
||||
* @returns {Promise<string> } A successful update.
|
||||
* @throws {Error} When an empty proxy was provided, or a proxy exists.
|
||||
*/
|
||||
mh.updateProxy = async function (authorId, memberName, proxy) {
|
||||
// Throws error if exists
|
||||
await mh.checkIfProxyExists(authorId, proxy).catch((e) => { throw e; });
|
||||
await mh.checkIfProxyExists(authorId, proxy);
|
||||
|
||||
return await mh.updateMemberField(authorId, memberName, "proxy", proxy).catch((e) => { throw e;});
|
||||
return await mh.updateMemberField(authorId, memberName, "proxy", proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,14 +278,13 @@ mh.updateProxy = async function (authorId, memberName, proxy) {
|
||||
* @param {string | null} attachmentUrl - The attachment URL, if any
|
||||
* @param {string | null} attachmentExpiration - The attachment expiry date, if any
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {Error} When loading the profile picture from a URL doesn't work.
|
||||
*/
|
||||
mh.updatePropic = async function (authorId, memberName, values, attachmentUrl = null, attachmentExpiration = null) {
|
||||
const imgUrl = values ?? attachmentUrl;
|
||||
// Throws error if invalid
|
||||
await utils.checkImageFormatValidity(imgUrl).catch((e) => { throw e });
|
||||
|
||||
return await mh.updateMemberField(authorId, memberName, "propic", imgUrl, attachmentExpiration).catch((e) => { throw e });
|
||||
await utils.checkImageFormatValidity(imgUrl);
|
||||
const expirationWarning = utils.setExpirationWarning(imgUrl, attachmentExpiration);
|
||||
return await mh.updateMemberField(authorId, memberName, "propic", imgUrl, expirationWarning);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,17 +297,17 @@ mh.updatePropic = async function (authorId, memberName, values, attachmentUrl =
|
||||
* @throws {Error} When there is no member to remove.
|
||||
*/
|
||||
mh.removeMember = async function (authorId, memberName) {
|
||||
return await database.members.destroy({
|
||||
const destroyed = await database.members.destroy({
|
||||
where: {
|
||||
name: {[Op.iLike]: memberName},
|
||||
userid: authorId
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
return `Member "${memberName}" has been deleted.`;
|
||||
}
|
||||
throw new Error(`${enums.err.NO_MEMBER}`);
|
||||
})
|
||||
if (destroyed > 0) {
|
||||
return `Member "${memberName}" has been deleted.`;
|
||||
} else {
|
||||
throw new Error(`${enums.err.NO_MEMBER}`);
|
||||
}
|
||||
}
|
||||
|
||||
/*======Non-Subcommands======*/
|
||||
@@ -338,11 +326,10 @@ mh.removeMember = async function (authorId, memberName) {
|
||||
* @throws {Error} 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, attachmentExpiration = null) {
|
||||
await mh.getMemberByName(authorId, memberName).then((member) => {
|
||||
if (member) {
|
||||
throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`);
|
||||
}
|
||||
});
|
||||
const existingMember = await mh.getMemberByName(authorId, memberName);
|
||||
if (existingMember) {
|
||||
throw new Error(`Can't add ${memberName}. ${enums.err.MEMBER_EXISTS}`);
|
||||
}
|
||||
const errors = [];
|
||||
|
||||
const trimmedName = memberName.trim();
|
||||
@@ -366,28 +353,31 @@ mh.addFullMember = async function (authorId, memberName, displayName = null, pro
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let isValidProxy;
|
||||
if (proxy && proxy.length > 0) {
|
||||
await mh.checkIfProxyExists(authorId, proxy).then(() => {
|
||||
isValidProxy = true;
|
||||
}).catch((e) => {
|
||||
try {
|
||||
const proxyExists = await mh.checkIfProxyExists(authorId, proxy);
|
||||
isValidProxy = !proxyExists;
|
||||
}
|
||||
catch(e) {
|
||||
errors.push(`Tried to set proxy to \"${proxy}\". ${e.message}. ${enums.err.SET_TO_NULL}`);
|
||||
isValidProxy = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let isValidPropic;
|
||||
if (propic && propic.length > 0) {
|
||||
await utils.checkImageFormatValidity(propic).then(() => {
|
||||
isValidPropic = true;
|
||||
}).catch((e) => {
|
||||
try {
|
||||
isValidPropic = await utils.checkImageFormatValidity(propic);
|
||||
}
|
||||
catch(e) {
|
||||
errors.push(`Tried to set profile picture to \"${propic}\". ${e.message}. ${enums.err.SET_TO_NULL}`);
|
||||
isValidPropic = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (isValidPropic && attachmentExpiration) {
|
||||
errors.push(mh.setExpirationWarning(attachmentExpiration));
|
||||
const expirationWarning = utils.setExpirationWarning(propic, attachmentExpiration);
|
||||
if (expirationWarning) {
|
||||
errors.push(expirationWarning);
|
||||
}
|
||||
const member = await database.members.create({
|
||||
name: memberName, userid: authorId, displayname: isValidDisplayName ? displayName : null, proxy: isValidProxy ? proxy : null, propic: isValidPropic ? propic : null
|
||||
@@ -404,42 +394,21 @@ mh.addFullMember = async function (authorId, memberName, displayName = null, pro
|
||||
* @param {string} memberName - The member to update
|
||||
* @param {string} columnName - The column name to update.
|
||||
* @param {string} value - The value to update to.
|
||||
* @param {string | null} [attachmentExpiration] - The attachment expiration date (if any)
|
||||
* @param {string | null} [expirationWarning] - The attachment expiration warning (if any)
|
||||
* @returns {Promise<string>} A successful update.
|
||||
* @throws {Error} When no member row was updated.
|
||||
*/
|
||||
mh.updateMemberField = async function (authorId, memberName, columnName, value, attachmentExpiration = null) {
|
||||
let fluxerPropicWarning;
|
||||
|
||||
// indicates that an attachment was uploaded on Fluxer directly
|
||||
if (columnName === "propic" && attachmentExpiration) {
|
||||
fluxerPropicWarning = mh.setExpirationWarning(value);
|
||||
}
|
||||
return await database.members.update({[columnName]: value}, {
|
||||
mh.updateMemberField = async function (authorId, memberName, columnName, value, expirationWarning = null) {
|
||||
const res = await database.members.update({[columnName]: value}, {
|
||||
where: {
|
||||
name: {[Op.iLike]: memberName},
|
||||
userid: authorId
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res[0] === 0) {
|
||||
throw new Error(`Can't update ${memberName}. ${enums.err.NO_MEMBER}.`);
|
||||
} else {
|
||||
return `Updated ${columnName} for ${memberName} to ${value}${fluxerPropicWarning ?? ''}.`;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the warning for an expiration date.
|
||||
*
|
||||
* @param {string} expirationString - An expiration date string.
|
||||
* @returns {string} A description of the expiration, interpolating the expiration string.
|
||||
*/
|
||||
mh.setExpirationWarning = function (expirationString) {
|
||||
let expirationDate = new Date(expirationString);
|
||||
if (!isNaN(expirationDate.valueOf())) {
|
||||
expirationDate = expirationDate.toDateString();
|
||||
return `\n**NOTE:** Because this profile picture was uploaded via Fluxer, it will currently expire on *${expirationDate}*. To avoid this, upload the picture to another website like <https://imgbb.com/> and link to it directly`
|
||||
if (res[0] === 0) {
|
||||
throw new Error(`Can't update ${memberName}. ${enums.err.NO_MEMBER}.`);
|
||||
} else {
|
||||
return `Updated ${columnName} for ${memberName} to ${value}${expirationWarning ? `. ${expirationWarning}.` : '.'}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,12 +441,12 @@ mh.getMemberInfo = function (member) {
|
||||
*/
|
||||
mh.getAllMembersInfo = async function (authorId, authorName) {
|
||||
const members = await mh.getMembersByAuthor(authorId);
|
||||
if (members == null) throw Error(enums.err.USER_NO_MEMBERS);
|
||||
const fields = [...members.entries()].map(([name, member]) => ({
|
||||
if (members.length === 0) throw Error(enums.err.USER_NO_MEMBERS);
|
||||
const fields = [...members.entries()].map(([index, member]) => ({
|
||||
name: member.name, value: `(Proxy: \`${member.proxy ?? "unset"}\`)`, inline: true,
|
||||
}));
|
||||
return new EmbedBuilder()
|
||||
.setTitle(`${fields > 25 ? "First 25 m" : "M"}embers for ${authorName}`)
|
||||
.setTitle(`${fields.length > 25 ? "First 25 m" : "M"}embers for ${authorName}`)
|
||||
.addFields(...fields);
|
||||
}
|
||||
|
||||
@@ -517,14 +486,11 @@ mh.checkIfProxyExists = async function (authorId, proxy) {
|
||||
if (splitProxy.length < 2) throw new Error(enums.err.NO_TEXT_FOR_PROXY);
|
||||
if (!splitProxy[0] && !splitProxy[1]) throw new Error(enums.err.NO_PROXY_WRAPPER);
|
||||
|
||||
await mh.getMembersByAuthor(authorId).then((memberList) => {
|
||||
const proxyExists = memberList.some(member => member.proxy === proxy);
|
||||
if (proxyExists) {
|
||||
throw new Error(enums.err.PROXY_EXISTS);
|
||||
}
|
||||
}).catch(e => {
|
||||
throw e
|
||||
});
|
||||
const memberList = await mh.getMembersByAuthor(authorId);
|
||||
const proxyExists = memberList.some(member => member.proxy === proxy);
|
||||
if (proxyExists) {
|
||||
throw new Error(enums.err.PROXY_EXISTS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ msgh.parseCommandArgs = function(content, commandName) {
|
||||
* @param {string} authorId - The author of the message.
|
||||
* @param {string} content - The full message content
|
||||
* @param {string | null} [attachmentUrl] - The url for an attachment to the message, if any exists.
|
||||
* @returns {{model, string, bool}} The proxy message object.
|
||||
* @throws {Error} If a proxy message is sent with no message or attachment within it.
|
||||
* @returns {Promise<{model, string, bool}>} The proxy message object.
|
||||
*/
|
||||
msgh.parseProxyTags = async function (authorId, content, attachmentUrl = null){
|
||||
const members = await memberHelper.getMembersByAuthor(authorId);
|
||||
|
||||
@@ -15,15 +15,43 @@ u.debounce = function(func, delay) {
|
||||
*
|
||||
* @async
|
||||
* @param {string} imageUrl - The url of the image
|
||||
* @returns {bool} - Whether the image is in a valid format
|
||||
* @throws {Error} When loading the profile picture from a URL doesn't work, or it fails requirements.
|
||||
*/
|
||||
u.checkImageFormatValidity = async function (imageUrl) {
|
||||
const acceptableImages = ['image/png', 'image/jpg', 'image/jpeg', 'image/webp'];
|
||||
await fetch(imageUrl).then(r => r.blob()).then(blobFile => {
|
||||
if (blobFile.size > 1000000 || !acceptableImages.includes(blobFile.type)) throw new Error(enums.err.PROPIC_FAILS_REQUIREMENTS);
|
||||
}).catch((error) => {
|
||||
throw new Error(`${enums.err.PROPIC_CANNOT_LOAD}: ${error.message}`);
|
||||
});
|
||||
let response, blobFile;
|
||||
try {
|
||||
response = await fetch(imageUrl);
|
||||
}
|
||||
catch(e) {
|
||||
throw new Error(`${enums.err.PROPIC_CANNOT_LOAD}: ${e.message}`);
|
||||
}
|
||||
|
||||
blobFile = await response.blob();
|
||||
if (blobFile.size > 10000000 || !acceptableImages.includes(blobFile.type)) throw new Error(enums.err.PROPIC_FAILS_REQUIREMENTS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the warning that a Fluxer-uploaded image will expire.
|
||||
*
|
||||
* @param {string | null} [imgUrl] - An image URL.
|
||||
* @param {string | null} [expirationString] - An expiration date string.
|
||||
* @returns {string | null} A description of the expiration, or null.
|
||||
*/
|
||||
u.setExpirationWarning = function (imgUrl = null, expirationString = null) {
|
||||
if (imgUrl && imgUrl.startsWith(enums.misc.FLUXER_ATTACHMENT_URL)) {
|
||||
return enums.misc.ATTACHMENT_EXPIRATION_WARNING;
|
||||
}
|
||||
else if (expirationString) {
|
||||
let expirationDate = new Date(expirationString);
|
||||
if (!isNaN(expirationDate.valueOf())) {
|
||||
return `${enums.misc.ATTACHMENT_EXPIRATION_WARNING}. Expiration date: *${expirationString}*.`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const utils = u;
|
||||
|
||||
@@ -15,7 +15,7 @@ const name = 'PluralFlux Proxy Webhook';
|
||||
*/
|
||||
wh.sendMessageAsMember = async function(client, message) {
|
||||
const attachmentUrl = message.attachments.size > 0 ? message.attachments.first().url : null;
|
||||
const proxyMatch = await messageHelper.parseProxyTags(message.author.id, message.content, attachmentUrl).catch(e =>{throw e});
|
||||
const proxyMatch = await messageHelper.parseProxyTags(message.author.id, message.content, attachmentUrl);
|
||||
// If the message doesn't match a proxy, just return.
|
||||
if (!proxyMatch || !proxyMatch.member || (proxyMatch.message.length === 0 && !proxyMatch.hasAttachment) ) {
|
||||
return;
|
||||
@@ -27,7 +27,7 @@ wh.sendMessageAsMember = async function(client, message) {
|
||||
if (proxyMatch.hasAttachment) {
|
||||
return await message.reply(`${enums.misc.ATTACHMENT_SENT_BY} ${proxyMatch.member.displayname ?? proxyMatch.member.name}`)
|
||||
}
|
||||
await wh.replaceMessage(client, message, proxyMatch.message, proxyMatch.member).catch(e =>{throw e});
|
||||
await wh.replaceMessage(client, message, proxyMatch.message, proxyMatch.member);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,20 +43,19 @@ wh.replaceMessage = async function(client, message, text, member) {
|
||||
// attachment logic is not relevant yet, text length will always be over 0 right now
|
||||
if (text.length > 0 || message.attachments.size > 0) {
|
||||
const channel = client.channels.get(message.channelId);
|
||||
const webhook = await wh.getOrCreateWebhook(client, channel).catch((e) =>{throw e});
|
||||
const webhook = await wh.getOrCreateWebhook(client, channel);
|
||||
const username = member.displayname ?? member.name;
|
||||
if (text.length > 0) {
|
||||
await webhook.send({content: text, username: username, avatar_url: member.propic}).catch(async(e) => {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(text);
|
||||
await webhook.send({content: returnedBuffer.text, username: username, avatar_url: member.propic, files: [{ name: 'text.txt', data: returnedBuffer.file }]
|
||||
})
|
||||
console.error(e);
|
||||
});
|
||||
if (text.length <= 2000) {
|
||||
await webhook.send({content: text, username: username, avatar_url: member.propic})
|
||||
}
|
||||
else if (text.length > 2000) {
|
||||
const returnedBuffer = messageHelper.returnBufferFromText(text);
|
||||
await webhook.send({content: returnedBuffer.text, username: username, avatar_url: member.propic, files: [{ name: 'text.txt', data: returnedBuffer.file }]
|
||||
})
|
||||
}
|
||||
if (message.attachments.size > 0) {
|
||||
// Not implemented yet
|
||||
}
|
||||
|
||||
await message.delete();
|
||||
}
|
||||
}
|
||||
@@ -72,7 +71,7 @@ wh.replaceMessage = async function(client, message, text, member) {
|
||||
wh.getOrCreateWebhook = async function(client, channel) {
|
||||
// If channel doesn't allow webhooks
|
||||
if (!channel?.createWebhook) throw new Error(enums.err.NO_WEBHOOKS_ALLOWED);
|
||||
let webhook = await wh.getWebhook(client, channel).catch((e) =>{throw e});
|
||||
let webhook = await wh.getWebhook(client, channel)
|
||||
if (!webhook) {
|
||||
webhook = await channel.createWebhook({name: name});
|
||||
}
|
||||
@@ -91,13 +90,7 @@ wh.getWebhook = async function(client, channel) {
|
||||
if (channelWebhooks.length === 0) {
|
||||
return;
|
||||
}
|
||||
let pf_webhook;
|
||||
channelWebhooks.forEach((webhook) => {
|
||||
if (webhook.name === name) {
|
||||
pf_webhook = webhook;
|
||||
}
|
||||
})
|
||||
return pf_webhook;
|
||||
return channelWebhooks.find((webhook) => webhook.name === name);
|
||||
}
|
||||
|
||||
export const webhookHelper = wh;
|
||||
Reference in New Issue
Block a user