```
This commit is contained in:
+7
-3
@@ -1,6 +1,7 @@
|
|||||||
import type { Client } from "discord.js";
|
import type { Client } from "discord.js";
|
||||||
import type { AppConfig } from "../config";
|
import type { AppConfig } from "../config";
|
||||||
import { createDb } from "../db";
|
import { createDb } from "../db";
|
||||||
|
import { logger } from "../logger";
|
||||||
import { BoosterRoleService } from "../services/boosterRoleService";
|
import { BoosterRoleService } from "../services/boosterRoleService";
|
||||||
import { DrizzleBoosterRoleStore } from "../services/drizzleBoosterRoleStore";
|
import { DrizzleBoosterRoleStore } from "../services/drizzleBoosterRoleStore";
|
||||||
import { DiscordRoleRepository } from "../services/discordRoleRepository";
|
import { DiscordRoleRepository } from "../services/discordRoleRepository";
|
||||||
@@ -33,9 +34,12 @@ export function attachBotHandlers(client: Client, config: AppConfig): void {
|
|||||||
const hadBooster = oldMember.roles.cache.has(eligibilityRoleId);
|
const hadBooster = oldMember.roles.cache.has(eligibilityRoleId);
|
||||||
const hasBooster = newMember.roles.cache.has(eligibilityRoleId);
|
const hasBooster = newMember.roles.cache.has(eligibilityRoleId);
|
||||||
if (!hadBooster && hasBooster && config.boosterGreetingChannelId) {
|
if (!hadBooster && hasBooster && config.boosterGreetingChannelId) {
|
||||||
await sendBoostGreeting(newMember, config.boosterGreetingChannelId).catch((err) => {
|
const channel = newMember.guild.channels.cache.get(config.boosterGreetingChannelId);
|
||||||
logger.error("Failed to send boost greeting", { error: String(err), userId: newMember.id });
|
if (channel && "send" in channel) {
|
||||||
});
|
await sendBoostGreeting(channel as { send(input: { content: string }): Promise<unknown> }, newMember.id, config.boosterGreetingChannelId).catch((err) => {
|
||||||
|
logger.error("Failed to send boost greeting", { error: String(err), userId: newMember.id });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle boost loss (existing behaviour)
|
// Handle boost loss (existing behaviour)
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { sendBoostGreeting } from "./boostGreeting";
|
||||||
|
|
||||||
|
describe("sendBoostGreeting", () => {
|
||||||
|
test("sends boost greeting to the given channel", async () => {
|
||||||
|
const sent: string[] = [];
|
||||||
|
const channel = {
|
||||||
|
send: async (input: { content: string }): Promise<void> => {
|
||||||
|
sent.push(input.content);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await sendBoostGreeting(channel, "user-123", "channel-456");
|
||||||
|
|
||||||
|
expect(sent.length).toBe(1);
|
||||||
|
expect(sent[0]).toContain("Thank you for boosting");
|
||||||
|
expect(sent[0]).toContain("<@user-123>");
|
||||||
|
expect(sent[0]).toContain("/booster-role claim");
|
||||||
|
expect(sent[0]).toContain("<#channel-456>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles different user and channel IDs", async () => {
|
||||||
|
const sent: string[] = [];
|
||||||
|
const channel = {
|
||||||
|
send: async (input: { content: string }): Promise<void> => {
|
||||||
|
sent.push(input.content);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await sendBoostGreeting(channel, "other-user", "other-channel");
|
||||||
|
|
||||||
|
expect(sent[0]).toContain("<@other-user>");
|
||||||
|
expect(sent[0]).toContain("<#other-channel>");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,50 +1,19 @@
|
|||||||
import { logger } from "../../logger";
|
import { logger } from "../../logger";
|
||||||
|
|
||||||
type GuildTextChannel = {
|
|
||||||
send(input: { content: string }): Promise<unknown>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GuildMemberLike = {
|
|
||||||
id: string;
|
|
||||||
user?: { id: string };
|
|
||||||
guild: {
|
|
||||||
id: string;
|
|
||||||
channels: {
|
|
||||||
cache: {
|
|
||||||
get(channelId: string): GuildTextChannel | undefined;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a welcome message to the configured greeting channel.
|
* Sends a welcome message via the given channel when a member newly
|
||||||
* Call this after confirming the member newly gained the booster eligibility role.
|
* acquires the booster eligibility role (i.e. just boosted the server).
|
||||||
*/
|
*/
|
||||||
export async function sendBoostGreeting(
|
export async function sendBoostGreeting(
|
||||||
member: GuildMemberLike,
|
channel: { send(input: { content: string }): Promise<unknown> },
|
||||||
|
userId: string,
|
||||||
greetingChannelId: string,
|
greetingChannelId: string,
|
||||||
): Promise<void> {
|
): 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,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mention = member.user?.id ?? member.id;
|
|
||||||
const message =
|
const message =
|
||||||
`🎉 Thank you for boosting <@${mention}>! ` +
|
`🎉 Thank you for boosting <@${userId}>! ` +
|
||||||
`You can now claim a custom role using \`/booster-role claim\` in <#${greetingChannelId}>.`;
|
`You can now claim a custom role using \`/booster-role claim\` in <#${greetingChannelId}>.`;
|
||||||
|
|
||||||
await channel.send({ content: message });
|
await channel.send({ content: message });
|
||||||
|
|
||||||
logger.info("Boost greeting sent", {
|
logger.info("Boost greeting sent", { userId, channelId: greetingChannelId });
|
||||||
userId: member.id,
|
|
||||||
guildId: member.guild.id,
|
|
||||||
channelId: greetingChannelId,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user