Skip to content

Commit

Permalink
Add claim league patreon benefits button (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
rorro authored Nov 21, 2024
1 parent 33c680f commit 4fa4bc2
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 7 deletions.
15 changes: 12 additions & 3 deletions src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import {
} from 'discord.js';
import config from './config';
import * as router from './commands/router';
import { PATREON_MODAL_ID, handlePatreonModalSubmit, setupPatreonTrigger } from './patreon-trigger';
import {
PATREON_LEAGUE_MODAL_ID,
handlePatreonLeagueModalSubmit,
PATREON_MODAL_ID,
handlePatreonModalSubmit,
setupPatreonTrigger
} from './patreon-trigger';
import { handleButtonInteraction } from './utils/buttonInteractions';

const CACHED_ACTIVE_USER_IDS = new Set<string>(config.discord.cache.excludeUsers);
Expand Down Expand Up @@ -80,8 +86,11 @@ class Bot {
return;
}

if (interaction.isModalSubmit() && interaction.customId === PATREON_MODAL_ID) {
handlePatreonModalSubmit(interaction);
if (interaction.isModalSubmit()) {
const customId = interaction.customId;

if (customId === PATREON_MODAL_ID) handlePatreonModalSubmit(interaction);
else if (customId === PATREON_LEAGUE_MODAL_ID) handlePatreonLeagueModalSubmit(interaction);
return;
}

Expand Down
4 changes: 3 additions & 1 deletion src/content/patreon-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ The avatar and banner size guide can be found [here](https://www.figma.com/desig
# How to claim your benefits

After subscribing to our [Patreon](https://wiseoldman.net/patreon), you should connect your Discord account on Patreon (
see a guide [here](https://support.patreon.com/hc/en-us/articles/212052266-Getting-Discord-access>)), and then you can click the button below to claim your benefits.
see a guide [here](https://support.patreon.com/hc/en-us/articles/212052266-Getting-Discord-access)), and then you can click the button below to claim your benefits.

Note: If you'd like to also claim these benefits for your Leagues website group, click the Leagues button below, and make sure to insert the correct (league) group ID.
93 changes: 91 additions & 2 deletions src/patreon-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import {
} from 'discord.js';
import config from './config';
import { hasRole, sendModLog } from './utils';
import { claimBenefits } from './services/wiseoldman';
import { claimBenefits, claimLeagueBenefits } from './services/wiseoldman';

export const PATREON_MODAL_ID = 'patreon-benefits-modal';
export const PATREON_LEAGUE_MODAL_ID = 'patreon-league-benefits-modal';

export const PATREON_TRIGGER_ID = 'patreon-benefits-trigger';
export const PATREON_LEAGUE_TRIGGER_ID = 'patreon-league-benefits-trigger';

const NOT_A_PATRON_ERROR_MESSAGE = `Only Patreon supporters can claim benefits, please consider helping fund the project at https://wiseoldman.net/patreon.\n\nIf you already are a Patreon supporter, make sure to connect your Discord account to your Patreon account.`;

Expand All @@ -40,7 +42,11 @@ export async function setupPatreonTrigger(client: Client) {
new ButtonBuilder()
.setCustomId(PATREON_TRIGGER_ID)
.setLabel('Claim Patreon Benefits')
.setStyle(ButtonStyle.Success)
.setStyle(ButtonStyle.Success),
new ButtonBuilder()
.setCustomId(PATREON_LEAGUE_TRIGGER_ID)
.setLabel('(🏆 Leagues) Claim Patreon Benefits')
.setStyle(ButtonStyle.Secondary)
);

const message = await patreonInfoChannel.send({ content, components: [actions] });
Expand Down Expand Up @@ -86,6 +92,45 @@ export async function handlePatreonTrigger(interaction: ButtonInteraction) {
interaction.showModal(modal);
}

export async function handlePatreonLeagueTrigger(interaction: ButtonInteraction) {
if (!interaction.member) return;

const member = interaction.member as GuildMember;

if (!hasRole(member, config.discord.roles.patreonSupporter)) {
await interaction.reply({ content: NOT_A_PATRON_ERROR_MESSAGE, ephemeral: true });
return;
}

const isTier2Supporter = hasRole(member, config.discord.roles.patreonSupporterT2);

const modal = new ModalBuilder()
.setCustomId(PATREON_LEAGUE_MODAL_ID)
.setTitle(`Claim League Benefits (Tier ${isTier2Supporter ? 2 : 1})`);

const usernameInput = new TextInputBuilder()
.setCustomId('username')
.setLabel('Your in-game username')
.setPlaceholder('Ex: Zezima')
.setMaxLength(12)
.setStyle(1)
.setRequired(true);

const groupIdInput = new TextInputBuilder()
.setCustomId('groupId')
.setLabel("Your League group's ID")
.setPlaceholder("Ex: 139 (Can be found on your group's page URL.)")
.setStyle(1);

modal.addComponents(new ActionRowBuilder<TextInputBuilder>().addComponents(usernameInput));

if (isTier2Supporter) {
modal.addComponents(new ActionRowBuilder<TextInputBuilder>().addComponents(groupIdInput));
}

interaction.showModal(modal);
}

export async function handlePatreonModalSubmit(interaction: ModalSubmitInteraction) {
const username = interaction.fields.getTextInputValue('username');

Expand Down Expand Up @@ -129,3 +174,47 @@ export async function handlePatreonModalSubmit(interaction: ModalSubmitInteracti
interaction.reply({ content: error.message, ephemeral: true });
}
}

export async function handlePatreonLeagueModalSubmit(interaction: ModalSubmitInteraction) {
const username = interaction.fields.getTextInputValue('username');

if (!username) {
interaction.reply({ content: '❌ Please provide your in-game username.', ephemeral: true });
return;
}

let groupId: number | undefined;

if (hasRole(interaction.member as GuildMember, config.discord.roles.patreonSupporterT2)) {
const groupIdValue = interaction.fields.getTextInputValue('groupId');
const isInteger = typeof groupIdValue === 'string' && Number.isInteger(parseInt(groupIdValue));

if (!isInteger) {
interaction.reply({ content: '❌ Please provide a valid group ID.', ephemeral: true });
return;
}

groupId = parseInt(groupIdValue);
}

try {
await claimLeagueBenefits(interaction.user.id, username, groupId);

let successMessage = '✅ Your benefits have been claimed!';

if (groupId) {
successMessage += ` You can edit your group's images and social links on your group's edit page on the website.`;
}

interaction.reply({ content: successMessage, ephemeral: true });

sendModLog(
interaction.guild,
`${interaction.user} has claimed ${
groupId ? 'Tier 2' : 'Tier 1'
} (League) Patreon benefits for: \nUsername: ${username}${groupId ? `\nGroup id: ${groupId}` : ''}`
);
} catch (error) {
interaction.reply({ content: error.message, ephemeral: true });
}
}
18 changes: 18 additions & 0 deletions src/services/wiseoldman.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ const womClient = new WOMClient({
apiKey: config.apiKey
});

const leagueWomClient = new WOMClient({
userAgent: 'WiseOldMan Discord Bot',
baseAPIUrl: 'https://api.wiseoldman.net/league',
apiKey: config.apiKey
});

export function getCompetitionStatus(competition: CompetitionDetails | CompetitionListItem) {
const now = new Date();
const endsAt = competition.endsAt;
Expand Down Expand Up @@ -179,6 +185,18 @@ export async function claimBenefits(
});
}

export async function claimLeagueBenefits(
discordId: string,
username: string,
groupId?: number
): Promise<void> {
return leagueWomClient.putRequest(`/patrons/claim/${discordId}`, {
username,
groupId,
adminPassword: env.ADMIN_PASSWORD
});
}

/**
* Send an API request attempting to update a player's country
*/
Expand Down
9 changes: 8 additions & 1 deletion src/utils/buttonInteractions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {
EmbedBuilder
} from 'discord.js';
import config from '../config';
import { handlePatreonTrigger, PATREON_TRIGGER_ID } from '../patreon-trigger';
import {
handlePatreonTrigger,
PATREON_TRIGGER_ID,
PATREON_LEAGUE_TRIGGER_ID,
handlePatreonLeagueTrigger
} from '../patreon-trigger';
import { allowActions, blockActions } from '../services/wiseoldman';
import { CommandError } from './commands';

Expand All @@ -26,6 +31,8 @@ export async function handleButtonInteraction(interaction: ButtonInteraction): P

if (action === PATREON_TRIGGER_ID) {
handlePatreonTrigger(interaction);
} else if (action === PATREON_LEAGUE_TRIGGER_ID) {
handlePatreonLeagueTrigger(interaction);
} else if (action === Actions.BLOCK || action === Actions.ALLOW) {
await interaction.update({
components: [createConfirmationButtons(action, type as ModerationType, ipHash)]
Expand Down

0 comments on commit 4fa4bc2

Please sign in to comment.