ps/Modules/Alkami.DevOps.Common/Public/Publish-MessageToSlack.ps1

163 lines
5.6 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
function Publish-MessageToSlack {
<#
.SYNOPSIS
Posts a message to Slack.
.DESCRIPTION
Posts a message to Slack.
.PARAMETER Channels
Array of channels to post to, such as @("@username","#some-channel-name")
.PARAMETER SlackHookUrl
Slack webhook url
.PARAMETER SlackParameters
Hashtable of "messagebody" parameters. Cannot be used in conjunction with
MessageText, UserName and IconEmoji. This is used when the caller wants to
build their own message body JSON.
.PARAMETER SlackAttachments
Hashtable of Slack message attachments to be added to the "messagebody"
.PARAMETER MessageText
String of simple message text. If this is populated, MessageBody must be
left empty or MessageBody will be used instead. This is used in combination
with UserName and IconEmoji to construct a simple message JSON object. Caller
does not have to build JSON object to send a simple message.
.EXAMPLE
$chan = @("@trowton","#eng-sre-ci-cd-alerts")
$buildlog = "http://duckduckgo.com"
$fallback = "View the Build: $buildLog"
$actions = @(
@{
"type" = "button"
"text" = "Build Log"
"url" = $buildLog
}
)
$attachments = @{
fallback = $fallback
color = "#009EFF"
actions = $actions
}
$params = @{
"username"="someuser";"icon_emoji"=":teamcity:";"text"="Text [with square brackets] and a period."
}
Publish-MessageToSlack -Channels $chan -SlackHookUrl $slackHookUrl -MessageBody $params -SlackAttachments $attachments
Publish-MessageToSlack -Channels $chan -SlackHookUrl $slackHookUrl -MessageText "sampletext" -IconEmoji ":smiley:" -Username "TC job" -SlackAttachments $attachments
.LINK
https://api.slack.com/methods/chat.postMessage
.NOTES
Either MessageBody or MessageText must be populated to send a message. If MessageBody
is populated, it will take precedence over MessageText.
#>
[CmdletBinding()]
[OutputType([void])]
param(
[Parameter(Mandatory = $True)]
[array]$Channels,
[Parameter(Mandatory = $True)]
[string]$SlackHookUrl,
[Parameter(Mandatory = $False)]
[Alias ("MessageBody")]
[hashtable]$SlackParameters,
[Parameter(Mandatory = $False)]
[hashtable]$SlackAttachments,
[Parameter(Mandatory = $False)]
[string] $MessageText,
[Parameter(Mandatory = $False)]
[string] $Username = "Publish Message",
[Parameter(Mandatory = $False)]
[string] $IconEmoji = ":slack:"
)
$loglead = (Get-LogLeadName)
# Test if either MessageBody and MessageText are populated. One must be populated.
if($null -eq $SlackParameters -and [string]::IsNullOrWhiteSpace($MessageText)) {
throw "SlackParameters or MessageText must be populated to send a message!"
}
# Test if both MessageBody and MessageText are populated.
if($null -ne $SlackParameters -and !([string]::IsNullOrWhiteSpace($MessageText))) {
Write-Host "$loglead Both SlackParameters and MessageText parameters are not null. Choosing SlackParameters as message body."
}
# If MessageText is populated and SlackParameters is null, build a body.
if($null -eq $SlackParameters) {
Write-Verbose "$loglead SlackParameters is null, using MessageText [$MessageText], UserName [$UserName] and Icon [$IconEmoji] to send message."
$messageBody = @{
"username" = "$Username";
"text" = "$MessageText";
"icon_emoji" = "$IconEmoji";
}
} else {
# Parameters are a direct mapping to the message body.
$messageBody = $SlackParameters
}
# Add attachments to message body, if they're provided.
if ($null -ne $SlackAttachments) {
$messageBody["attachments"] = @($SlackAttachments)
}
# Test for required keys in attachments.
if($messageBody["attachments"].Count -gt 0) {
$hasFallback = $false
foreach ($attachment in $messageBody["attachments"]) {
foreach ($aKey in $attachment.Keys) {
if ($aKey -eq "fallback") {
$hasFallback = $true
}
}
}
if ($hasFallback -eq $false) {
throw "Missing required parameter key 'fallback' on 'SlackAttachments'."
}
}
# Test for 'text' key in MessageBody.
$hasText = $false
foreach ($param in $messageBody) {
foreach ($key in $param.Keys) {
if ($key -eq "text") {
$hasText = $true
}
}
}
if ($hasText -eq $false) {
throw "Missing required parameter key 'text' on 'SlackParameters'."
}
# Check $channels for commas to split on.
if ($Channels[0].Contains(",")) {
Write-Host "$loglead : Channels was supplied as a comma delimited string, not an array. Splitting..."
$sanitizedChannels = $Channels[0].Split(",")
} else {
$sanitizedChannels = $Channels
}
# Send message to each specified channel(s).
foreach ($channel in $sanitizedChannels) {
$messageBody["channel"] = $channel;
$messageJson = ($messageBody | ConvertTo-Json -Depth 100).Replace('\\r\\n', '\r\n')
Write-Verbose "$loglead : Posting JSON:"
Write-Verbose $messageJson
try {
(Invoke-RestMethod -Uri $SlackHookUrl -Method POST -Body $messageJson -ContentType "application/json") | Out-Null
} catch {
$errorMessage = $_.Exception.Message
Write-Warning "$logLead : Could not post message to Slack.`nError message is: $errorMessage"
# TODO: Metric this so we know that errors occurred.
}
}
}