Added module name-list-cleaner#178
Conversation
as per Sukram2.0's suggestion also added tabs in en.json...
There was a problem hiding this comment.
Pull request overview
Adds a new name-list-cleaner module intended to sanitize member display names by stripping leading special characters, and wires it into member update + bot ready events with accompanying English localization strings.
Changes:
- Introduces the
name-list-cleanermodule metadata, configuration schema, and event handlers. - Implements
renameMember/checkUsernamelogic to compute a cleaned nickname (or reset nickname depending on config). - Updates
locales/en.jsonformatting and addsname-list-cleanerlocale keys.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/name-list-cleaner/renameMember.js | Core renaming logic and username sanitization helper. |
| modules/name-list-cleaner/module.json | Module metadata registration (name, author, tags, config examples). |
| modules/name-list-cleaner/events/guildMemberUpdate.js | Triggers sanitization on nickname/username changes. |
| modules/name-list-cleaner/events/botReady.js | Sanitizes all cached members on startup. |
| modules/name-list-cleaner/configs/config.json | Defines configurable behavior (whitelist/blacklist, user whitelist, etc.). |
| locales/en.json | Adds localized strings for the new module and adjusts indentation in the ping-protection section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (newName === guildMember.user.username) return; | ||
| } else return; | ||
| if (guildMember.guild.ownerId === guildMember.id) { | ||
| client.logger.error('[nicknames] ' + localize('name-list-cleaner', 'owner-cannot-be-renamed', {u: guildMember.user.username})) |
There was a problem hiding this comment.
The log prefix here is [nicknames] but the message is for the name-list-cleaner module. This makes operational debugging harder; switch the prefix/tag to [name-list-cleaner] for consistency with the rest of this file’s logging.
| client.logger.error('[nicknames] ' + localize('name-list-cleaner', 'owner-cannot-be-renamed', {u: guildMember.user.username})) | |
| client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'owner-cannot-be-renamed', {u: guildMember.user.username})) |
| client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'nickname-error', {u: guildMember.user.username, e: e})) | ||
| } | ||
| } else { | ||
| await guildMember.setNickname(null, localize('name-list-cleaner', 'nickname-reset', {u: guildMember.user.username})); |
There was a problem hiding this comment.
In the keepNickname === false branch, setNickname(null, ...) is awaited without error handling. Other nickname-changing code in this repo wraps setNickname in try/catch (or .catch) to avoid unhandled rejections when the bot lacks permissions / role hierarchy is too low; apply the same handling here.
| await guildMember.setNickname(null, localize('name-list-cleaner', 'nickname-reset', {u: guildMember.user.username})); | |
| try { | |
| await guildMember.setNickname(null, localize('name-list-cleaner', 'nickname-reset', {u: guildMember.user.username})); | |
| } catch (e) { | |
| client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'nickname-error', {u: guildMember.user.username, e: e})) | |
| } |
| if (name.length === 0) return 'INVALID NAME'; | ||
| if (moduleConf.symbolWhitelist === []) { | ||
| if (name.charAt(0).match(/^[a-zA-Z0-9]$/)) { | ||
| return name; | ||
| } else { | ||
| return await checkUsername(client, name.substring(1)); | ||
| } | ||
| } else if (!moduleConf.symbolWhitelist.includes(name.charAt(0)) && !moduleConf.isBlacklist) { |
There was a problem hiding this comment.
moduleConf.symbolWhitelist === [] will always be false in JS (array reference comparison). This breaks the intended “empty list” behavior (especially when isBlacklist is true). Use an emptiness check like Array.isArray(...) && symbolWhitelist.length === 0 (and ensure the empty-list behavior matches the config description).
| if (name.length === 0) return 'INVALID NAME'; | ||
| if (moduleConf.symbolWhitelist === []) { |
There was a problem hiding this comment.
When the input name consists entirely of stripped characters, this returns the hard-coded string 'INVALID NAME', which would then be applied as a nickname. Consider returning null/'' and handling that in renameMember (e.g., reset nickname or skip) so the bot never sets a literal "INVALID NAME" nickname.
| if (name.length === 0) return 'INVALID NAME'; | |
| if (moduleConf.symbolWhitelist === []) { | |
| if (name.length === 0) return null; | |
| if (!Array.isArray(moduleConf.symbolWhitelist) || moduleConf.symbolWhitelist.length === 0) { |
| "link": "https://github.com/hfgd123", | ||
| "scnxOrgID": "2" | ||
| }, | ||
| "openSourceURL": "https://github.com/hfgd123/CustomDCBot/tree/main/modules/username-check", |
There was a problem hiding this comment.
openSourceURL points to modules/username-check, which doesn’t match this module’s name/path (modules/name-list-cleaner). Update it to the correct repository URL so metadata consumers can find the module’s source.
| "openSourceURL": "https://github.com/hfgd123/CustomDCBot/tree/main/modules/username-check", | |
| "openSourceURL": "https://github.com/hfgd123/CustomDCBot/tree/main/modules/name-list-cleaner", |
| } catch (e) { | ||
| client.logger.error('[name-list-cleaner] ' + localize('name-list-cleaner', 'nickname-error', {u: guildMember.user.username, e: e})) | ||
| } | ||
| } else { |
There was a problem hiding this comment.
If alsoCheckUsernames is enabled and keepNickname is false, this code will attempt setNickname(null, ...) even when the member already has no nickname (no-op but still an API call + audit log entry). Consider short-circuiting when guildMember.nickname === null in this branch to avoid unnecessary requests.
| } else { | |
| } else { | |
| if (guildMember.nickname === null) { | |
| return; | |
| } |
| if (guildMember.nickname !== null) { | ||
| newName = await checkUsername(client, guildMember.nickname); | ||
| if (newName === guildMember.nickname) return; | ||
| } else if (moduleConf.alsoCheckUsername) { |
There was a problem hiding this comment.
moduleConf.alsoCheckUsername does not match the configuration key defined in this module's config schema (alsoCheckUsernames), so the username-check path will never run. Rename one side so the code reads the actual configured flag (and keep naming consistent across config + implementation).
| } else if (moduleConf.alsoCheckUsername) { | |
| } else if (moduleConf.alsoCheckUsernames) { |
as per Sukram2.0's suggestion
also added tabs in en.json...