Skip to content

Commit

Permalink
Merge pull request #63 from Philenst/main
Browse files Browse the repository at this point in the history
Telegram notification support
  • Loading branch information
tigattack authored Jan 18, 2024
2 parents 1273153 + bec6452 commit 5488772
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 36 deletions.
75 changes: 51 additions & 24 deletions AlertSender.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -352,37 +352,64 @@ try {
# Create variable for service name in TitleCase format.
$textInfo = (Get-Culture).TextInfo
$serviceName = $textInfo.ToTitleCase($service.Name)
If ($service.Value.webhook -ne $null) {
If ($service.Value.webhook.StartsWith('https')) {
Write-LogMessage -Tag 'INFO' -Message "Sending notification to $($serviceName)."
$logId_service = $vbrSessionLogger.AddLog("[VeeamNotify] Sending notification to $($serviceName)...")

# Add user information for mention if relevant.
Write-LogMessage -Tag 'DEBUG' -Message 'Determining if user should be mentioned.'
If ($mention) {
Write-LogMessage -Tag 'DEBUG' -Message 'Getting user ID for mention.'
$payloadParams.UserId = $service.Value.user_id

# Set username if exists
If ($service.Value.user_name -and $service.Value.user_name -ne 'Your Name') {
Write-LogMessage -Tag 'DEBUG' -Message 'Setting user name for mention.'
$payloadParams.UserName = $service.Value.user_name
}
}

If ($service.Value.webhook.StartsWith('https')) {
Write-LogMessage -Tag 'INFO' -Message "Sending notification to $($serviceName)."
$logId_service = $vbrSessionLogger.AddLog("[VeeamNotify] Sending notification to $($serviceName)...")
# Get URI from webhook value
$uri = $service.Value.webhook

# Add user information for mention if relevant.
Write-LogMessage -Tag 'DEBUG' -Message 'Determining if user should be mentioned.'
If ($mention) {
Write-LogMessage -Tag 'DEBUG' -Message 'Getting user ID for mention.'
$payloadParams.UserId = $service.Value.user_id
Try {
New-Payload -Service $service.Name -Parameters $payloadParams | Send-Payload -Uri $uri -JSONPayload $true | Out-Null

# Get username if Teams
If ($service.Value.user_name -and $service.Value.user_name -ne 'Your Name') {
Write-LogMessage -Tag 'DEBUG' -Message 'Getting Teams user name for mention.'
$payloadParams.UserName = $service.Value.user_name
Write-LogMessage -Tag 'INFO' -Message "Notification sent to $serviceName successfully."
$vbrSessionLogger.UpdateSuccess($logId_service, "[VeeamNotify] Sent notification to $($serviceName).") | Out-Null
}
Catch {
Write-LogMessage -Tag 'ERROR' -Message "Unable to send $serviceName notification: $_"
$vbrSessionLogger.UpdateErr($logId_service, "[VeeamNotify] $serviceName notification could not be sent.", "Please check the log: $Logfile") | Out-Null
}
}

Try {
New-Payload -Service $service.Name -Parameters $payloadParams | Send-Payload -Uri $service.Value.webhook | Out-Null

Write-LogMessage -Tag 'INFO' -Message "Notification sent to $serviceName successfully."
$vbrSessionLogger.UpdateSuccess($logId_service, "[VeeamNotify] Sent notification to $($serviceName).") | Out-Null
}
Catch {
Write-LogMessage -Tag 'ERROR' -Message "Unable to send $serviceName notification: $_"
$vbrSessionLogger.UpdateErr($logId_service, "[VeeamNotify] $serviceName notification could not be sent.", "Please check the log: $Logfile") | Out-Null
Else {
Write-LogMessage -Tag 'DEBUG' -Message "$serviceName is unconfigured (invalid URL). Skipping $serviceName notification."
}
}
Else {
Write-LogMessage -Tag 'DEBUG' -Message "$serviceName is unconfigured (invalid URL). Skipping $serviceName notification."
else {
# Get URI from webhook value
If ($service.Name -eq 'telegram') {
if (!($Service.Value.bot_token -eq 'TelegramBotToken' -or $Service.Value.chat_id -eq 'TelegramChatID')) {
Write-LogMessage -Tag 'INFO' -Message "Sending notification to $($serviceName)."
$logId_service = $vbrSessionLogger.AddLog("[VeeamNotify] Sending notification to $($serviceName)...")
Try {
$payload = New-Payload -Service $service.Name -Parameters $payloadParams
Send-Payload -Uri "https://api.telegram.org/bot$($service.Value.bot_token)/sendMessage" -Body @{ chat_id = "$($service.Value.chat_id)"; parse_mode = 'MarkdownV2'; text = $payload }

Write-LogMessage -Tag 'INFO' -Message "Notification sent to $serviceName successfully."
$vbrSessionLogger.UpdateSuccess($logId_service, "[VeeamNotify] Sent notification to $($serviceName).") | Out-Null
}
Catch {
Write-LogMessage -Tag 'ERROR' -Message "Unable to send $serviceName notification: $_"
$vbrSessionLogger.UpdateErr($logId_service, "[VeeamNotify] $serviceName notification could not be sent.", "Please check the log: $Logfile") | Out-Null
}
}
Else {
Write-LogMessage -Tag 'DEBUG' -Message "$serviceName is unconfigured (invalid bot_token or chat_id). Skipping $serviceName notification."
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ VeeamNotify is a replacement for [VeeamDiscordNotifications](https://github.com/
* Discord
* Slack
* Microsoft Teams
* Telegram

Please create a [feature request](https://github.com/tigattack/VeeamNotify/issues/new?assignees=tigattack&labels=enhancement&template=feature_request.yml&title=[FEAT]+New+service:+) if your preferred service isn't listed here.

Expand Down
4 changes: 4 additions & 0 deletions config/conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"webhook": "TeamsWebhook",
"user_id": "user@domain.tld",
"user_name": "Your Name"
},
"telegram": {
"bot_token": "TelegramBotToken",
"chat_id": "TelegramChatID"
}
},
"mentions": {
Expand Down
14 changes: 13 additions & 1 deletion config/conf.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@
"type": "string"
}
}
},
"telegram": {
"type": "object",
"properties": {
"bot_token": {
"type": "string"
},
"chat_id": {
"type": "string"
}
}
}
},
"required": [
"discord",
"slack",
"teams"
"teams",
"telegram"
]
},
"mentions": {
Expand Down
123 changes: 112 additions & 11 deletions resources/NotificationHandler.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function New-Payload {
[OutputType([System.Collections.Hashtable])]
param (
[Parameter(Mandatory=$true)]
[ValidateSet('Discord', 'Slack', 'Teams')]
[ValidateSet('Discord', 'Slack', 'Teams', 'Telegram')]
[string]$Service,

[Parameter(Mandatory=$true)]
Expand All @@ -20,6 +20,9 @@ function New-Payload {
'Teams' {
New-TeamsPayload @Parameters
}
'Telegram' {
New-TelegramPayload @Parameters
}
Default {
Write-LogMessage -Tag 'ERROR' -Message "Unknown service: $Service"
}
Expand Down Expand Up @@ -679,22 +682,120 @@ function New-SlackPayload {
return $payload
}

function New-TelegramPayload {
[CmdletBinding()]
[OutputType([string])]
param (
[string]$JobName,
[string]$JobType,
[string]$Status,
[string]$DataSize,
[string]$TransferSize,
[string]$ProcessedSize,
[int]$DedupRatio,
[int]$CompressRatio,
[string]$Speed,
[string]$Bottleneck,
[string]$Duration,
[DateTime]$StartTime,
[DateTime]$EndTime,
[boolean]$Mention,
[string]$UserId,
[string]$ThumbnailUrl,
[string]$FooterMessage,
[boolean]$UpdateNotification,
[string]$LatestVersion
)

# Mention user if configured to do so.
# Must be done at early stage to ensure this section is at the top of the embed object.
If ($mention) {
$message = "[$UserName](tg://user?id=$UserId) Job $($Status.ToLower())!`n"
}
else {
$message = ''
}

# Build payload object.
$message += "*$JobName*`n`n*Session result:* $Status`n*Job type:* $JobType`n`n"

# Set timestamps
$timestampStart = $(Get-Date $StartTime -UFormat '%d %B %Y %R').ToString()
$timestampEnd = $(Get-Date $EndTime -UFormat '%d %B %Y %R').ToString()

# Build blocks object.
if (-not ($JobType.EndsWith('Agent Backup'))) {
$message += @"
*Backup Size:* $DataSize
*Transferred Data:* $TransferSize
*Dedup Ratio:* $DedupRatio
*Compression Ratio:* $CompressRatio
*Processing Rate:* $Speed
*Bottleneck:* $Bottleneck
*Start Time:* $timestampStart
*End Time:* $timestampEnd
*Duration:* $Duration
"@
}

elseif ($JobType.EndsWith('Agent Backup')) {
$message += @"
*Processed Size:* $ProcessedSize
*Transferred Data:* $TransferSize
*Processing Rate:* $Speed
*Bottleneck:* $Bottleneck
*Start Time:* $timestampStart
*End Time:* $timestampEnd
*Duration:* $Duration
"@
}

# Add footer to payload object.
$message += "`n`n$FooterMessage"

# Add update notice if relevant and configured to do so.
If ($UpdateNotification) {
# Add block to payload.
$message += "`nA new version of VeeamNotify is available! See release [*$LatestVersion* on GitHub](https://github.com/tigattack/VeeamNotify/releases/$LatestVersion)."
}

# https://core.telegram.org/bots/api#markdownv2-style
$escapes = '_', '[', ']', '(', ')', '~', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'

foreach ($char in $escapes) {
$message = $message.Replace("$char", "\$char")
}

return $message
}

function Send-Payload {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline)]
[Parameter(Mandatory=$true)]
$Payload,
$Uri
$Uri,
$JSONPayload = $false
)

process {
# Build post parameters
$postParams = @{
Uri = $Uri
Body = ($Payload | ConvertTo-Json -Depth 11)
Method = 'Post'
ContentType = 'application/json'
ErrorAction = 'Stop'
if ($JSONPayload) {
$postParams = @{
Uri = $Uri
Body = ($Payload | ConvertTo-Json -Depth 11)
Method = 'Post'
ContentType = 'application/json'
ErrorAction = 'Stop'
}
}
Else {
$postParams = @{
Body = $Body
Method = 'Post'
ContentType = 'application/x-www-form-urlencoded'
ErrorAction = 'Stop'
}
}

Try {
Expand All @@ -705,8 +806,8 @@ function Send-Payload {
return $request
}
Catch [System.Net.WebException] {
Write-LogMessage -Tag 'ERROR' -Message 'Unable to send webhook. Check your webhook URL or network connection.'
Write-LogMessage -Tag 'ERROR' -Message 'Unable to send Payload. Check your Payload or network connection.'
throw
}
}
}
}

0 comments on commit 5488772

Please sign in to comment.