2026-02-13 18:20:29 -05:00
import { db } from '../sequelize.js' ;
2026-02-13 21:23:33 -05:00
import { enums } from "../enums.js" ;
2026-02-14 01:00:23 -05:00
import { loadImage } from "canvas" ;
2026-02-13 18:20:29 -05:00
const mh = { } ;
2026-02-13 22:18:43 -05:00
// Has an empty "command" to parse the help message properly
2026-02-14 01:00:23 -05:00
const commandList = [ '--help' , 'add' , 'remove' , 'displayName' , 'proxy' , 'propic' , '' ] ;
2026-02-13 21:45:01 -05:00
2026-02-13 21:23:33 -05:00
/ * *
* Parses through the subcommands that come after "pf;member" and calls functions accordingly .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ param { string } attachment - The message attachments
* @ returns { Promise < string > } A message .
2026-02-13 21:23:33 -05:00
* /
2026-02-14 00:20:36 -05:00
mh . parseMemberCommand = async function ( authorId , args , attachment ) {
2026-02-13 20:38:51 -05:00
console . log ( authorId , args ) ;
2026-02-13 22:18:43 -05:00
let member ;
// checks whether command is in list, otherwise assumes it's a name
2026-02-13 21:45:01 -05:00
if ( ! commandList . includes ( args [ 0 ] ) ) {
2026-02-13 22:18:43 -05:00
member = await getMemberInfo ( authorId , args [ 0 ] ) ;
2026-02-14 00:20:36 -05:00
if ( member === enums . err . NO _MEMBER ) {
return member ;
2026-02-13 22:18:43 -05:00
}
2026-02-13 21:45:01 -05:00
}
2026-02-13 18:20:29 -05:00
switch ( args [ 0 ] ) {
2026-02-13 20:08:24 -05:00
case '--help' :
2026-02-13 21:18:44 -05:00
return enums . help . MEMBER ;
2026-02-13 20:08:24 -05:00
case 'add' :
2026-02-13 22:18:43 -05:00
return await addNewMember ( authorId , args ) ;
2026-02-13 18:56:36 -05:00
case 'remove' :
2026-02-13 22:18:43 -05:00
return await removeMember ( authorId , args ) ;
2026-02-13 21:30:22 -05:00
case 'displayname' :
2026-02-13 22:18:43 -05:00
return enums . help . DISPLAY _NAME ;
2026-02-13 21:30:22 -05:00
case 'proxy' :
return enums . help . PROXY ;
2026-02-14 01:00:23 -05:00
case 'propic' :
return enums . help . PROPIC ;
2026-02-13 21:30:22 -05:00
case '' :
return enums . help . MEMBER ;
2026-02-13 18:20:29 -05:00
}
switch ( args [ 1 ] ) {
2026-02-13 18:56:36 -05:00
case '--help' :
2026-02-13 21:18:44 -05:00
return enums . help . MEMBER ;
2026-02-13 18:20:29 -05:00
case 'displayname' :
2026-02-13 22:18:43 -05:00
return await updateDisplayName ( authorId , args ) ;
2026-02-13 18:56:36 -05:00
case 'proxy' :
2026-02-13 22:18:43 -05:00
return await updateProxy ( authorId , args ) ;
2026-02-14 00:20:36 -05:00
case 'propic' :
return await updatePropic ( authorId , args , attachment )
2026-02-13 18:20:29 -05:00
default :
2026-02-13 22:18:43 -05:00
return member ;
2026-02-13 18:20:29 -05:00
}
}
2026-02-13 21:23:33 -05:00
/ * *
* Adds a member , first checking that there is no member of that name associated with the author .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } A successful addition , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function addNewMember ( authorId , args ) {
if ( args [ 1 ] && args [ 1 ] === "--help" || ! args [ 1 ] ) {
2026-02-13 21:18:44 -05:00
return enums . help . ADD ;
2026-02-13 18:20:29 -05:00
}
2026-02-13 20:38:51 -05:00
const memberName = args [ 1 ] ;
const displayName = args [ 2 ] ;
2026-02-13 22:18:43 -05:00
const member = await getMemberInfo ( authorId , memberName ) ;
if ( member && member !== enums . err . NO _MEMBER ) {
2026-02-13 21:18:44 -05:00
return enums . err . MEMBER _EXISTS ;
2026-02-13 18:20:29 -05:00
}
2026-02-13 20:38:51 -05:00
const trimmedName = displayName ? displayName . replaceAll ( ' ' , '' ) : null ;
2026-02-13 18:20:29 -05:00
return await db . members . create ( {
2026-02-13 20:38:51 -05:00
name : memberName ,
userid : authorId ,
displayname : trimmedName !== null ? displayName : null ,
2026-02-13 18:20:29 -05:00
} ) . then ( ( m ) => {
let success = ` Member was successfully added. \n Name: ${ m . dataValues . name } `
2026-02-13 20:38:51 -05:00
success += displayName ? ` \n Display name: ${ m . dataValues . displayname } ` : "" ;
2026-02-13 18:20:29 -05:00
return success ;
} ) . catch ( e => {
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . ADD _ERROR } : ${ e . message } ` ;
2026-02-13 18:20:29 -05:00
} )
}
2026-02-13 21:23:33 -05:00
/ * *
* Updates the display name for a member .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } A successful update , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function updateDisplayName ( authorId , args ) {
if ( args [ 1 ] && args [ 1 ] === "--help" || ! args [ 1 ] ) {
2026-02-13 22:18:43 -05:00
return enums . help . DISPLAY _NAME ;
2026-02-13 18:20:29 -05:00
}
2026-02-13 20:38:51 -05:00
const memberName = args [ 0 ] ;
const displayName = args [ 2 ] ;
const trimmed _name = displayName ? displayName . replaceAll ( ' ' , '' ) : null ;
if ( ! displayName || trimmed _name === null ) {
2026-02-13 22:18:43 -05:00
let member = await mh . getMemberByName ( authorId , memberName ) ;
2026-02-13 18:20:29 -05:00
if ( member . displayname ) {
2026-02-13 22:18:43 -05:00
return ` Display name for ${ memberName } is: \" ${ member . displayname } \" . ` ;
2026-02-13 18:20:29 -05:00
}
2026-02-13 21:18:44 -05:00
return ` Display name ${ enums . err . NO _VALUE } `
2026-02-13 18:20:29 -05:00
}
2026-02-13 21:23:33 -05:00
else if ( displayName . length > 32 ) {
2026-02-13 21:18:44 -05:00
return enums . err . DISPLAY _NAME _TOO _LONG ;
2026-02-13 18:56:36 -05:00
}
2026-02-13 20:38:51 -05:00
console . log ( displayName ) ;
2026-02-13 21:23:33 -05:00
return updateMember ( authorId , args ) ;
2026-02-13 18:20:29 -05:00
}
2026-02-13 21:23:33 -05:00
/ * *
* Updates the proxy for a member , first checking that no other members attached to the author have the tag .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } A successful update , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function updateProxy ( authorId , args ) {
if ( args [ 1 ] && args [ 1 ] === "--help" || ! args [ 1 ] ) {
2026-02-13 21:18:44 -05:00
return enums . help . PROXY ;
2026-02-13 20:38:51 -05:00
}
2026-02-13 18:56:36 -05:00
const proxy = args [ 2 ] ;
2026-02-13 20:38:51 -05:00
const trimmedProxy = proxy ? proxy . replaceAll ( ' ' , '' ) : null ;
2026-02-13 18:56:36 -05:00
2026-02-13 20:38:51 -05:00
if ( trimmedProxy == null ) {
2026-02-14 00:20:36 -05:00
return ` Proxy ${ enums . err . NO _VALUE } ` ;
2026-02-13 18:56:36 -05:00
}
2026-02-13 20:38:51 -05:00
const members = await mh . getMembersByAuthor ( authorId ) ;
2026-02-13 20:08:24 -05:00
const proxyExists = members . some ( member => member . proxy === proxy ) ;
if ( proxyExists ) {
2026-02-13 21:18:44 -05:00
return enums . err . PROXY _EXISTS ;
2026-02-13 20:08:24 -05:00
}
2026-02-13 21:23:33 -05:00
return updateMember ( authorId , args ) ;
2026-02-13 18:56:36 -05:00
}
2026-02-14 01:00:23 -05:00
/ * *
* Updates the profile pic for a member , based on either the attachment or the args provided .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
* @ param { string } attachment - The url of the first attachment in the message
* @ returns { Promise < string > } A successful update , or an error message .
* /
2026-02-14 00:20:36 -05:00
async function updatePropic ( authorId , args , attachment ) {
if ( args [ 1 ] && args [ 1 ] === "--help" ) {
return enums . help . PROPIC ;
}
let img ;
const updatedArgs = args ;
if ( ! updatedArgs [ 1 ] && ! attachment ) {
return enums . help . PROPIC ;
} else if ( attachment ) {
updatedArgs [ 2 ] = attachment . url ;
2026-02-14 01:00:23 -05:00
updatedArgs [ 3 ] = attachment . expires _at ;
2026-02-14 00:20:36 -05:00
}
if ( updatedArgs [ 2 ] ) {
img = updatedArgs [ 2 ] ;
}
return await loadImage ( img ) . then ( ( ) => {
return updateMember ( authorId , updatedArgs ) ;
} ) . catch ( ( err ) => {
return ` ${ enums . err . PROPIC _CANNOT _LOAD } : ${ err . message } ` ;
} ) ;
}
2026-02-13 21:23:33 -05:00
/ * *
* Removes a member .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } A successful removal , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function removeMember ( authorId , args ) {
if ( args [ 1 ] && args [ 1 ] === "--help" ) {
2026-02-13 21:18:44 -05:00
return enums . help . REMOVE ;
2026-02-13 20:38:51 -05:00
}
const memberName = args [ 1 ] ;
if ( ! memberName ) {
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . NO _NAME _PROVIDED } deletion. ` ;
2026-02-13 20:38:51 -05:00
}
return await db . members . destroy ( { where : { name : memberName , userid : authorId } } ) . then ( ( ) => {
2026-02-14 10:07:27 -05:00
return ` Member " ${ memberName } " has been deleted. ` ;
2026-02-13 18:20:29 -05:00
} ) . catch ( e => {
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . NO _MEMBER } : ${ e . message } ` ;
2026-02-13 18:20:29 -05:00
} ) ;
}
2026-02-14 00:20:36 -05:00
/*======Non-Subcommands======*/
2026-02-13 21:23:33 -05:00
/ * *
* Updates a member ' s fields in the database .
*
* @ param { string } authorId - The author of the message
* @ param { string [ ] } args - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } A successful update , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function updateMember ( authorId , args ) {
const memberName = args [ 0 ] ;
const columnName = args [ 1 ] ;
const value = args [ 2 ] ;
2026-02-14 01:00:23 -05:00
let fluxerPropicWarning ;
// indicates that an attachment was uploaded on Fluxer directly
if ( columnName === "propic" && args [ 3 ] ) {
console . log ( args ) ;
fluxerPropicWarning = setExpirationWarning ( args [ 3 ] ) ;
}
2026-02-13 20:38:51 -05:00
return await db . members . update ( { [ columnName ] : value } , { where : { name : memberName , userid : authorId } } ) . then ( ( ) => {
2026-02-14 10:07:27 -05:00
return ` Updated ${ columnName } for ${ memberName } to " ${ value } " ${ fluxerPropicWarning ? ? '' } . ` ;
2026-02-13 18:20:29 -05:00
} ) . catch ( e => {
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . NO _MEMBER } : ${ e . message } ` ;
2026-02-13 18:20:29 -05:00
} ) ;
}
2026-02-14 01:00:23 -05:00
/ * *
* Sets the warning for an expiration date .
*
* @ param { string } expirationString - An expiration date string .
* @ returns { string } A successful update , or an error message .
* /
function setExpirationWarning ( expirationString ) {
let expirationDate = new Date ( expirationString ) ;
console . log ( expirationDate , expirationDate instanceof Date ) ;
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. `
}
}
2026-02-13 21:23:33 -05:00
/ * *
* Gets the details for a member .
*
* @ param { string } authorId - The author of the message
* @ param { string } memberName - The message arguments
2026-02-14 00:20:36 -05:00
* @ returns { Promise < string > } The member ' s info , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
async function getMemberInfo ( authorId , memberName ) {
let member = await db . members . findOne ( { where : { name : memberName , userid : authorId } } ) ;
if ( member ) {
let member _info = ` Member name: ${ member . name } ` ;
member _info += member . displayname ? ` \n Display name: ${ member . displayname } ` : '\nDisplay name: unset' ;
member _info += member . proxy ? ` \n Proxy Tag: ${ member . proxy } ` : '\nProxy tag: unset' ;
member _info += member . propic ? ` \n Profile pic: ${ member . propic } ` : '\nProfile pic: unset' ;
return member _info ;
}
2026-02-13 21:18:44 -05:00
return enums . err . NO _MEMBER ;
2026-02-13 20:38:51 -05:00
}
2026-02-13 21:23:33 -05:00
/ * *
* Gets a member based on the author and proxy tag .
*
* @ param { string } authorId - The author of the message .
* @ param { string } name - The member ' s name .
2026-02-14 00:20:36 -05:00
* @ returns { Promise < model > | Promise < string > } The member object , or an error message .
2026-02-13 21:23:33 -05:00
* /
mh . getMemberByName = async function ( authorId , name ) {
return await db . members . findOne ( { where : { userid : authorId , name : name } } ) . catch ( e => {
return ` ${ enums . err . NO _MEMBER } : ${ e . message } ` ;
} ) ;
}
/ * *
* Gets a member based on the author and proxy tag .
*
* @ param { string } authorId - The author of the message
* @ param { string } proxy - The proxy tag
2026-02-14 00:20:36 -05:00
* @ returns { Promise < model > | Promise < string > } The member object , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
mh . getMemberByProxy = async function ( authorId , proxy ) {
return await db . members . findOne ( { where : { userid : authorId , proxy : proxy } } ) . catch ( e => {
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . NO _MEMBER } : ${ e . message } ` ;
2026-02-13 18:20:29 -05:00
} ) ;
}
2026-02-13 21:23:33 -05:00
/ * *
* Gets all members belonging to the author .
*
* @ param { string } authorId - The author of the message
2026-02-14 00:20:36 -05:00
* @ returns { Promise < model [ ] > | Promise < string > } The member object , or an error message .
2026-02-13 21:23:33 -05:00
* /
2026-02-13 20:38:51 -05:00
mh . getMembersByAuthor = async function ( authorId ) {
return await db . members . findAll ( { where : { userid : authorId } } ) . catch ( e => {
2026-02-13 18:20:29 -05:00
// I have no idea how this could possibly happen but better safe than sorry
2026-02-13 21:18:44 -05:00
return ` ${ enums . err . USER _NO _MEMBERS } : ${ e . message } ` ;
2026-02-13 18:20:29 -05:00
} ) ;
}
export const memberHelper = mh ;