feat(config): add BOOSTER_GREETING_CHANNEL_ID environment variable
This commit is contained in:
@@ -4,4 +4,5 @@ DISCORD_GUILD_ID=
|
|||||||
DATABASE_URL=postgresql://booster_role:booster_role@localhost:5432/booster_role
|
DATABASE_URL=postgresql://booster_role:booster_role@localhost:5432/booster_role
|
||||||
BOOSTER_ROLE_ANCHOR_ROLE_ID=
|
BOOSTER_ROLE_ANCHOR_ROLE_ID=
|
||||||
BOOSTER_ELIGIBILITY_ROLE_ID=1206431347925852162
|
BOOSTER_ELIGIBILITY_ROLE_ID=1206431347925852162
|
||||||
|
BOOSTER_GREETING_CHANNEL_ID=
|
||||||
LOG_LEVEL=info
|
LOG_LEVEL=info
|
||||||
|
|||||||
@@ -73,12 +73,13 @@ jobs:
|
|||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
BOOSTER_ROLE_ANCHOR_ROLE_ID: ${{ secrets.BOOSTER_ROLE_ANCHOR_ROLE_ID }}
|
BOOSTER_ROLE_ANCHOR_ROLE_ID: ${{ secrets.BOOSTER_ROLE_ANCHOR_ROLE_ID }}
|
||||||
BOOSTER_ELIGIBILITY_ROLE_ID: ${{ secrets.BOOSTER_ELIGIBILITY_ROLE_ID }}
|
BOOSTER_ELIGIBILITY_ROLE_ID: ${{ secrets.BOOSTER_ELIGIBILITY_ROLE_ID }}
|
||||||
|
BOOSTER_GREETING_CHANNEL_ID: ${{ secrets.BOOSTER_GREETING_CHANNEL_ID }}
|
||||||
LOG_LEVEL: ${{ secrets.LOG_LEVEL }}
|
LOG_LEVEL: ${{ secrets.LOG_LEVEL }}
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.VPS_HOST }}
|
host: ${{ secrets.VPS_HOST }}
|
||||||
username: ${{ secrets.VPS_USER }}
|
username: ${{ secrets.VPS_USER }}
|
||||||
key: ${{ secrets.VPS_SSH_KEY }}
|
key: ${{ secrets.VPS_SSH_KEY }}
|
||||||
envs: IMAGE_NAME,GHCR_USERNAME,GHCR_TOKEN,DISCORD_TOKEN,DISCORD_CLIENT_ID,DISCORD_GUILD_ID,DATABASE_URL,BOOSTER_ROLE_ANCHOR_ROLE_ID,BOOSTER_ELIGIBILITY_ROLE_ID,LOG_LEVEL
|
envs: IMAGE_NAME,GHCR_USERNAME,GHCR_TOKEN,DISCORD_TOKEN,DISCORD_CLIENT_ID,DISCORD_GUILD_ID,DATABASE_URL,BOOSTER_ROLE_ANCHOR_ROLE_ID,BOOSTER_ELIGIBILITY_ROLE_ID,BOOSTER_GREETING_CHANNEL_ID,LOG_LEVEL
|
||||||
script: |
|
script: |
|
||||||
set -eu
|
set -eu
|
||||||
mkdir -p /opt/booster-role
|
mkdir -p /opt/booster-role
|
||||||
@@ -91,6 +92,7 @@ jobs:
|
|||||||
DATABASE_URL=${DATABASE_URL:?DATABASE_URL is required}
|
DATABASE_URL=${DATABASE_URL:?DATABASE_URL is required}
|
||||||
BOOSTER_ROLE_ANCHOR_ROLE_ID=${BOOSTER_ROLE_ANCHOR_ROLE_ID}
|
BOOSTER_ROLE_ANCHOR_ROLE_ID=${BOOSTER_ROLE_ANCHOR_ROLE_ID}
|
||||||
BOOSTER_ELIGIBILITY_ROLE_ID=${BOOSTER_ELIGIBILITY_ROLE_ID:-1206431347925852162}
|
BOOSTER_ELIGIBILITY_ROLE_ID=${BOOSTER_ELIGIBILITY_ROLE_ID:-1206431347925852162}
|
||||||
|
BOOSTER_GREETING_CHANNEL_ID=${BOOSTER_GREETING_CHANNEL_ID}
|
||||||
LOG_LEVEL=${LOG_LEVEL:-info}
|
LOG_LEVEL=${LOG_LEVEL:-info}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -6,6 +6,7 @@ export type AppConfig = {
|
|||||||
boosterRoleAnchorRoleId: string | null;
|
boosterRoleAnchorRoleId: string | null;
|
||||||
boosterEligibilityRoleId: string;
|
boosterEligibilityRoleId: string;
|
||||||
boostCleanupIntervalMs: number;
|
boostCleanupIntervalMs: number;
|
||||||
|
boosterGreetingChannelId: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function loadConfig(env: Record<string, string | undefined> = process.env): AppConfig {
|
export function loadConfig(env: Record<string, string | undefined> = process.env): AppConfig {
|
||||||
@@ -16,7 +17,8 @@ export function loadConfig(env: Record<string, string | undefined> = process.env
|
|||||||
databaseUrl: env.DATABASE_URL ?? "postgresql://booster_role:booster_role@localhost:5432/booster_role",
|
databaseUrl: env.DATABASE_URL ?? "postgresql://booster_role:booster_role@localhost:5432/booster_role",
|
||||||
boosterRoleAnchorRoleId: env.BOOSTER_ROLE_ANCHOR_ROLE_ID ?? null,
|
boosterRoleAnchorRoleId: env.BOOSTER_ROLE_ANCHOR_ROLE_ID ?? null,
|
||||||
boosterEligibilityRoleId: env.BOOSTER_ELIGIBILITY_ROLE_ID ?? "1206431347925852162",
|
boosterEligibilityRoleId: env.BOOSTER_ELIGIBILITY_ROLE_ID ?? "1206431347925852162",
|
||||||
boostCleanupIntervalMs: Number(env.BOOST_CLEANUP_INTERVAL_MS) || 5 * 60 * 1000
|
boostCleanupIntervalMs: Number(env.BOOST_CLEANUP_INTERVAL_MS) || 5 * 60 * 1000,
|
||||||
|
boosterGreetingChannelId: env.BOOSTER_GREETING_CHANNEL_ID ?? null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { logger } from "../../logger";
|
||||||
|
|
||||||
|
type GuildTextChannel = {
|
||||||
|
send(input: { content: string }): Promise<unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type GuildMember = {
|
||||||
|
id: string;
|
||||||
|
guild: {
|
||||||
|
id: string;
|
||||||
|
channels: {
|
||||||
|
cache: {
|
||||||
|
get(channelId: string): GuildTextChannel | undefined;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
export async function sendBoostGreeting(
|
||||||
|
member: { id: string; guild: { id: string; channels: { cache: { get(channelId: string): { send(input: { content: string }): Promise<unknown> } | undefined } } } },
|
||||||
|
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 });
|
||||||
|
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}>.`
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info("Boost greeting sent", {
|
||||||
|
userId: member.user?.id ?? member.id,
|
||||||
|
guildId: member.guild.id,
|
||||||
|
channelId: greetingChannelId,
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user