From 530b943790c8e87f1b3c4a88982afd86cc8f959b Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Fri, 20 May 2022 16:27:28 +0700 Subject: [PATCH] Finish embeds and commands for getting raffle winners --- Bot/Admin.fs | 89 ++++++++++++++++++++++++++++++++++++++++++-- Bot/Bot.fs | 1 + Bot/InviteTracker.fs | 1 - 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/Bot/Admin.fs b/Bot/Admin.fs index 24d2d5d..7d12971 100644 --- a/Bot/Admin.fs +++ b/Bot/Admin.fs @@ -26,7 +26,8 @@ let handleGuildDownloadReady _ (event : GuildDownloadCompletedEventArgs) = let ( _ , adminRole ) = guild.Roles.TryGetValue(GuildEnvironment.roleAdmin) let permission = DiscordApplicationCommandPermission(adminRole, true) - let commands = commands |> Seq.map (fun com -> DiscordGuildApplicationCommandPermissions(com.Id, [ permission ])) + let commands = commands |> Seq.map (fun com -> + DiscordGuildApplicationCommandPermissions(com.Id, [ permission ])) do! guild.BatchEditApplicationCommandPermissionsAsync(commands) |> Async.AwaitTask |> Async.Ignore return () } :> Task @@ -99,6 +100,12 @@ let getCsvFromTotalInvites (users : {| Username : string ; DiscordId : uint64 ; |> String.concat "\n" |> (+) "Discord Id Num,Username,Total Invites\n" +let getCsvFromRaffleTickets (users : {| Id : uint64 ; Name : string ; TicketsOwned : int |} seq) = + users + |> Seq.map (fun user -> $"{user.Id},{user.Name},{user.TicketsOwned}") + |> String.concat "\n" + |> (+) "Discord Id Num,Username,Tickets Owned\n" + let getUserInvites userIds = GuildEnvironment.connectionString |> Sql.connect @@ -146,10 +153,80 @@ let getUserInvitesFromReactions (channel : DiscordChannel) (message : string) (c dict.Add("users.csv", ms) builder.AddFiles(dict) |> ignore do! ctx.FollowUp(builder) - with ex -> - printfn $"exception {ex.Message}" + with ex -> printfn $"exception {ex.Message}" } :> Task +let getRaffleWinners count (ctx : IDiscordContext) = + task { + do! Messaging.defer ctx + let! raffleItems = + [ "BACKALLEY1" ; "BACKALLEY2" ; "BACKALLEY3" ] + |> List.map DbService.getStoreItems + |> Async.Parallel + + let buttons = + raffleItems + |> Seq.concat + |> Seq.map (fun item -> + DiscordButtonComponent(ButtonStyle.Primary, $"GetRaffleWinner-{item.Item.Id}-{count}", $"{item.Item.Name}") + :> DiscordComponent) + + let builder = DiscordFollowupMessageBuilder().AsEphemeral(true) + buttons + |> Seq.chunkBySize 5 + |> Seq.iter (fun btns -> builder.AddComponents(btns) |> ignore) + builder.Content <- "Click on the respective item" + + do! ctx.FollowUp builder + } :> Task + +let pickRaffleWinners (ctx : IDiscordContext) = + task { + do! Messaging.defer ctx + let tokens = ctx.GetInteractionId().Split('-') + let itemId = tokens.[1] + let count = int tokens.[2] + let! winners = + DbService.connStr + |> Sql.connect + |> Sql.parameters [ "iid", Sql.string itemId ; "winner_count" , Sql.int count] + |> Sql.query """ + SELECT discord_id, count(*) AS tickets_owned, display_name + FROM "user" + INNER JOIN inventory_item ii ON "user".id = ii.user_id + WHERE ii.item_id = @iid + GROUP BY discord_id, display_name + ORDER BY random() + LIMIT @winner_count; + """ + |> Sql.executeAsync (fun read -> + {| Id = read.string "discord_id" |> uint64 + Name = read.string "display_name" + TicketsOwned = read.int "tickets_owned"|}) + |> Async.AwaitTask + + let csv = getCsvFromRaffleTickets winners + let builder = DiscordFollowupMessageBuilder().AsEphemeral(true) + use ms = new MemoryStream(Text.Encoding.ASCII.GetBytes(csv)) :> Stream + let dict = Collections.Generic.Dictionary() + dict.Add("users.csv", ms) + builder.AddFiles(dict) |> ignore + + do! ctx.FollowUp builder + } :> Task + +let handleButtonEvent _ (event : ComponentInteractionCreateEventArgs) = + let eventCtx = DiscordEventContext event :> IDiscordContext + match event.Id with + | id when id.StartsWith("GetRaffleWinner") -> pickRaffleWinners eventCtx + | _ -> + task { + let builder = DiscordInteractionResponseBuilder() + builder.IsEphemeral <- true + builder.Content <- $"Incorrect Action identifier {eventCtx.GetInteractionId()}" + do! eventCtx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask + } + type AdminBot() = inherit ApplicationCommandModule () @@ -194,4 +271,10 @@ type AdminBot() = [] messageId : string) = enforceAdmin (DiscordInteractionContext ctx) (getUserInvitesFromReactions channel messageId) + [] + [] + member this.GetRaffleWinners (ctx : InteractionContext, [] count : int64) = + enforceAdmin (DiscordInteractionContext ctx) (getRaffleWinners count) + + diff --git a/Bot/Bot.fs b/Bot/Bot.fs index fea8baa..e756c8a 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -84,6 +84,7 @@ inviterBot.add_MessageCreated(AsyncEventHandler(InviteTracker.handleMessageCreat slotsBot.add_ComponentInteractionCreated(AsyncEventHandler(SlotMachine.handleButton)) slotsBot.add_GuildDownloadCompleted(AsyncEventHandler(SlotMachine.handleGuildDownloadCompleted)) slotsBot.add_MessageCreated(AsyncEventHandler(SlotMachine.handleMessageCreated)) +adminBot.add_ComponentInteractionCreated(AsyncEventHandler(Admin.handleButtonEvent)) let asdf _ (event : DSharpPlus.EventArgs.InteractionCreateEventArgs) = async { diff --git a/Bot/InviteTracker.fs b/Bot/InviteTracker.fs index c0ab1d8..c228d81 100644 --- a/Bot/InviteTracker.fs +++ b/Bot/InviteTracker.fs @@ -8,7 +8,6 @@ open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open Degenz.Messaging open Npgsql.FSharp -open Solnet.Rpc open Solnet.Wallet let connStr = GuildEnvironment.connectionString