diff --git a/Bot/Admin.fs b/Bot/Admin.fs index 7ecfca0..d42e8b6 100644 --- a/Bot/Admin.fs +++ b/Bot/Admin.fs @@ -1,5 +1,7 @@ module Degenz.Admin +open System +open System.IO open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities @@ -7,6 +9,7 @@ open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open DSharpPlus.SlashCommands.Attributes open Degenz.Messaging +open Npgsql.FSharp type InitEmbeds = | Dojo = 0 @@ -34,6 +37,77 @@ let sendEmbed embed (ctx : IDiscordContext) = do! Messaging.sendSimpleResponse ctx "Sent!" } :> Task +let getAllReactions (msg : DiscordMessage) = + task { + let mutable listOfUsers = ResizeArray(512) + + for reaction in msg.Reactions do + let mutable count = 0 + for r in 0..reaction.Count / 100 do + let rs = + if count > 0 then + msg.GetReactionsAsync(reaction.Emoji, 100, listOfUsers.[listOfUsers.Count - 1].Id) |> Async.AwaitTask |> Async.RunSynchronously + else + msg.GetReactionsAsync(reaction.Emoji, 100) |> Async.AwaitTask |> Async.RunSynchronously + listOfUsers.AddRange(rs) + printfn $"Emoji {reaction.Emoji.Name} - {reaction.Count} - Total users: {rs.Count} - Page {count}" + count <- count + 1 + do! Async.Sleep 2000 + + return + listOfUsers + |> List.ofSeq + |> List.map (fun (user : DiscordUser) -> + {| Id = user.Id ; FullName = $"{user.Username}#{user.Discriminator}" |}) + |> List.distinctBy (fun u -> u.Id) + |> List.map (fun user -> $"{user.Id},{user.FullName}") + |> String.concat "\n" + |> (+) "Discord Id Num,Username\n" + } + +let getUserInvites userIds = + GuildEnvironment.connectionString + |> Sql.connect + |> Sql.parameters [ "dids" , Sql.stringArray (userIds |> List.toArray) ] + |> Sql.query """ + SELECT usr.display_name, inviter, count(invite_id) AS total_invites FROM invite + JOIN invited_user iu ON invite.id = iu.invite_id + JOIN "user" usr ON invite.inviter = usr.discord_id + WHERE iu.accepted = true AND inviter = ANY (ARRAY[@dids]::char varying[]) + GROUP BY inviter, usr.display_name + ORDER BY total_invites DESC; + """ + |> Sql.executeAsync (fun read -> {| Username = read.string "display_name" ; DiscordId = read.string "discord_id" |> uint64 ; TotalInvites = read.int "total_invites" |}) + |> Async.AwaitTask + + +let getMessageReactions (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) = + task { + do! Messaging.defer ctx + let ( result , mId ) = UInt64.TryParse(message) + if result then + let! msg = channel.GetMessageAsync(message |> uint64) |> Async.AwaitTask + let! reactions = getAllReactions msg + let builder = DiscordFollowupMessageBuilder() + use ms = new MemoryStream(Text.Encoding.ASCII.GetBytes(reactions)) :> Stream + let dict = Collections.Generic.Dictionary() + dict.Add("users.csv", ms) + builder.AddFiles(dict) |> ignore + do! ctx.FollowUp(builder) + else + do! Messaging.sendSimpleResponse ctx $"The message ID provided was not a valid: {message}" + } :> Task + +//let getUserInvitesTable (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) = +let getUserInvitesTable (ctx : IDiscordContext) = + task { + do! Messaging.defer ctx + let! invites = getUserInvites [ "90588624566886400" ; "822834227467780136" ] + let builder = DiscordFollowupMessageBuilder() + builder.Content <- $"%A{invites}" + do! ctx.FollowUp(builder) + } :> Task + type AdminBot() = inherit ApplicationCommandModule () @@ -46,7 +120,7 @@ type AdminBot() = [] member this.GetAttributions (ctx : InteractionContext, [] user : DiscordUser) = - enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getInvitedUsersForId) + enforceAdmin (DiscordInteractionContext ctx) (InviteTracker.getInvitedUsersForId user) [] member this.SetStock (ctx : InteractionContext, [] amount : int64) = @@ -56,4 +130,14 @@ type AdminBot() = member this.SendEmbedToChannel (ctx : InteractionContext, [] embed : InitEmbeds) = enforceAdmin (DiscordInteractionContext ctx) (sendEmbed embed) + [] + member this.GetMessageReactions (ctx : InteractionContext, + [] channel : DiscordChannel, + [] messageId : string) = + enforceAdmin (DiscordInteractionContext ctx) (getMessageReactions channel messageId) + + [] + member this.GetInvitesTable (ctx : InteractionContext) = + enforceAdmin (DiscordInteractionContext ctx) getUserInvitesTable +