Admin commands to get invites table

This commit is contained in:
Joseph Ferano 2022-04-25 10:24:28 +07:00
parent f04c61a3ab
commit bdb2a1aa13

View File

@ -7,7 +7,6 @@ open DSharpPlus
open DSharpPlus.Entities open DSharpPlus.Entities
open DSharpPlus.EventArgs open DSharpPlus.EventArgs
open DSharpPlus.SlashCommands open DSharpPlus.SlashCommands
open DSharpPlus.SlashCommands.Attributes
open Degenz.Messaging open Degenz.Messaging
open Npgsql.FSharp open Npgsql.FSharp
@ -37,10 +36,11 @@ let sendEmbed embed (ctx : IDiscordContext) =
do! Messaging.sendSimpleResponse ctx "Sent!" do! Messaging.sendSimpleResponse ctx "Sent!"
} :> Task } :> Task
let getAllReactions (msg : DiscordMessage) = let getAllReactions (msg : DiscordMessage) (ctx : IDiscordContext) : Task<DiscordUser seq> =
task { task {
let mutable listOfUsers = ResizeArray<DiscordUser>(512) let mutable listOfUsers = ResizeArray<DiscordUser>(512)
let mutable emojiCount = 0
for reaction in msg.Reactions do for reaction in msg.Reactions do
let mutable count = 0 let mutable count = 0
for r in 0..reaction.Count / 100 do for r in 0..reaction.Count / 100 do
@ -50,12 +50,18 @@ let getAllReactions (msg : DiscordMessage) =
else else
msg.GetReactionsAsync(reaction.Emoji, 100) |> Async.AwaitTask |> Async.RunSynchronously msg.GetReactionsAsync(reaction.Emoji, 100) |> Async.AwaitTask |> Async.RunSynchronously
listOfUsers.AddRange(rs) listOfUsers.AddRange(rs)
printfn $"Emoji {reaction.Emoji.Name} - {reaction.Count} - Total users: {rs.Count} - Page {count}"
count <- count + 1 count <- count + 1
do! Async.Sleep 2000 let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
builder.Content <- $"Reading {emojiCount + 1} out of {msg.Reactions.Count}: {reaction.Emoji.Name} with {reaction.Count} reactions"
do! ctx.FollowUp builder
do! Async.Sleep 1800
emojiCount <- emojiCount + 1
return return listOfUsers
listOfUsers }
let getCsvFromUsersList users =
users
|> List.ofSeq |> List.ofSeq
|> List.map (fun (user : DiscordUser) -> |> List.map (fun (user : DiscordUser) ->
{| Id = user.Id ; FullName = $"{user.Username}#{user.Discriminator}" |}) {| Id = user.Id ; FullName = $"{user.Username}#{user.Discriminator}" |})
@ -63,12 +69,17 @@ let getAllReactions (msg : DiscordMessage) =
|> List.map (fun user -> $"{user.Id},{user.FullName}") |> List.map (fun user -> $"{user.Id},{user.FullName}")
|> String.concat "\n" |> String.concat "\n"
|> (+) "Discord Id Num,Username\n" |> (+) "Discord Id Num,Username\n"
}
let getCsvFromTotalInvites (users : {| Username : string ; DiscordId : uint64 ; TotalInvites : int |} seq) =
users
|> Seq.map (fun user -> $"{user.DiscordId},{user.Username},{user.TotalInvites}")
|> String.concat "\n"
|> (+) "Discord Id Num,Username,Total Invites\n"
let getUserInvites userIds = let getUserInvites userIds =
GuildEnvironment.connectionString GuildEnvironment.connectionString
|> Sql.connect |> Sql.connect
|> Sql.parameters [ "dids" , Sql.stringArray (userIds |> List.toArray) ] |> Sql.parameters [ "dids" , Sql.stringArray (userIds |> Seq.toArray) ]
|> Sql.query """ |> Sql.query """
SELECT usr.display_name, inviter, count(invite_id) AS total_invites FROM invite SELECT usr.display_name, inviter, count(invite_id) AS total_invites FROM invite
JOIN invited_user iu ON invite.id = iu.invite_id JOIN invited_user iu ON invite.id = iu.invite_id
@ -77,19 +88,19 @@ let getUserInvites userIds =
GROUP BY inviter, usr.display_name GROUP BY inviter, usr.display_name
ORDER BY total_invites DESC; 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" |}) |> Sql.executeAsync (fun read -> {| Username = read.string "display_name" ; DiscordId = read.string "inviter" |> uint64 ; TotalInvites = read.int "total_invites" |})
|> Async.AwaitTask |> Async.AwaitTask
let getUsersFromMessageReactions (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) =
let getMessageReactions (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) =
task { task {
do! Messaging.defer ctx do! Messaging.defer ctx
let ( result , mId ) = UInt64.TryParse(message) let ( result , mId ) = UInt64.TryParse(message)
if result then if result then
let! msg = channel.GetMessageAsync(message |> uint64) |> Async.AwaitTask let! msg = channel.GetMessageAsync(message |> uint64) |> Async.AwaitTask
let! reactions = getAllReactions msg let! reactions = getAllReactions msg ctx
let builder = DiscordFollowupMessageBuilder() let csv = getCsvFromUsersList reactions
use ms = new MemoryStream(Text.Encoding.ASCII.GetBytes(reactions)) :> Stream let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
use ms = new MemoryStream(Text.Encoding.ASCII.GetBytes(csv)) :> Stream
let dict = Collections.Generic.Dictionary() let dict = Collections.Generic.Dictionary()
dict.Add("users.csv", ms) dict.Add("users.csv", ms)
builder.AddFiles(dict) |> ignore builder.AddFiles(dict) |> ignore
@ -98,16 +109,19 @@ let getMessageReactions (channel : DiscordChannel) (message : string) (ctx : IDi
do! Messaging.sendSimpleResponse ctx $"The message ID provided was not a valid: {message}" do! Messaging.sendSimpleResponse ctx $"The message ID provided was not a valid: {message}"
} :> Task } :> Task
//let getUserInvitesTable (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) = let getUserInvitesFromReactions (channel : DiscordChannel) (message : string) (ctx : IDiscordContext) =
let getUserInvitesTable (ctx : IDiscordContext) =
task { task {
do! Messaging.defer ctx do! Messaging.defer ctx
printfn $"Trying this out" let! msg = channel.GetMessageAsync(message |> uint64) |> Async.AwaitTask
let! users = getAllReactions msg ctx
try try
let! invites = getUserInvites [ "90588624566886400" ; "822834227467780136" ] let! invites = getUserInvites (users |> Seq.map (fun u -> string u.Id))
printfn $"Total Invites? \n{invites}" let csv = getCsvFromTotalInvites (invites)
let builder = DiscordFollowupMessageBuilder() let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
builder.Content <- $"%A{invites}" 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) do! ctx.FollowUp(builder)
with ex -> with ex ->
printfn $"exception {ex.Message}" printfn $"exception {ex.Message}"
@ -139,10 +153,12 @@ type AdminBot() =
member this.GetMessageReactions (ctx : InteractionContext, member this.GetMessageReactions (ctx : InteractionContext,
[<Option("channel", "The channel where the message is")>] channel : DiscordChannel, [<Option("channel", "The channel where the message is")>] channel : DiscordChannel,
[<Option("message-id", "The ID of the message with all the reactions")>] messageId : string) = [<Option("message-id", "The ID of the message with all the reactions")>] messageId : string) =
enforceAdmin (DiscordInteractionContext ctx) (getMessageReactions channel messageId) enforceAdmin (DiscordInteractionContext ctx) (getUsersFromMessageReactions channel messageId)
[<SlashCommand("admin-get-invites-table", "Invites Table", false)>] [<SlashCommand("admin-get-invites-table", "Invites Table", false)>]
member this.GetInvitesTable (ctx : InteractionContext) = member this.GetInvitesFromReactedMessages (ctx : InteractionContext,
enforceAdmin (DiscordInteractionContext ctx) getUserInvitesTable [<Option("channel", "The channel where the message is")>] channel : DiscordChannel,
[<Option("message-id", "The ID of the message with all the reactions")>] messageId : string) =
enforceAdmin (DiscordInteractionContext ctx) (getUserInvitesFromReactions channel messageId)