Skip to content

Conversation

@TannPat
Copy link
Collaborator

@TannPat TannPat commented Dec 3, 2025

  • add database model and CRUD methods
  • add commands for adding, getting, and deleting joinphrases
  • add logic to send joinphrases on user join
  • implement conditions of minimum time and messages since last JP per user per room
  • add otherHandler to track messages for miscellaneous use

Copy link
Owner

@PartMan7 PartMan7 left a comment

Choose a reason for hiding this comment

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

Hi there's a couple things I've left comments on

Most of the stuff is done though, thanks! Tag me if you'd like me to implement some of the comments I've mentioned

},
userId: {
type: String,
default: toId(username),
Copy link
Owner

Choose a reason for hiding this comment

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

The username here is the bot's username; that's probably not the default we want to go with - ideally this should be a function that takes the given username

help: 'Joinphrases module!',
perms: ['room', 'driver'],
syntax: 'CMD',
aliases: ['joinphrase'],
Copy link
Owner

Choose a reason for hiding this comment

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

aliases and name should be swapped here - the name is the full name of the command, while aliases are abbreviations for those

aliases: ['joinphrase'],
categories: ['utility'],
extendedAliases: {
addjp: ['jp', 'new'],
Copy link
Owner

Choose a reason for hiding this comment

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

Could you also add ajp, djp, and ejp? Those are currently the most commonly used ones

Comment on lines 38 to 40
const args: string[] = arg.split(',').map(s => s.trim());
const username = args[0];
const phrase = args[1];
Copy link
Owner

Choose a reason for hiding this comment

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

This is broken with commas (phrases with commas will only have the first bit)

Suggested change
const args: string[] = arg.split(',').map(s => s.trim());
const username = args[0];
const phrase = args[1];
const [username, phrase] = arg.lazySplit(/\s*,\s*/, 1);

See https://github.com/PartMan7/PartBot/blob/main/src/globals/prototypes.ts#L58 for reference

Comment on lines 49 to 51
} catch (e: unknown) {
message.reply(`${username} already has a joinphrase in ${message.target.title}...` as ToTranslate);
}
Copy link
Owner

Choose a reason for hiding this comment

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

You don't need to catch explicitly - throwing an error is the preferred approach, since that automatically handles private replies and whatnot

messageCount: number; // messages since last jp
lastTime: number; // timestamp of last jp
}
const jpStateMap: Partial<Record<string, jpState>> = {};
Copy link
Owner

Choose a reason for hiding this comment

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

This should be in @/cache instead of here

Comment on lines 21 to 36
export function otherHandler(message: PSMessage) {
if (message.isIntro) return;
if (!message.author || !message.author.userid || !message.target || message.author.id === message.parent.status.userid) return;
if (message.content.startsWith('|')) return;
const roomId = message.target.id;

for (const key in jpStateMap) {
if (!jpStateMap[key]) continue;

const rId = key.split('-')[1];
if (rId !== roomId) continue;

jpStateMap[key]!.messageCount++;
} // increment message count for each joinphrase in the room
}

Copy link
Owner

Choose a reason for hiding this comment

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

This should be in its own file; this file is about join/leave/rename events

state = { messageCount: minimumMessages, lastTime: 0 };
jpStateMap[key] = state;
}
const now = Date.now() / 1000;
Copy link
Owner

Choose a reason for hiding this comment

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

Try to use milliseconds instead of seconds wherever possible

Comment on lines 27 to 34
for (const key in jpStateMap) {
if (!jpStateMap[key]) continue;

const rId = key.split('-')[1];
if (rId !== roomId) continue;

jpStateMap[key]!.messageCount++;
} // increment message count for each joinphrase in the room
Copy link
Owner

Choose a reason for hiding this comment

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

Performance wise this is a bit concerning; if there's a couple hundred JPs total, you're looping over every single one of them on every message

Instead, the state map should be grouped by rooms instead so you don't iterate over JPs that aren't for the room

// (Kinda creepy name for the feature, but it CAN be used in creepy ways so make sure it's regulated!)

const userId = toId(user),
roomId = toId(room);
Copy link
Owner

Choose a reason for hiding this comment

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

Why's room been cast to roomId here?

TannPat and others added 3 commits December 23, 2025 01:50
- add database model and CRUD methods
- add commands for adding, getting, and deleting joinphrases
- add logic to send joinphrases on user join
- add conditions of minimum time and messages since last JP per user per room
- add otherHandler to track messages for miscellaneous use
@PartMan7 PartMan7 linked an issue Dec 24, 2025 that may be closed by this pull request
@PartMan7
Copy link
Owner

Alright, this looks good now. Thanks!

@PartMan7 PartMan7 merged commit ad1516f into PartMan7:main Dec 24, 2025
4 checks passed
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.

feat: Joinphrases

2 participants