From 25f3c0b89daa86aceda10a600655db8250602156 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 3 Mar 2022 12:43:13 +0700 Subject: [PATCH] Add helper invite commands --- Bot/Bot.fs | 4 -- Bot/Games/HackerBattle.fs | 86 +++++++++++++++++++++++++++++++++++---- Bot/GuildEnvironment.fs | 1 + Bot/InviteTracker.fs | 22 ++++++++-- 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/Bot/Bot.fs b/Bot/Bot.fs index 3d820a4..9d9a3d3 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -58,10 +58,6 @@ stealCommands.RegisterCommands(guild); hackerBattleBot.add_ComponentInteractionCreated(AsyncEventHandler(HackerBattle.handleButtonEvent)) storeBot.add_ComponentInteractionCreated(AsyncEventHandler(Store.handleStoreEvents)) stealBot.add_ComponentInteractionCreated(AsyncEventHandler(Thief.handleStealButton)) -hackerBattleBot.add_InviteCreated((fun client args -> - task { - do! InviteTracker.createInvite args.Invite.Inviter.Id args.Invite.Code |> Async.Ignore - })) hackerBattleBot.add_GuildMemberAdded(AsyncEventHandler(fun client ea -> task { let! guildInvites = ea.Guild.GetInvitesAsync() diff --git a/Bot/Games/HackerBattle.fs b/Bot/Games/HackerBattle.fs index e5d0826..302861a 100644 --- a/Bot/Games/HackerBattle.fs +++ b/Bot/Games/HackerBattle.fs @@ -1,6 +1,7 @@ module Degenz.HackerBattle open System +open System.Text open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities @@ -242,16 +243,71 @@ let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEve do! eventCtx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } -let invite (ctx : IDiscordContext) = +let createInvite (ctx : IDiscordContext) = task { - let channel = ctx.GetGuild().GetChannel(927449884204867664uL) - let invite = channel.CreateInviteAsync(reason = "I MEAN WHY NOT") |> Async.AwaitTask |> Async.RunSynchronously + let channel = ctx.GetGuild().Channels.[GuildEnvironment.channelWelcome] + let! invite = channel.CreateInviteAsync(max_age = 259200) + do! InviteTracker.createInvite (ctx.GetDiscordMember().Id) invite.Code |> Async.Ignore - printfn "The invite code is %s" invite.Code + let embed = + DiscordEmbedBuilder() + .WithDescription($"Send this invite to your friend, when they join, they can type the `/enter-code` slash command") + .WithImageUrl("https://pbs.twimg.com/profile_banners/1449270642340089856/1640071520/1500x500") + .WithTitle("Invite Code") - do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, DiscordInteractionResponseBuilder().AsEphemeral(true).WithContent($"https://discord.gg/{invite.Code}")) |> Async.AwaitTask + let msg = + DiscordInteractionResponseBuilder() + .AddEmbed(embed) + .AsEphemeral(true) + .WithContent($"https://discord.gg/{invite.Code}") + + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) } +let listServerInvites (ctx : IDiscordContext) = task { + let! invites = ctx.GetGuild().GetInvitesAsync() + let sb = StringBuilder() + for invite in invites do + sb.AppendLine($"{invite.Inviter.Username} - {invite.Code}") |> ignore + let msg = + DiscordInteractionResponseBuilder() + .AsEphemeral(true) + .WithContent("Server Invites\n" + sb.ToString()) + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) +} + +let getAttributions (ctx : IDiscordContext) userId = task { + let! total = InviteTracker.getInviteAttributions(userId) + let msg = + DiscordInteractionResponseBuilder() + .AsEphemeral(true) + .WithContent($"<@{userId}> has invited {total} people") + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) +} + +let getInvitedUsers (ctx : IDiscordContext) userId = task { + let! users = InviteTracker.getInvitedUsers(userId) + let sb = StringBuilder() + for user in users do + sb.AppendLine($"<@{user}>") |> ignore + let msg = + DiscordInteractionResponseBuilder() + .AsEphemeral(true) + .WithContent($"<@{userId}> has invited the following people:\n{sb}") + do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg) +} + +let clearInvites (ctx : IDiscordContext) = task { + let! invites = ctx.GetGuild().GetInvitesAsync() + do! + invites + |> Seq.map (fun invite -> invite.DeleteAsync() |> Async.AwaitTask) + |> Async.Parallel + |> Async.Ignore +} + + + //let invite (ctx : IDiscordContext) = // task { // let code = Guid.NewGuid().ToString().Substring(0, 7) @@ -296,9 +352,25 @@ type HackerGame() = do! Messaging.sendSimpleResponse ctx msg } - [] + [] member this.CreateInvite (ctx : InteractionContext) = - invite (DiscordInteractionContext ctx) + createInvite (DiscordInteractionContext ctx) + + [] + member this.ListServerInvites (ctx : InteractionContext) = + listServerInvites (DiscordInteractionContext ctx) + + [] + member this.getAttributions (ctx : InteractionContext, [] user : DiscordUser) = + getAttributions (DiscordInteractionContext ctx) user.Id + + [] + member this.ListInvitedPeople (ctx : InteractionContext, [] user : DiscordUser) = + getInvitedUsers (DiscordInteractionContext ctx) user.Id + + [] + member this.ClearInvites (ctx : InteractionContext) = + clearInvites (DiscordInteractionContext ctx) [] member this.Arsenal (ctx : InteractionContext) = diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 0221b09..4dbc87a 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -25,6 +25,7 @@ let channelBackAlley = getId "CHANNEL_BACKALLEY" let channelBattle = getId "CHANNEL_BATTLE" 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" diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index 7a6412e..7eb8795 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -16,7 +16,10 @@ let getInvites () = async { let! invites = connStr |> Sql.connect - |> Sql.query "SELECT code, inviter, count FROM invite" + |> Sql.query """ + SELECT code, inviter, count FROM invite + WHERE created_at > (current_timestamp at time zone 'utc') - interval '3 day' + """ |> Sql.executeAsync (fun read -> { Code = read.string "code" Inviter = read.string "inviter" |> uint64 @@ -49,10 +52,21 @@ let addInvitedUser did code = ] |> Async.AwaitTask -let getInviteAttributions user = +let getInviteAttributions userId = connStr |> Sql.connect - |> Sql.parameters [ "did" , Sql.string (string user.DiscordId) ] + |> Sql.parameters [ "did" , Sql.string (string userId) ] |> Sql.query "SELECT sum(count) AS total FROM invite WHERE inviter = @did" - |> Sql.executeAsync (fun read -> read.int "total") + |> Sql.executeRowAsync (fun read -> read.int "total") + |> Async.AwaitTask + +let getInvitedUsers userId = + connStr + |> Sql.connect + |> Sql.parameters [ "did" , Sql.string (string userId) ] + |> Sql.query """ + WITH invite AS (SELECT id FROM invite WHERE inviter = @did) + SELECT discord_id FROM invited_user, invite WHERE invite.id = invited_user.invite_id + """ + |> Sql.executeAsync (fun read -> read.string "discord_id" |> uint64) |> Async.AwaitTask