Instrumentation
This commit is contained in:
parent
542adbf9a7
commit
694cab3e49
79
Bot/Analytics.fs
Normal file
79
Bot/Analytics.fs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
module Degenz.Analytics
|
||||||
|
|
||||||
|
open Mixpanel
|
||||||
|
|
||||||
|
let private mix = MixpanelClient(GuildEnvironment.tokenMixpanel)
|
||||||
|
|
||||||
|
let private track eventName id data =
|
||||||
|
let map =
|
||||||
|
[ "distinct_id" , box id
|
||||||
|
"guild_id" , box GuildEnvironment.guildId
|
||||||
|
"env" , box GuildEnvironment.environment ]
|
||||||
|
mix.TrackAsync(eventName, data @ map |> dict) |> Async.AwaitTask |> Async.Ignore
|
||||||
|
|
||||||
|
let invitedUserEntered inviteCode inviterId inviteeId inviterName inviteeName =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , inviterName
|
||||||
|
"invite_code" , inviteCode
|
||||||
|
"invitee_id" , inviteeId
|
||||||
|
"invitee_name" , inviteeName
|
||||||
|
]
|
||||||
|
track "Invited User Entered" inviterId data
|
||||||
|
|
||||||
|
let invitedUserAccepted inviteCode inviterId inviteeId inviterName inviteeName =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , inviterName
|
||||||
|
"invite_code" , inviteCode
|
||||||
|
"invitee_id" , inviteeId
|
||||||
|
"invitee_name" , inviteeName
|
||||||
|
]
|
||||||
|
track "Invited User Accepted" inviterId data
|
||||||
|
|
||||||
|
let recruitCommand origin id name channelId channelName =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"origin" , origin
|
||||||
|
"channel_id" , channelId
|
||||||
|
"channel_name" , channelName
|
||||||
|
]
|
||||||
|
track "Recruit Command Invoked" id data
|
||||||
|
|
||||||
|
let recruitLinkButton inviteCode id name channelId channelName =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"invite_code" , inviteCode
|
||||||
|
"channel_id" , channelId
|
||||||
|
"channel_name" , channelName
|
||||||
|
]
|
||||||
|
track "Recruited Command Invoked" id data
|
||||||
|
|
||||||
|
let recruitedCommand totalUsers id name channelId channelName =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"total_users_at_the_time" , totalUsers
|
||||||
|
"channel_id" , channelId
|
||||||
|
"channel_name" , channelName
|
||||||
|
]
|
||||||
|
track "Recruited Command Invoked" id data
|
||||||
|
|
||||||
|
let whiteListButton availability id name =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"availability" , availability
|
||||||
|
]
|
||||||
|
track "Recruited Command Invoked" id data
|
||||||
|
|
||||||
|
let whiteListPurchased amount id name =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"purchase_amount" , amount
|
||||||
|
]
|
||||||
|
track "Recruited Command Invoked" id data
|
||||||
|
|
||||||
|
let trainingDojoStep step id name =
|
||||||
|
let data = [
|
||||||
|
"user_display_name" , name
|
||||||
|
"step" , step
|
||||||
|
]
|
||||||
|
track "Recruited Command Invoked" id data
|
||||||
|
|
@ -6,13 +6,10 @@ open DSharpPlus
|
|||||||
open DSharpPlus.SlashCommands
|
open DSharpPlus.SlashCommands
|
||||||
open Degenz
|
open Degenz
|
||||||
open Emzi0767.Utilities
|
open Emzi0767.Utilities
|
||||||
open Mixpanel
|
|
||||||
//open Degenz.SlotMachine
|
//open Degenz.SlotMachine
|
||||||
|
|
||||||
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
|
||||||
|
|
||||||
let mix = MixpanelClient("SOMETOKEN")
|
|
||||||
|
|
||||||
let guild = GuildEnvironment.guildId
|
let guild = GuildEnvironment.guildId
|
||||||
|
|
||||||
let hackerBattleConfig = DiscordConfiguration()
|
let hackerBattleConfig = DiscordConfiguration()
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<Compile Include="GameTypes.fs" />
|
<Compile Include="GameTypes.fs" />
|
||||||
<Compile Include="GameHelpers.fs" />
|
<Compile Include="GameHelpers.fs" />
|
||||||
<Compile Include="DbService.fs" />
|
<Compile Include="DbService.fs" />
|
||||||
|
<Compile Include="Analytics.fs" />
|
||||||
<Compile Include="PlayerInteractions.fs" />
|
<Compile Include="PlayerInteractions.fs" />
|
||||||
<Compile Include="InviteTracker.fs" />
|
<Compile Include="InviteTracker.fs" />
|
||||||
<Compile Include="XP.fs" />
|
<Compile Include="XP.fs" />
|
||||||
|
@ -70,6 +70,7 @@ let handleTrainerStep1 (ctx : IDiscordContext) =
|
|||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
|
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
|
||||||
|
do! Analytics.trainingDojoStep "LFG" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
} |> Async.StartAsTask :> Task
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let defend (ctx : IDiscordContext) =
|
let defend (ctx : IDiscordContext) =
|
||||||
@ -79,6 +80,7 @@ let defend (ctx : IDiscordContext) =
|
|||||||
let name = if System.String.IsNullOrEmpty m.Nickname then m.DisplayName else m.Nickname
|
let name = if System.String.IsNullOrEmpty m.Nickname then m.DisplayName else m.Nickname
|
||||||
let embed = Embeds.pickDefense "Trainer-2" { PlayerData.empty with Inventory = [ Shield defaultShield ] ; Name = name } true
|
let embed = Embeds.pickDefense "Trainer-2" { PlayerData.empty with Inventory = [ Shield defaultShield ] ; Name = name } true
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
|
do! Analytics.trainingDojoStep "DefendCommand" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
} |> Async.StartAsTask :> Task
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let handleDefenseMsg hackId = {
|
let handleDefenseMsg hackId = {
|
||||||
@ -104,6 +106,7 @@ let handleDefense (ctx : IDiscordContext) =
|
|||||||
do! sendMessage' $"❌ HACKING FAILED!\n\n{playerName} defended hack from <@{Sensei.Id}>!"
|
do! sendMessage' $"❌ HACKING FAILED!\n\n{playerName} defended hack from <@{Sensei.Id}>!"
|
||||||
do! Async.Sleep 1500
|
do! Async.Sleep 1500
|
||||||
do! sendFollowUpMessageWithButton ctx (handleDefenseMsg defaultHack.Item.Name)
|
do! sendFollowUpMessageWithButton ctx (handleDefenseMsg defaultHack.Item.Name)
|
||||||
|
do! Analytics.trainingDojoStep "ShieldActivated" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
} |> Async.StartAsTask :> Task
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let handleTrainerStep3 (ctx : IDiscordContext) =
|
let handleTrainerStep3 (ctx : IDiscordContext) =
|
||||||
@ -117,6 +120,7 @@ let handleTrainerStep3 (ctx : IDiscordContext) =
|
|||||||
+ $"Type the `/hack` command now, then choose me - <@{Sensei.Id}> as your target, and select `{defaultHack.Item.Name}`")
|
+ $"Type the `/hack` command now, then choose me - <@{Sensei.Id}> as your target, and select `{defaultHack.Item.Name}`")
|
||||||
|
|
||||||
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
|
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask
|
||||||
|
do! Analytics.trainingDojoStep "LetsHack" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
} |> Async.StartAsTask :> Task
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let hack (target : DiscordUser) (ctx : IDiscordContext) =
|
let hack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||||
@ -138,6 +142,7 @@ let hack (target : DiscordUser) (ctx : IDiscordContext) =
|
|||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
do! ctx.FollowUp(builder) |> Async.AwaitTask
|
do! ctx.FollowUp(builder) |> Async.AwaitTask
|
||||||
|
do! Analytics.trainingDojoStep "HackCommand" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
} |> Async.StartAsTask :> Task
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let handleHack (ctx : IDiscordContext) =
|
let handleHack (ctx : IDiscordContext) =
|
||||||
@ -153,7 +158,8 @@ let handleHack (ctx : IDiscordContext) =
|
|||||||
+ "When you **HACK** other Degenz, you **TAKE** their 💰$GBT.\n"
|
+ "When you **HACK** other Degenz, you **TAKE** their 💰$GBT.\n"
|
||||||
+ "But remember, hacks take time to recover, so use them wisely.")
|
+ "But remember, hacks take time to recover, so use them wisely.")
|
||||||
|
|
||||||
do! Async.Sleep 2000
|
do! Analytics.trainingDojoStep "HackActivated" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
|
do! Async.Sleep 1000
|
||||||
|
|
||||||
let message =
|
let message =
|
||||||
$"""
|
$"""
|
||||||
@ -181,6 +187,7 @@ type the `/arsenal` command NOW"""
|
|||||||
do! ctx.GetDiscordMember().GrantRoleAsync(role) |> Async.AwaitTask
|
do! ctx.GetDiscordMember().GrantRoleAsync(role) |> Async.AwaitTask
|
||||||
|
|
||||||
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!")
|
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!")
|
||||||
|
do! Analytics.trainingDojoStep "CompletedNoGifts" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
})
|
})
|
||||||
|
|
||||||
let handleArsenal (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async {
|
let handleArsenal (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async {
|
||||||
@ -235,6 +242,7 @@ let handleArsenal (ctx : IDiscordContext) = PlayerInteractions.executePlayerActi
|
|||||||
do! Async.Sleep 1000
|
do! Async.Sleep 1000
|
||||||
|
|
||||||
do! sendFollowUpMessage ctx $"Now get out of there and go hack other Degenz in the <#{GuildEnvironment.channelBattle}> channel!"
|
do! sendFollowUpMessage ctx $"Now get out of there and go hack other Degenz in the <#{GuildEnvironment.channelBattle}> channel!"
|
||||||
|
do! Analytics.trainingDojoStep "CompletedWithGifts" (ctx.GetDiscordMember().Id) (ctx.GetDiscordMember().Username)
|
||||||
else
|
else
|
||||||
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
||||||
do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
|
do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
|
||||||
|
@ -15,11 +15,13 @@ let getId str = getVar str |> uint64
|
|||||||
let connectionString = (getVar "DATABASE_URL").Replace("postgresql://", "postgres://").Replace("?sslmode=require", "")
|
let connectionString = (getVar "DATABASE_URL").Replace("postgresql://", "postgres://").Replace("?sslmode=require", "")
|
||||||
|
|
||||||
let guildId = getId "DISCORD_GUILD"
|
let guildId = getId "DISCORD_GUILD"
|
||||||
|
let environment = getVar "ENVIRONMENT"
|
||||||
let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS"
|
let tokenPlayerInteractions = getVar "TOKEN_PLAYER_INTERACTIONS"
|
||||||
let tokenSteal = getVar "TOKEN_STEAL"
|
let tokenSteal = getVar "TOKEN_STEAL"
|
||||||
let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE"
|
let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE"
|
||||||
let tokenStore = getVar "TOKEN_STORE"
|
let tokenStore = getVar "TOKEN_STORE"
|
||||||
let tokenInviter = getVar "TOKEN_INVITER"
|
let tokenInviter = getVar "TOKEN_INVITER"
|
||||||
|
let tokenMixpanel = getVar "TOKEN_MIXPANEL"
|
||||||
let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
|
let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
|
||||||
let channelTraining = getId "CHANNEL_TRAINING"
|
let channelTraining = getId "CHANNEL_TRAINING"
|
||||||
let channelArmory = getId "CHANNEL_ARMORY"
|
let channelArmory = getId "CHANNEL_ARMORY"
|
||||||
|
@ -199,7 +199,7 @@ let guildInviteEmbed =
|
|||||||
let button = DiscordButtonComponent(ButtonStyle.Success, $"CreateGuildInvite", $"GET MY UNIQUE LINK") :> DiscordComponent
|
let button = DiscordButtonComponent(ButtonStyle.Success, $"CreateGuildInvite", $"GET MY UNIQUE LINK") :> DiscordComponent
|
||||||
builder.AddComponents [| button |]
|
builder.AddComponents [| button |]
|
||||||
|
|
||||||
let private showInviteMessage (ctx : IDiscordContext) =
|
let private showInviteMessage (ctx : IDiscordContext) origin =
|
||||||
task {
|
task {
|
||||||
let builder = DiscordInteractionResponseBuilder().AsEphemeral(true)
|
let builder = DiscordInteractionResponseBuilder().AsEphemeral(true)
|
||||||
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder)
|
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder)
|
||||||
@ -216,6 +216,7 @@ let private showInviteMessage (ctx : IDiscordContext) =
|
|||||||
You must **COMPLETE YOUR TRAINING FIRST!** Then you can `/recruit`...
|
You must **COMPLETE YOUR TRAINING FIRST!** Then you can `/recruit`...
|
||||||
Go to <#{GuildEnvironment.channelTraining}> now to become a **HACKER**!
|
Go to <#{GuildEnvironment.channelTraining}> now to become a **HACKER**!
|
||||||
"""
|
"""
|
||||||
|
do! Analytics.recruitCommand origin player.DiscordId (ctx.GetDiscordMember().Username) (ctx.GetChannel().Id) (ctx.GetChannel().Name)
|
||||||
| None ->
|
| None ->
|
||||||
do! sendFollowUpMessage ctx $"You're not in the game! Go to <#{GuildEnvironment.channelShelters}> NOW to get assigned a private bunk, and **JOIN THE GAME!**"
|
do! sendFollowUpMessage ctx $"You're not in the game! Go to <#{GuildEnvironment.channelShelters}> NOW to get assigned a private bunk, and **JOIN THE GAME!**"
|
||||||
} :> Task
|
} :> Task
|
||||||
@ -259,6 +260,9 @@ let private getInvitedUsersForId (ctx : IDiscordContext) = task {
|
|||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
.WithContent(str)
|
.WithContent(str)
|
||||||
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg)
|
do! ctx.Respond(InteractionResponseType.ChannelMessageWithSource, msg)
|
||||||
|
let user = ctx.GetDiscordMember()
|
||||||
|
let channel = ctx.GetChannel()
|
||||||
|
do! Analytics.recruitedCommand total user.Id user.Username channel.Id channel.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
let clearInvites (ctx : IDiscordContext) = task {
|
let clearInvites (ctx : IDiscordContext) = task {
|
||||||
@ -281,6 +285,7 @@ let private processNewUser (eventArgs : GuildMemberAddEventArgs) =
|
|||||||
match result with
|
match result with
|
||||||
| Some (_,count) ->
|
| Some (_,count) ->
|
||||||
if invite.Uses > count then
|
if invite.Uses > count then
|
||||||
|
do! Analytics.invitedUserEntered invite.Code invite.Inviter.Id eventArgs.Member.Id invite.Inviter.Username eventArgs.Member.Username
|
||||||
do! addInvitedUser eventArgs.Member.Id invite.Code invite.Uses |> Async.Ignore
|
do! addInvitedUser eventArgs.Member.Id invite.Code invite.Uses |> Async.Ignore
|
||||||
| None -> ()
|
| None -> ()
|
||||||
} :> Task
|
} :> Task
|
||||||
@ -291,36 +296,23 @@ let acceptInvite (ctx : IDiscordContext) (invitedPlayer : PlayerData) =
|
|||||||
| false ->
|
| false ->
|
||||||
let! _ = markInvitedAccepted invitedPlayer.DiscordId |> Async.Ignore
|
let! _ = markInvitedAccepted invitedPlayer.DiscordId |> Async.Ignore
|
||||||
try
|
try
|
||||||
let! inviter = getInviteFromInvitedUser invitedPlayer.DiscordId
|
let! invite = getInviteFromInvitedUser invitedPlayer.DiscordId
|
||||||
let! player = DbService.tryFindPlayer inviter.Inviter
|
let! player = DbService.tryFindPlayer invite.Inviter
|
||||||
match player with
|
match player with
|
||||||
| Some player ->
|
| Some player ->
|
||||||
do! DbService.updatePlayerCurrency (int InviteRewardAmount) player |> Async.Ignore
|
do! DbService.updatePlayerCurrency (int InviteRewardAmount) player |> Async.Ignore
|
||||||
let builder = DiscordMessageBuilder()
|
let builder = DiscordMessageBuilder()
|
||||||
builder.WithContent($"{invitedPlayer.Name} was recruited to the server. <@{player.DiscordId}> just earned {InviteRewardAmount} 💰$GBT for their efforts!") |> ignore
|
builder.WithContent($"{invitedPlayer.Name} was recruited and is now a Degen. <@{player.DiscordId}> just earned {InviteRewardAmount} 💰$GBT for their efforts!") |> ignore
|
||||||
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
|
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
|
||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
|
do! Analytics.invitedUserAccepted invite.Code player.DiscordId invitedPlayer.DiscordId player.Name invitedPlayer.Name
|
||||||
| None -> return ()
|
| None -> return ()
|
||||||
with _ -> ()
|
with _ -> ()
|
||||||
| true -> return ()
|
| true -> return ()
|
||||||
} :> Task
|
} :> Task
|
||||||
|
|
||||||
// If we do it like this then there's an obvious exploit where the user can come and go as many times and it will keep
|
|
||||||
// rewarding GBT.
|
|
||||||
//let handleGuildMemberRemoved _ (eventArgs : GuildMemberRemoveEventArgs) =
|
|
||||||
// task {
|
|
||||||
// do! removeInvitedUser eventArgs.Member.Id
|
|
||||||
// } :> Task
|
|
||||||
|
|
||||||
//Degenz Game
|
|
||||||
//Mint Date: April 2022
|
|
||||||
//Supply: 3,333
|
|
||||||
//Price: 1.984 $SOL
|
|
||||||
|
|
||||||
//Your NFT will be your In-Game Character that provides you with unique traits, and abilities in game.
|
|
||||||
|
|
||||||
let sendInitialEmbed (client : DiscordClient) =
|
let sendInitialEmbed (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
try
|
try
|
||||||
@ -435,7 +427,8 @@ let handleGimmeWhitelist (ctx : IDiscordContext) =
|
|||||||
let recruitBtn = DiscordButtonComponent(ButtonStyle.Danger, $"ShowRecruitmentEmbed", $"Recruit Now") :> DiscordComponent
|
let recruitBtn = DiscordButtonComponent(ButtonStyle.Danger, $"ShowRecruitmentEmbed", $"Recruit Now") :> DiscordComponent
|
||||||
|
|
||||||
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
|
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
|
||||||
match! tryGrantWhitelist ctx with
|
let! availability = tryGrantWhitelist ctx
|
||||||
|
match availability with
|
||||||
| NotAHacker -> whitelistEmbed.Description <- notAHackerMsg
|
| NotAHacker -> whitelistEmbed.Description <- notAHackerMsg
|
||||||
| NotInGame -> whitelistEmbed.Description <- notInGameMsg
|
| NotInGame -> whitelistEmbed.Description <- notInGameMsg
|
||||||
| AlreadyWhitelisted ->
|
| AlreadyWhitelisted ->
|
||||||
@ -455,6 +448,13 @@ let handleGimmeWhitelist (ctx : IDiscordContext) =
|
|||||||
whitelistEmbed.Description <- canBuyWhitelistMsg
|
whitelistEmbed.Description <- canBuyWhitelistMsg
|
||||||
builder.AddEmbed(whitelistEmbed) |> ignore
|
builder.AddEmbed(whitelistEmbed) |> ignore
|
||||||
do! ctx.FollowUp(builder)
|
do! ctx.FollowUp(builder)
|
||||||
|
let availabilityStr =
|
||||||
|
match availability with
|
||||||
|
| NotEnoughGBT _ -> "NotEnoughGBT"
|
||||||
|
| Granted _ -> "Granted"
|
||||||
|
| _ -> string availability
|
||||||
|
let user = ctx.GetDiscordMember()
|
||||||
|
do! Analytics.whiteListButton availabilityStr user.Id user.Username
|
||||||
} :> Task
|
} :> Task
|
||||||
|
|
||||||
let buyWhitelistMsg = $"""
|
let buyWhitelistMsg = $"""
|
||||||
@ -476,10 +476,18 @@ let handleBuyWhitelist (ctx : IDiscordContext) =
|
|||||||
|
|
||||||
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
|
let builder = DiscordFollowupMessageBuilder().AsEphemeral(true)
|
||||||
match! tryGrantWhitelist ctx with
|
match! tryGrantWhitelist ctx with
|
||||||
| NotAHacker -> builder.Content <- $"You are somehow not a hacker anymore, what exactly are you doing?"
|
| NotAHacker ->
|
||||||
| NotInGame -> builder.Content <- $"You somehow have left the game, what exactly are you doing?"
|
builder.Content <- $"You are somehow not a hacker anymore, what exactly are you doing?"
|
||||||
| AlreadyWhitelisted -> builder.Content <- "🎉 You're already WHITELISTED!"
|
do! ctx.FollowUp(builder)
|
||||||
| NotEnoughGBT _ -> builder.Content <- $"You somehow do not have enough $GBT, what exactly are you doing?"
|
| NotInGame ->
|
||||||
|
builder.Content <- $"You somehow have left the game, what exactly are you doing?"
|
||||||
|
do! ctx.FollowUp(builder)
|
||||||
|
| AlreadyWhitelisted ->
|
||||||
|
builder.Content <- "🎉 You're already WHITELISTED!"
|
||||||
|
do! ctx.FollowUp(builder)
|
||||||
|
| NotEnoughGBT _ ->
|
||||||
|
builder.Content <- $"You somehow do not have enough $GBT, what exactly are you doing?"
|
||||||
|
do! ctx.FollowUp(builder)
|
||||||
| Granted player ->
|
| Granted player ->
|
||||||
let embed = DiscordEmbedBuilder()
|
let embed = DiscordEmbedBuilder()
|
||||||
embed.Description <- buyWhitelistMsg
|
embed.Description <- buyWhitelistMsg
|
||||||
@ -491,6 +499,7 @@ let handleBuyWhitelist (ctx : IDiscordContext) =
|
|||||||
do! ctx.GetDiscordMember().GrantRoleAsync(role)
|
do! ctx.GetDiscordMember().GrantRoleAsync(role)
|
||||||
let! _ = DbService.updatePlayerCurrency -WhitelistPrice player
|
let! _ = DbService.updatePlayerCurrency -WhitelistPrice player
|
||||||
builder.AddEmbed(embed) |> ignore
|
builder.AddEmbed(embed) |> ignore
|
||||||
|
do! ctx.FollowUp(builder)
|
||||||
|
|
||||||
// Send message to hall of privacy
|
// Send message to hall of privacy
|
||||||
let builder = DiscordMessageBuilder()
|
let builder = DiscordMessageBuilder()
|
||||||
@ -499,8 +508,9 @@ let handleBuyWhitelist (ctx : IDiscordContext) =
|
|||||||
do! channel.SendMessageAsync(builder)
|
do! channel.SendMessageAsync(builder)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
|
let user = ctx.GetDiscordMember()
|
||||||
|
do! Analytics.whiteListPurchased WhitelistPrice user.Id user.Username
|
||||||
|
|
||||||
do! ctx.FollowUp(builder)
|
|
||||||
} :> Task
|
} :> Task
|
||||||
|
|
||||||
let handleCreateInvite (ctx : IDiscordContext) =
|
let handleCreateInvite (ctx : IDiscordContext) =
|
||||||
@ -532,6 +542,7 @@ let handleCreateInvite (ctx : IDiscordContext) =
|
|||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
do! ctx.FollowUp(msg)
|
do! ctx.FollowUp(msg)
|
||||||
|
do! Analytics.recruitLinkButton code user.Id user.Username (ctx.GetChannel().Id) (ctx.GetChannel().Name)
|
||||||
} :> Task
|
} :> Task
|
||||||
|
|
||||||
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||||
@ -540,7 +551,7 @@ let handleButtonEvent (_ : DiscordClient) (event : ComponentInteractionCreateEv
|
|||||||
| id when id.StartsWith("GimmeWhitelist") -> handleGimmeWhitelist eventCtx
|
| id when id.StartsWith("GimmeWhitelist") -> handleGimmeWhitelist eventCtx
|
||||||
| id when id.StartsWith("BuyWhitelist") -> handleBuyWhitelist eventCtx
|
| id when id.StartsWith("BuyWhitelist") -> handleBuyWhitelist eventCtx
|
||||||
| id when id.StartsWith("CreateGuildInvite") -> handleCreateInvite eventCtx
|
| id when id.StartsWith("CreateGuildInvite") -> handleCreateInvite eventCtx
|
||||||
| id when id.StartsWith("ShowRecruitmentEmbed") -> showInviteMessage eventCtx
|
| id when id.StartsWith("ShowRecruitmentEmbed") -> showInviteMessage eventCtx "RecruitButton"
|
||||||
| _ ->
|
| _ ->
|
||||||
task {
|
task {
|
||||||
let builder = DiscordInteractionResponseBuilder()
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
@ -561,7 +572,7 @@ type Inviter() =
|
|||||||
|
|
||||||
[<SlashCommand("recruit", "Recruit another user to this discord and earn rewards")>]
|
[<SlashCommand("recruit", "Recruit another user to this discord and earn rewards")>]
|
||||||
member this.CreateInvite (ctx : InteractionContext) =
|
member this.CreateInvite (ctx : InteractionContext) =
|
||||||
showInviteMessage (DiscordInteractionContext ctx)
|
showInviteMessage (DiscordInteractionContext ctx) "RecruitCommand"
|
||||||
|
|
||||||
[<SlashCommand("recruited", "Get total invites from a specific user")>]
|
[<SlashCommand("recruited", "Get total invites from a specific user")>]
|
||||||
member this.ListInvitedPeople (ctx : InteractionContext) =
|
member this.ListInvitedPeople (ctx : InteractionContext) =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user