#load "/home/joe/Development/DegenzGame/.paket/load/net6.0/main.group.fsx";; open Npgsql.FSharp open DSharpPlus open DSharpPlus.Entities open dotenv.net let prodEnv = DotEnv.Read(DotEnvOptions(envFilePaths = [ "./.prod.env" ])) let devEnv = DotEnv.Read(DotEnvOptions(envFilePaths = [ "./.dev.env" ])) let ( _ , prodConnStr )= prodEnv.TryGetValue("DATABASE_URL") let ( _ , devConnStr )= devEnv.TryGetValue("DATABASE_URL") let ( _ , adminBotToken )= prodEnv.TryGetValue("TOKEN_ADMINBOT") let botConfig = DiscordConfiguration() botConfig.TokenType <- TokenType.Bot botConfig.Intents <- DiscordIntents.All botConfig.Token <- adminBotToken printfn "Connecting" let bot = new DiscordClient(botConfig) bot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously printfn "Getting Guild" let prodGuild = 933888229776703559uL let guild = bot.GetGuildAsync(prodGuild) |> Async.AwaitTask |> Async.RunSynchronously printfn "Getting Members" let users = guild.GetAllMembersAsync() |> Async.AwaitTask |> Async.RunSynchronously printfn $"Total Members: {users.Count}" let firstDrop = users |> Seq.filter (fun u -> u.Roles |> Seq.exists (fun role -> role.Id = 978229149569286174uL)) |> Seq.distinct |> Seq.toList printfn $"{firstDrop.Length}" let changeStatus ids = devConnStr |> Sql.connect |> Sql.parameters [ "ids" , Sql.stringArray ids ] |> Sql.query """ UPDATE crypto SET status = 'Ready' WHERE discord_id = ANY (ARRAY[@ids]::varchar[]) AND status = 'Nothing' """ |> Sql.executeNonQuery changeStatus (firstDrop |> List.map (fun m -> string m.Id) |> List.toArray) let whitelisted = users |> Seq.filter (fun u -> u.Roles |> Seq.exists (fun role -> role.Name.Contains("Confirmed"))) |> Seq.toList printfn $"Total Whitelist Confirmed: {whitelisted.Length}" printfn "Getting Wallet Addresses:" let walletAddresses = prodConnStr |> Sql.connect |> Sql.query """ SELECT DISTINCT discord_id, display_name, wallet_address FROM "user" WHERE wallet_address IS NOT NULL; """ |> Sql.execute (fun reader -> {| Id = reader.string "discord_id" |> uint64 ; Name = reader.string "display_name" ; Wallet = reader.string "wallet_address" |}) printfn $"Total Wallet Addresses: {walletAddresses.Length}" let insert did name wallet wl og = devConnStr |> Sql.connect |> Sql.parameters [ "did" , Sql.string (string did) ; "name" , Sql.string name ; "wallet" , Sql.string wallet "wl" , Sql.bool wl ; "og" , Sql.bool og ] |> Sql.query """ INSERT INTO crypto(discord_id, display_name, wallet_address, has_wl, has_og) VALUES (@did, @name, @wallet, @wl, @og) ON CONFLICT (discord_id) DO UPDATE SET wallet_address = @wallet, has_wl = @wl , has_og = @og WHERE crypto.discord_id = @did AND crypto.status = 'Nothing'; """ |> Sql.executeNonQuery let updateUserWithWallet wallet wl og = devConnStr |> Sql.connect |> Sql.parameters [ "wallet" , Sql.string wallet ; "wl" , Sql.bool wl ; "og" , Sql.bool og ] |> Sql.query """ UPDATE crypto SET has_wl = @wl, has_og = @og WHERE crypto.wallet_address = @wallet AND crypto.status = 'Nothing'; """ |> Sql.executeNonQuery let prune ids = devConnStr |> Sql.connect |> Sql.parameters [ "ids" , Sql.stringArray ids ] |> Sql.query """ DELETE FROM crypto WHERE discord_id = ANY (ARRAY[@ids]::varchar[]) AND status = 'Nothing' """ |> Sql.executeNonQuery let getExisting () = devConnStr |> Sql.connect |> Sql.query """ SELECT discord_id, display_name, wallet_address FROM crypto """ |> Sql.execute (fun reader -> {| Id = reader.string "discord_id" |> uint64 ; Name = reader.string "display_name" ; Wallet = reader.string "wallet_address" |}) let walletExists wallet = let list = devConnStr |> Sql.connect |> Sql.parameters [ "wallet" , Sql.string wallet ] |> Sql.query """ SELECT wallet_address FROM crypto WHERE wallet_address = @wallet """ |> Sql.execute (fun reader -> reader.string "wallet_address") not list.IsEmpty printfn "Inserting" async { for user in whitelisted do for wa in walletAddresses do if wa.Id = user.Id then let hasWL = user.Roles |> Seq.exists (fun role -> role.Name = "Whitelist Confirmed") let hasOG = user.Roles |> Seq.exists (fun role -> role.Name = "OG Whitelist Confirmed") try if walletExists wa.Wallet then let _ = updateUserWithWallet wa.Wallet hasWL hasOG () else let _ = insert wa.Id wa.Name wa.Wallet hasWL hasOG () with ex -> printfn $"Huh? {ex.Message}" () () let existing = getExisting () let usersToFilter = existing |> List.filter (fun wa -> (whitelisted |> List.exists (fun wl -> wl.Id = wa.Id)) |> not) let toPrune = usersToFilter |> List.map (fun u -> u.Id |> string) |> List.toArray let _ = prune toPrune if toPrune.Length > 0 then printfn $"Pruning {toPrune.Length} users: {toPrune}" let existing = getExisting () printfn $"Total Users: {existing.Length}" } |> Async.RunSynchronously bot.DisconnectAsync() |> Async.AwaitTask |> Async.RunSynchronously