Skip to content

Instantly share code, notes, and snippets.

@devblackops
Created March 5, 2020 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devblackops/28afca76db2e1b5ed4fbd3eedf7c94cc to your computer and use it in GitHub Desktop.
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
[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