pwsh 发送钉钉机器人消息
# 钉钉消息发送

$ErrorActionPreference = 'Stop'

#  钉钉消息推送相关
class DingMessage {

    [string] $secret = ""
    [string] $ServerUrl = ""

    [void] send($title, $message) {

        $server = $this.getServerUrl();

        $this.sendContent($server, $title, $message)
    }

    # 返回服务器地址,根据需要进行签名
    [string]getServerUrl() {

        if (-not $this.ServerUrl) {
            throw [System.ArgumentException]::new("ServerUrl is null")
        }

        $server = $this.ServerUrl
        if ($this.secret) {
            $server = $this.signUrl($server, $this.secret)
        }

        return $server
    }

    # 签名
    [string] signUrl([string]$server, [string]$secret) {

        $timestamp = [DateTimeOffset]::Now.ToUnixTimeMilliseconds() # 获取当前时间戳(毫秒)
        $stringToSign = "$timestamp`n$secret"         # 构建待签名字符串

        # 创建 HmacSHA256 实例并设置密钥
        $hmac = New-Object System.Security.Cryptography.HMACSHA256
        $hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($secret)

        $signData = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($stringToSign))  # 计算签名

        $base64Sign = [System.Convert]::ToBase64String($signData) # Base64 编码
        $urlEncodedSign = [uri]::EscapeDataString($base64Sign) # URL 编码

        return "$server&timestamp=$timestamp&sign=$urlEncodedSign"
    }

    # 发送消息
    [void] sendContent([string]$server, [string]$title, [string]$message) {

        [PSCustomObject]$body = $this.buildContent($title, $message)
        $jsonBody = $body | ConvertTo-Json -Depth 10  -Compress 

        $bytes = [System.Text.Encoding]::UTF8.GetBytes($jsonBody)

        $response = Invoke-WebRequest -Uri $server -Method Post -Body $bytes -ContentType "application/json" -UseBasicParsing

        $this.verifyResponse($response)
    }

    [PSCustomObject]buildContent([string]$title, [string]$message) {

        return [PSCustomObject]@{
            msgtype  = "markdown"
            markdown = [PSCustomObject]@{
                title = $title
                text  = $message
            }
        }
    }

    # 解析 Invoke-WebRequest 返回结果
    [void]verifyResponse(<# [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject] 有些机器上没有这个类型 #> $response) {

        if ($response.StatusCode -ne 200) {
            throw [ApplicationException]::new("Failed to send message, [$($response.StatusCode)], $($response.StatusDescription)")
        }

        $json = $response.Content | ConvertFrom-Json        
        if ($json.errcode -ne 0) {            
            throw [System.ApplicationException]::new("Failed to send message, [$($json.errcode)], $($json.errmsg)")
        }
    }

    static [string] buildMarkdownMessage([string]$title, [string[]]$messages) {

        $markdown = @()
        $markdown += "### $title"
        foreach ($message in $messages) {
            $markdown += "- $message"
        }

        return [string]::Join("`n", $markdown)
    }

    static [DingMessage] createDefault() {

        $message = [DingMessage]::new()
        $message.secret = "xxxxx" 
        $message.ServerUrl = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"

        return $message

    }
}

try {

    $title = "备份完成"
    $content = [DingMessage]::buildMarkdownMessage($title, @("备份时间:$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')", "备份机器:$([System.Environment]::MachineName)",  "备份结果:成功"))

    $message =[DingMessage]::createDefault()

    $message.send($title, $content)
}
catch {
    Write-Error "Error: $($_.Exception.Message)"    
    throw $_.Exception
}
上一篇
下一篇