diff --git a/Bot/Bot.fs b/Bot/Bot.fs index 17f5609..f605719 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -62,6 +62,7 @@ hackerBattleBot.add_ComponentInteractionCreated(AsyncEventHandler(HackerBattle.h storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleStoreEvents)) stealBot.add_ComponentInteractionCreated(AsyncEventHandler(Thief.handleStealButton)) inviterBot.add_GuildMemberAdded(AsyncEventHandler(InviteTracker.handleGuildMemberAdded)) +inviterBot.add_ComponentInteractionCreated(AsyncEventHandler(InviteTracker.handleWhitelist)) //inviterBot.add_GuildMemberRemoved(AsyncEventHandler(InviteTracker.handleGuildMemberRemoved)) let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEventArgs) = @@ -83,6 +84,8 @@ let asdf (_ : DiscordClient) (event : DSharpPlus.EventArgs.InteractionCreateEven //if guild <> 922419263275425832uL then // Trainer.sendInitialEmbed hackerBattleBot +InviteTracker.sendInitialEmbed inviterBot + hackerBattleBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously GuildEnvironment.botUserHackerBattle <- Some hackerBattleBot.CurrentUser diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 7efd0fa..be9119d 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -23,11 +23,12 @@ let tokenInviter = getVar "TOKEN_INVITER" let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE" let channelTraining = getId "CHANNEL_TRAINING" let channelArmory = getId "CHANNEL_ARMORY" -//let channelBackAlley = getId "CHANNEL_BACKALLEY" let channelBattle = getId "CHANNEL_BATTLE" +let channelWelcome = getId "CHANNEL_WELCOME" +let channelWhitelist = getId "CHANNEL_WHITELIST" +//let channelBackAlley = getId "CHANNEL_BACKALLEY" //let channelMarket = getId "CHANNEL_MARKET" //let channelAccessoryShop = getId "CHANNEL_ACCESSORIES" -let channelWelcome = getId "CHANNEL_WELCOME" //let channelThievery = getId "CHANNEL_THIEVERY" let botIdHackerBattle = getId "BOT_HACKER_BATTLE" @@ -35,6 +36,7 @@ let botIdArmory = getId "BOT_ARMORY" //let botInviter = getId "BOT_INVITER" let roleTrainee = getId "ROLE_TRAINEE" let rolePrisoner = getId "ROLE_PRISONER" +let roleWhitelist = getId "ROLE_WHITELIST" let mutable botUserHackerBattle : DiscordUser option = None let mutable botUserArmory : DiscordUser option = None diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index c221eb8..40a0074 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -11,6 +11,7 @@ open Npgsql.FSharp let connStr = GuildEnvironment.connectionString let InviteRewardAmount = 100 +let WhitelistInviteRequirement = 5 type Invite = { Code : string @@ -22,6 +23,7 @@ let getInvites () = async { let! invites = connStr |> Sql.connect + // TODO: Invites shouldn't expire anymore |> Sql.query """ SELECT code, inviter, count FROM invite WHERE created_at > (current_timestamp at time zone 'utc') - interval '1 day' @@ -121,7 +123,7 @@ let getInvitedUsers userId = let createGuildInvite (ctx : IDiscordContext) = task { let channel = ctx.GetGuild().Channels.[GuildEnvironment.channelWelcome] - let! invite = channel.CreateInviteAsync(max_age = 86400, unique = true) + let! invite = channel.CreateInviteAsync(max_age = 0, unique = true) // When a player generates an invite code but it hasn't expired, it generates the same code, creating a duplicate entry // so catch the exception thrown because the code column is unique @@ -132,20 +134,21 @@ let createGuildInvite (ctx : IDiscordContext) = printfn "%A" ex.Message () - let embed = + let header = DiscordEmbedBuilder() - .WithDescription($"**⏀ | Your Mission:**\nCopy this link & share it with Degenz you want to `/recruit`.\n\n" + - $"**⌼ | Your Reward:**\n`Earn {InviteRewardAmount} $GBT` 💰 for every Degen you've `/recruited`." + - $"```https://discord.gg/{invite.Code}```") + .WithDescription($"**⏀ | Your Mission:**\nCopy the link & share it with Degenz you want to `/recruit`.\n\n" + + $"**⌼ | Your Reward:**\n`Earn {InviteRewardAmount} $GBT` 💰 for every Degen you've `/recruited`.") .WithImageUrl("https://pbs.twimg.com/profile_banners/1449270642340089856/1640071520/1500x500") // .WithImageUrl("https://s7.gifyu.com/images/Resistance_Poster_Final_1.jpg") .WithTitle("Recruitment") + let footer = + DiscordEmbedBuilder() + .WithDescription($"```https://discord.gg/{invite.Code}```") let msg = DiscordInteractionResponseBuilder() - .AddEmbed(embed) + .AddEmbeds([ header.Build() ; footer.Build() ]) .AsEphemeral(true) -// .WithContent($"https://discord.gg/{invite.Code}") do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) } @@ -238,6 +241,58 @@ let handleGuildMemberAdded _ (eventArgs : GuildMemberAddEventArgs) = // do! removeInvitedUser eventArgs.Member.Id // } :> Task +let sendInitialEmbed (client : DiscordClient) = + async { + try + let! channel = client.GetChannelAsync(GuildEnvironment.channelWhitelist) |> Async.AwaitTask + let builder = DiscordMessageBuilder() + let embed = DiscordEmbedBuilder() + embed.ImageUrl <- "https://securitygladiators.com/wp-content/uploads/2020/09/Whitelist-Website-Featured-Image.jpg" + builder.AddEmbed embed |> ignore + builder.Content <- "Click on the button to get whitelist!" + let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-1", $"Gimme") :> DiscordComponent + builder.AddComponents [| button |] |> ignore + do! channel.SendMessageAsync(builder) + |> Async.AwaitTask + |> Async.Ignore + with e -> + printfn $"Error trying to get channel {GuildEnvironment.channelTraining}\n\n{e.Message}" + } |> Async.RunSynchronously + +type WhitelistResult = + | NotEnoughInvites of currentAmount : int + | Granted of DiscordRole + | AlreadyWhitelisted + +let tryGrantWhitelist (ctx : IDiscordContext) = + async { + let user = ctx.GetDiscordMember() + let role = ctx.GetGuild().GetRole(GuildEnvironment.roleWhitelist) + if Seq.contains role user.Roles + then return AlreadyWhitelisted + else + let! total = getInviteAttributions user.Id + if total >= WhitelistInviteRequirement then + return Granted role + else + return NotEnoughInvites total + } + +let handleWhitelist (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = + task { + let ctx = DiscordEventContext event :> IDiscordContext + let builder = DiscordInteractionResponseBuilder().AsEphemeral(true) + match! tryGrantWhitelist ctx with + | AlreadyWhitelisted -> + builder.Content <- "You are already whitelisted" + | NotEnoughInvites total -> + builder.Content <- $"You need to invite more people into the server. Please invite {WhitelistInviteRequirement - total} more people to get Whitelist" + | Granted role -> + do! ctx.GetDiscordMember().GrantRoleAsync(role) + builder.Content <- "You have been granted whitelist" + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) + } :> Task + type Inviter() = inherit ApplicationCommandModule ()