I am trying to use PowerShell V2 (testing purposes) to initiate a real-time messaging (rtm) instance with Slack. But according to Slack's FAQ, to connect to their rtm API, I need to use the wss:// protocol via a Websocket client to stream events associated. I am also trying to make it an asynchronous connection (receiving as well as connecting).
This doesn't work :
$webSock = New-Object System.Net.WebSocket.ClientWebSocket
$client = New-Object System.Threading.CancellationToken
One other thing is that I need a function to convert from JSON in PowerShell V2.
I tried using this but it doesn't work too:
function ConvertFrom-Json20([object] $item){
add-type -assembly system.web.extensions
$ps_js=new-object system.web.script.serialization.javascriptSerializer
#The comma operator is the array construction operator in PowerShell
return ,$ps_js.DeserializeObject($item)
}
- Kevin Sookocheff How Do Websockets Work? A WebSocket is a persistent connection between a client and server. WebSockets provide a bidirectional, full-duplex communications channel that operates over HTTP through a single TCP/IP socket connection. At its core, the WebSocket protocol facilitates message passing between a client and server.
All you have to do is call the WebSocket constructor and pass in the URL of your server. Once the connection has been established, the open event will be fired on your Web Socket instance.
Since the WebSocket re-uses the HTTP connection, there are potential security concerns if either side interprets WebSocket data as an HTTP request. After the client receives the server response, the WebSocket connection is open to start transmitting data.
The only accepted version of the WebSocket protocol is 13. Any other version listed in this header is invalid. Together, these headers would result in an HTTP GET request from the client to a ws:// URI like in the following example:
Oddly enough, I had this same need recently. Thanks to Mark Wragg, and his helpful link, here is a quick bit of code to get this going. You'll need at least Windows 8 and Server 2012 to make these things work.
Try{
Do{
$URL = 'ws://YOUR_URL_HERE/API/WebSocketHandler.ashx'
$WS = New-Object System.Net.WebSockets.ClientWebSocket
$CT = New-Object System.Threading.CancellationToken
$WS.Options.UseDefaultCredentials = $true
#Get connected
$Conn = $WS.ConnectAsync($URL, $CT)
While (!$Conn.IsCompleted) {
Start-Sleep -Milliseconds 100
}
Write-Host "Connected to $($URL)"
$Size = 1024
$Array = [byte[]] @(,0) * $Size
#Send Starting Request
$Command = [System.Text.Encoding]::UTF8.GetBytes("ACTION=Command")
$Send = New-Object System.ArraySegment[byte] -ArgumentList @(,$Command)
$Conn = $WS.SendAsync($Send, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $CT)
While (!$Conn.IsCompleted) {
#Write-Host "Sleeping for 100 ms"
Start-Sleep -Milliseconds 100
}
Write-Host "Finished Sending Request"
#Start reading the received items
While ($WS.State -eq 'Open') {
$Recv = New-Object System.ArraySegment[byte] -ArgumentList @(,$Array)
$Conn = $WS.ReceiveAsync($Recv, $CT)
While (!$Conn.IsCompleted) {
#Write-Host "Sleeping for 100 ms"
Start-Sleep -Milliseconds 100
}
#Write-Host "Finished Receiving Request"
Write-Host [System.Text.Encoding]::utf8.GetString($Recv.array)
}
} Until ($WS.State -ne 'Open')
}Finally{
If ($WS) {
Write-Host "Closing websocket"
$WS.Dispose()
}
}
It is possible to use .NET's System.Net.WebSockets.ClientWebSocket
class to do this. You need to be running Windows 8 or Server 2012 or newer as your underlying OS to utilise this class, so therefore I think you'd have at least PowerShell v3 regardless (and as a result the ConvertFrom-Json
cmdlet). You also need to make use of the System.ArraySegment
.NET class.
I've created a simple framework that demonstrates how to use the various classes to interact with the Slack RTM API from a PowerShell script. You can find the project on GitHub here: https://github.com/markwragg/Powershell-SlackBot
I've also blogged about it in more detail here: http://wragg.io/powershell-slack-bot-using-the-real-time-messaging-api/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With