Discord.Net.PowerShell.psm1

<#
    Code in this file will be added to the beginning of the .psm1. For example,
    you should place any using statements here.
#>

Function Connect-Discord {
    [cmdletbinding(
        DefaultParameterSetName = 'Rest'
    )]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'Rest'
        )]
        [switch]$RestClient,
        [Parameter(
            Mandatory,
            ParameterSetName = 'Socket'
        )]
        [switch]$SocketClient,
        [Discord.TokenType]$TokenType,
        [string]$Token,
        [switch]$Quiet
    )

    switch ($PSCmdlet.ParameterSetName) {
        'Rest' {
            $global:DiscordClient = [Discord.Rest.DiscordRestClient]::new()
        }
        'Socket' {
            $global:DiscordClient = [Discord.WebSocket.DiscordSocketClient]::new()
        }
    }
    $DiscordClient.LoginAsync($TokenType, $Token, $true).Wait()
    if (-not $Quiet.IsPresent) {
        $DiscordClient.LoginState
    }
}
Function Get-DiscordChannel {
    [OutputType([Discord.Rest.RestGuildChannel[]], ParameterSetName = 'guildObj-all')]
    [OutputType([Discord.Rest.RestGuildChannel[]], ParameterSetName = 'guildId-all')]
    [OutputType([Discord.Rest.RestGuildChannel], ParameterSetName = 'guildObj-channelId')]
    [OutputType([Discord.Rest.RestGuildChannel], ParameterSetName = 'guildId-channelId')]#>
    [cmdletbinding()]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-all'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-channelId'
        )]
        [Discord.Rest.RestGuild]$Guild,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-all'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-channelId'
        )]
        [uint64]$GuildId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-channelId'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-channelId'
        )]
        [uint64]$ChannelId,
        [Discord.RequestOptions]$RequestOptions
    )
    if ($PSCmdlet.ParameterSetName -like 'guildId*') {
        $Guild = Get-DiscordGuild -Id $GuildId
    }

    $task = if ($PSCmdlet.ParameterSetName -like '*all') {
        $Guild.GetChannelsAsync($RequestOptions)
    } else {
        $Guild.GetChannelAsync($ChannelId, $RequestOptions)
    }
    $task.Wait()
    $task.Result
}
Function Get-DiscordGlobalCommand {
    [OutputType([Discord.Rest.RestApplicationCommand], ParameterSetName = 'byId')]
    [OutputType([Discord.Rest.RestApplicationCommand[]], ParameterSetName = 'all')]
    [cmdletbinding(
        DefaultParameterSetName = 'all'
    )]
    param (
        [Parameter(
            ParameterSetName = 'byId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$Id,
        [Discord.RequestOptions]$RequestOptions
    )
    switch ($PSCmdlet.ParameterSetName) {
        'all' {
            $task = $DiscordClient.GetGlobalApplicationCommandsAsync($RequestOptions)
        }
        'byId' {
            $task = $DiscordClient.GetGlobalApplicationCommandAsync($Id, $RequestOptions)
        }
    }
    $task.Wait()
    $task.Result
}
Function Get-DiscordGuild {
    [OutputType([Discord.Rest.RestGuild], ParameterSetName = 'byId')]
    [OutputType([Discord.Rest.RestGuild[]], ParameterSetName = 'all')]
    [cmdletbinding(
        DefaultParameterSetName = 'all'
    )]
    param (
        [Parameter(
            ParameterSetName = 'byId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$Id,
        [Discord.RequestOptions]$RequestOptions = $null
    )
    switch ($PSCmdlet.ParameterSetName) {
        'all' {
            $task = $DiscordClient.GetGuildsAsync($RequestOptions)
        }
        'byId' {
            $task = $DiscordClient.GetGuildAsync($Id, $RequestOptions)
        }
    }
    $task.Wait()
    $task.Result
}
Function Get-DiscordGuildCommand {
    [OutputType([Discord.Rest.RestApplicationCommand], ParameterSetName = 'guildId-byId')]
    [OutputType([Discord.Rest.RestApplicationCommand], ParameterSetName = 'guildObj-byId')]
    [OutputType([Discord.Rest.RestApplicationCommand[]], ParameterSetName = 'guildId-all')]
    [OutputType([Discord.Rest.RestApplicationCommand[]], ParameterSetName = 'guildObj-all')]
    [cmdletbinding(
        DefaultParameterSetName = 'guildId-all'
    )]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-all'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-byId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$GuildId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-all'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-byId'
        )]
        [ValidateNotNullOrEmpty()]
        [Discord.Rest.RestGuild]$Guild,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-byId'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-byId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$CommandId,
        [Discord.RequestOptions]$RequestOptions
    )
    $task = $DiscordClient.GetGuildApplicationCommands($GuildId, $RequestOptions)
    $task.Wait()
    if ($PSCmdlet.ParameterSetName -like '*all') {
        $task.Result
    } else {
        $task.Result.Where({ $_.Id -eq $CommandId })
    }
}
Function New-DiscordGlobalCommand {
    [OutputType([Discord.Rest.RestGlobalCommand])]
    [cmdletbinding()]
    param (
        [Discord.ApplicationCommandType]$Type = 'Slash',
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Description
    )

    switch ($Type) {
        'Slash' {
            $cb = [Discord.SlashCommandBuilder]::new()
            $cb.Name = $Name
            $cb.Description = $Description
        }
        default {
            Throw "Command type '$Type' not yet implemented in module."
        }
    }
    $task = $DiscordClient.CreateGlobalApplicationCommand($cb.Build())
    $task.Wait()
    $task.Result
}
Function New-DiscordGuildCommand {
    [OutputType([Discord.Rest.RestGuildCommand])]
    [cmdletbinding(
        DefaultParameterSetName = 'byId'
    )]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'byId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$GuildId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'byObj'
        )]
        [ValidateNotNullOrEmpty()]
        [Discord.Rest.RestGuild]$Guild,
        [Discord.ApplicationCommandType]$Type = 'Slash',
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Description,
        [Discord.SlashCommandBuilder]$CommandBuilder
    )
    if ($PSCmdlet.ParameterSetName -eq 'byId') {
        $Guild = Get-DiscordGuild -Id $GuildId
    }

    switch ($Type) {
        'Slash' {
            if ($PSBoundParameters.Keys -notcontains 'CommandBuilder') {
                $cb = [Discord.SlashCommandBuilder]::new()
                $cb.Name = $Name
                $cb.Description = $Description
            } else {
                $cb = $CommandBuilder
            }
        }
        default {
            Throw "Command type '$Type' not yet implemented in module."
        }
    }
    $task = $Guild.CreateApplicationCommandAsync($cb.Build())
    $task.Wait()
    $task.Result
}
Function New-DiscordSlashCommand {
    [OutputType([Discord.SlashCommandBuilder])]
    [cmdletbinding(
        DefaultParameterSetName = 'byId'
    )]
    param (
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [string]$Description,
        [Alias('CommandOptions')]
        [Discord.SlashCommandOptionBuilder[]]$Options
    )
    $cb = [Discord.SlashCommandBuilder]::new()
    $cb.Name = $Name
    $cb.Description = $Description

    if ($PSBoundParameters.Keys -contains 'Options') {
        $cb.Options = $Options
    }

    $cb
}
Function New-DiscordSlashCommandOption {
    [OutputType([Discord.SlashCommandOptionBuilder])]
    [cmdletbinding()]
    param (
        [Parameter(
            Mandatory
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [string]$Description,
        [switch]$IsAutocomplete,
        [switch]$Required,
        [hashtable]$Choices,
        [Discord.ApplicationCommandOptionType]$Type

    )
    $co = [Discord.SlashCommandOptionBuilder]::new()

    $co.Name = $Name

    if ($PSBoundParameters.Keys -contains 'Description') {
        $co.Description = $Description
    }

    if ($PSBoundParameters.Keys -contains 'IsAutocomplete') {
        $co.IsAutocomplete = $IsAutocomplete.IsPresent
    }

    if ($Required.IsPresent) {
        $co.IsRequired = $true
    }

    if ($PSBoundParameters.Keys -contains 'Type') {
        $co.Type = $Type
    }

    if ($PSBoundParameters.Keys -contains 'Choices') {
        foreach ($key in $Choices.Keys) {
            $co.AddChoice($key, $Choices[$key]) | Out-Null
        }
    }

    $co
}
Function Parse-DiscordInteraction {
    [OutputType([Discord.Rest.RestSlashCommand])]
    [cmdletbinding()]
    param (
        [string]$PublicKey,
        [string]$Signature,
        [string]$TimeStamp,
        [string]$Body
    )
    $task = $DiscordClient.ParseHttpInteractionAsync($PublicKey, $Signature, $TimeStamp, $Body)
    $task.Wait()
    $task.Result
}
Function Remove-DiscordGuildCommand {
    [cmdletbinding(
        DefaultParameterSetName = ''
    )]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-commandId'
        )]
        [ValidateNotNullOrEmpty()]
        [UInt64]$GuildId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-commandId'
        )]
        [ValidateNotNullOrEmpty()]
        [Discord.Rest.RestGuild]$Guild,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-commandId'
        )]
        [ValidateNotNullOrEmpty()]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-commandId'
        )]
        [ValidateNotNullOrEmpty()]
        [ulong]$CommandId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'commandObj'
        )]
        [ValidateNotNullOrEmpty()]
        [Discord.Rest.RestGuildCommand]$Command
    )

    if ($PSCmdlet.ParameterSetName -like 'guildId-*') {
        $Guild = Get-DiscordGuild -Id $GuildId
    }

    if ($PSCmdlet.ParameterSetName -like '*-commandId') {
        $task = $Guild.GetApplicationCommandAsync($CommandId, $null)
        $task.Wait()
        $Command = $task.Result
    }

    $task = $Command.DeleteAsync()
    $task.Wait()
    $task.Result
}
Function Send-DiscordMessage {
    [OutputType([Discord.Rest.RestUserMessage])]
    [cmdletbinding()]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-channelId'
        )]
        [Discord.Rest.RestGuild]$Guild,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-channelId'
        )]
        [uint64]$GuildId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildObj-channelId'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'guildId-channelId'
        )]
        [uint64]$ChannelId,
        [Parameter(
            Mandatory,
            ParameterSetName = 'channelObj'
        )]
        [Discord.Rest.RestTextChannel]$Channel,
        [Discord.RequestOptions]$RequestOptions,
        [Parameter(
            Mandatory
        )]
        [string]$MessageText
    )
    if ($PSCmdlet.ParameterSetName -like 'guildId*') {
        $Guild = Get-DiscordGuild -Id $GuildId
    }
    
    if ($PSCmdlet.ParameterSetName -like '*channelId') {
        $Channel = Get-DiscordChannel -Guild $Guild -ChannelId $ChannelId
    }

    $task = $Channel.SendMessageAsync($MessageText)
    $task.Wait()
    $task.Result
}
Function Test-DiscordInteraction {
    [OutputType([bool])]
    [cmdletbinding()]
    param (
        [string]$PublicKey,
        [string]$Signature,
        [string]$TimeStamp,
        [string]$Body
    )
    if (-not (Get-Variable -Name DiscordClient -Scope Global -ErrorAction Ignore)) {
        $DiscordClient = [Discord.Rest.DiscordRestClient]::new()
    }
    $DiscordClient.IsValidHttpInteraction($PublicKey, $Signature, $TimeStamp, $Body)
}
<#
    Code in this file will be added to the end of the .psm1. For example,
    you should set variables or other environment settings here.
#>


# Load Assemblies

Get-ChildItem $PSScriptRoot\lib\*.dll | ForEach-Object {
    Add-Type -Path $_.FullName
}