feat(boost-greeting): integrate greeting into guild member update and clean up handler
This commit is contained in:
+14
-1
@@ -5,6 +5,7 @@ import { BoosterRoleService } from "../services/boosterRoleService";
|
||||
import { DrizzleBoosterRoleStore } from "../services/drizzleBoosterRoleStore";
|
||||
import { DiscordRoleRepository } from "../services/discordRoleRepository";
|
||||
import { handleGuildMemberUpdate } from "./events/guildMemberUpdate";
|
||||
import { sendBoostGreeting } from "./events/boostGreeting";
|
||||
import { handleInteraction } from "./interactionHandler";
|
||||
|
||||
export function attachBotHandlers(client: Client, config: AppConfig): void {
|
||||
@@ -26,13 +27,25 @@ export function attachBotHandlers(client: Client, config: AppConfig): void {
|
||||
});
|
||||
|
||||
client.on("guildMemberUpdate", async (oldMember, newMember) => {
|
||||
const eligibilityRoleId = config.boosterEligibilityRoleId;
|
||||
|
||||
// Detect boost gain: member just acquired the booster eligibility role
|
||||
const hadBooster = oldMember.roles.cache.has(eligibilityRoleId);
|
||||
const hasBooster = newMember.roles.cache.has(eligibilityRoleId);
|
||||
if (!hadBooster && hasBooster && config.boosterGreetingChannelId) {
|
||||
await sendBoostGreeting(newMember, config.boosterGreetingChannelId).catch((err) => {
|
||||
logger.error("Failed to send boost greeting", { error: String(err), userId: newMember.id });
|
||||
});
|
||||
}
|
||||
|
||||
// Handle boost loss (existing behaviour)
|
||||
const service = new BoosterRoleService(
|
||||
store,
|
||||
new DiscordRoleRepository(newMember.guild),
|
||||
{ anchorPosition: resolveAnchorPosition(newMember.guild, config.boosterRoleAnchorRoleId) }
|
||||
);
|
||||
|
||||
await handleGuildMemberUpdate(oldMember, newMember, service, config.boosterEligibilityRoleId);
|
||||
await handleGuildMemberUpdate(oldMember, newMember, service, eligibilityRoleId);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ type GuildTextChannel = {
|
||||
send(input: { content: string }): Promise<unknown>;
|
||||
};
|
||||
|
||||
type GuildMember = {
|
||||
type GuildMemberLike = {
|
||||
id: string;
|
||||
user?: { id: string };
|
||||
guild: {
|
||||
id: string;
|
||||
channels: {
|
||||
@@ -14,46 +15,35 @@ type GuildMember = {
|
||||
};
|
||||
};
|
||||
};
|
||||
user?: { id: string };
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a welcome message to the configured greeting channel when a member
|
||||
* newly acquires the booster eligibility role (i.e. just boosted the server).
|
||||
*
|
||||
* Only fires on a *gain* transition (hadBoosterRole = false → hasBoosterRole = true).
|
||||
*/
|
||||
export function handleBoostGreeting(
|
||||
oldMember: GuildMember,
|
||||
newMember: GuildMember,
|
||||
greetingChannelId: string | null,
|
||||
): void {
|
||||
if (!greetingChannelId) return;
|
||||
|
||||
const hadBoosterRole = oldMember.roles.cache.has(/** @type {any} */ (null) as any);
|
||||
// Actually detect the gain: we need the actual role ID. The caller should pass it.
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a welcome message when a member newly acquires the booster eligibility role.
|
||||
* Must be called with the booster eligibility role ID to check correctly.
|
||||
* Sends a welcome message to the configured greeting channel.
|
||||
* Call this after confirming the member newly gained the booster eligibility role.
|
||||
*/
|
||||
export async function sendBoostGreeting(
|
||||
member: { id: string; guild: { id: string; channels: { cache: { get(channelId: string): { send(input: { content: string }): Promise<unknown> } | undefined } } } },
|
||||
member: GuildMemberLike,
|
||||
greetingChannelId: string,
|
||||
): Promise<void> {
|
||||
const channel = member.guild.channels.cache.get(greetingChannelId);
|
||||
|
||||
if (!channel) {
|
||||
logger.warn("Boost greeting channel not found", { channelId: greetingChannelId, guildId: member.guild.id });
|
||||
logger.warn("Boost greeting channel not found", {
|
||||
channelId: greetingChannelId,
|
||||
guildId: member.guild.id,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await channel.send({
|
||||
content: `🎉 Thank you for boosting <@${member.user?.id ?? member.id}>! You can now claim a custom role using \`/booster-role claim\` in <#${greetingChannelId}>.`
|
||||
});
|
||||
const mention = member.user?.id ?? member.id;
|
||||
const message =
|
||||
`🎉 Thank you for boosting <@${mention}>! ` +
|
||||
`You can now claim a custom role using \`/booster-role claim\` in <#${greetingChannelId}>.`;
|
||||
|
||||
await channel.send({ content: message });
|
||||
|
||||
logger.info("Boost greeting sent", {
|
||||
userId: member.user?.id ?? member.id,
|
||||
userId: member.id,
|
||||
guildId: member.guild.id,
|
||||
channelId: greetingChannelId,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user