Skip to content

Instantly share code, notes, and snippets.

@Chirishman
Created April 14, 2017 18:24
Show Gist options
  • Save Chirishman/2270acf916c5378e89183c59f5365211 to your computer and use it in GitHub Desktop.
Save Chirishman/2270acf916c5378e89183c59f5365211 to your computer and use it in GitHub Desktop.
Trying to respond to a Slack PM with a response including buttons
Function Invoke-ExampleSlackBot {
[cmdletbinding()]
Param(
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullOrEmpty()]
[string]$BotName,
[Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullOrEmpty()]
[securestring]$Token = $(Read-Host -Prompt "API Key" -AsSecureString)
)
$ClearToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
$Token
)
)
#Web API call starts the session and gets a websocket URL to use.
$RTMSession = Invoke-RestMethod -Uri https://slack.com/api/rtm.start -Body @{token="$ClearToken"}
Write-Verbose "I am $($RTMSession.self.name)"
Try{
Do{
$WS = New-Object System.Net.WebSockets.ClientWebSocket
$CT = New-Object System.Threading.CancellationToken
$Conn = $WS.ConnectAsync($RTMSession.URL, $CT)
While (!$Conn.IsCompleted) { Start-Sleep -Milliseconds 100 }
Write-Verbose "Connected to $($RTMSession.URL)"
$Size = 1024
$Array = [byte[]] @(,0) * $Size
$Recv = New-Object System.ArraySegment[byte] -ArgumentList @(,$Array)
While ($WS.State -eq 'Open') {
$RTM = ""
Do {
$Conn = $WS.ReceiveAsync($Recv, $CT)
While (!$Conn.IsCompleted) { Start-Sleep -Milliseconds 100 }
$Recv.Array[0..($Conn.Result.Count - 1)] | ForEach-Object { $RTM = $RTM + [char]$_ }
} Until ($Conn.Result.Count -lt $Size)
Write-Verbose "$RTM"
If ($RTM){
$RTM = ($RTM | convertfrom-json)
Switch ($RTM){
{($_.type -eq 'message') -and (!$_.reply_to)} {
If ( ($_.text -Match "<@$($RTMSession.self.id)>") -or $_.channel.StartsWith('D') ){
#A message was sent to the bot
$MessageCommand = @{
BotName = $BotName
Message = "$($_.text)".ToLower()
Channel = $RTM.Channel
}
if ($MessageCommand.Message){
$ID = (get-date).ticks
$Timeout = 30
$Prop = @{
'id' = $ID;
'type' = 'message';
'text' = 'Would you like to play a game?';
'channel' = $MessageCommand.Channel
'attachments' = @(
@{
"text" = "Choose a game to play"
"fallback" = "You are unable to choose a game"
"callback_id" = "wopr_game"
"color" = "#3AA3E3"
"attachment_type" = "default"
"actions" = @(
@{
"name" = "game"
"text" = "Chess"
"type" = "button"
"value" = "chess"
},
@{
"name" = "game"
"text" = "Falken's Maze"
"type" = "button"
"value" = "maze"
},
@{
"name" = "game"
"text" = "Thermonuclear War"
"style" = "danger"
"type" = "button"
"value" = "war"
"confirm" = @{
"title" = "Are you sure?"
"text" = "Wouldn't you prefer a good game of chess?"
"ok_text" = "Yes"
"dismiss_text" = "No"
}
}
)
}
)
}
$Msg = (New-Object –TypeName PSObject –Prop $Prop) | ConvertTo-Json -Depth 5
$Array = @()
$Msg.ToCharArray() | ForEach-Object { $Array = $Array + [byte]$_ }
Write-Verbose $msg
$Msg = New-Object System.ArraySegment[byte] -ArgumentList @(,$Array)
Write-Verbose $msg
$Conn = $WS.SendAsync($Msg, [System.Net.WebSockets.WebSocketMessageType]::Text, [System.Boolean]::TrueString, $CT)
$ConnStart = Get-Date
While (!$Conn.IsCompleted) {
$TimeTaken = ((get-date) - $ConnStart).Seconds
If ($TimeTaken -gt $Timeout) {
Write-Verbose -Level Error "Message $ID took longer than $Timeout seconds and may not have been sent."
Return
}
Start-Sleep -Milliseconds 100
}
}
}Else{
Write-Verbose "Message ignored as it wasn't sent to @$($RTMSession.self.name) or in a DM channel"
}
}
{$_.type -eq 'reconnect_url'} { $RTMSession.URL = $RTM.url }
default { Write-Verbose "No action specified for $($RTM.type) event" }
}
}
}
} Until (!$Conn)
}Finally{
If ($WS) {
Write-Verbose "Closing websocket"
$WS.Dispose()
}
}
}
Invoke-ExampleSlackBot -BotName ProtobotSlack
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment