Created
March 5, 2020 17:23
-
-
Save devblackops/28afca76db2e1b5ed4fbd3eedf7c94cc to your computer and use it in GitHub Desktop.
Minimal reproduction of connecting to Slack's RTM websocket API to receive messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[cmdletbinding()] | |
param() | |
function Connect-SlackRtm { | |
[cmdletbinding()] | |
param( | |
[string]$Token | |
) | |
$loginData = @{} | |
$url = "https://slack.com/api/rtm.start?token=$($Token)&pretty=1" | |
try { | |
$r = Invoke-RestMethod -Uri $url -Method Get -Verbose:$false | |
if ($r.ok) { | |
Write-Verbose 'Successfully authenticated to Slack Real Time API' | |
$loginData['WebSocketUrl'] = $r.url | |
$loginData['Domain'] = $r.team.domain | |
$loginData['UserName'] = $r.self.name | |
} else { | |
throw $r | |
} | |
} catch { | |
Write-Error 'Error connecting to Slack Real Time API' | |
throw $_ | |
} | |
$loginData | |
} | |
function Start-SlackWsReceive { | |
param( | |
[hashtable]$LoginData | |
) | |
# Slack enforces TLS12 on the websocket API | |
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 | |
[Net.WebSockets.ClientWebSocket]$webSocket = [Net.WebSockets.ClientWebSocket]::new() | |
# Connect to websocket | |
Write-Verbose "[SlackBackend:ReceiveJob] Connecting to websocket at [$($LoginData.WebSocketUrl)]" | |
$buffer = [Net.WebSockets.WebSocket]::CreateClientBuffer(1024,1024) | |
$cts = [Threading.CancellationTokenSource]::new() | |
$task = $webSocket.ConnectAsync($LoginData.WebSocketUrl, $cts.Token) | |
do { | |
[Threading.Thread]::Sleep(10)} | |
until ($task.IsCompleted) | |
$ct = [Threading.CancellationToken]::new($false) | |
$taskResult = $null | |
# Maintain websocket connection and put received messages on the output stream | |
function Receive-Msg { | |
$jsonResult = "" | |
do { | |
$taskResult = $webSocket.ReceiveAsync($buffer, $ct) | |
while (-not $taskResult.IsCompleted) { | |
[Threading.Thread]::Sleep(10) | |
} | |
$jsonResult += [Text.Encoding]::UTF8.GetString($buffer, 0, $taskResult.Result.Count) | |
} until ( | |
$taskResult.Result.EndOfMessage | |
) | |
if (-not [string]::IsNullOrEmpty($jsonResult)) { | |
try { | |
$msgs = ConvertFrom-Json -InputObject $jsonResult | |
} | |
catch { | |
throw $Error[0] | |
} | |
foreach ($msg in $msgs) { | |
ConvertTo-Json -InputObject $msg -Compress | |
} | |
} | |
} | |
while ($webSocket.State -eq [Net.WebSockets.WebSocketState]::Open) { | |
Receive-Msg | |
} | |
} | |
$loginData = Connect-SlackRtm -Token '<YOUR-SLACK-TOKEN>' | |
Start-SlackWsReceive -LoginData $loginData |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment