discord-bot-game/Bot/Scripts/Whitelist.fsx

147 lines
5.4 KiB
Plaintext

#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