diff --git a/.gitignore b/.gitignore index 91c797a..b411b21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /log/singleton.log /config.sh +/Config.ps1 /crons/*.status /distinct/*.msg /git-prompt.sh diff --git a/Discord.ps1 b/Discord.ps1 new file mode 100644 index 0000000..9fa0e73 --- /dev/null +++ b/Discord.ps1 @@ -0,0 +1,88 @@ +############### +# Discord.ps1 # +############### +# +# Windows Powershell Script for logging to Discord using a webhook intergration. +# Just like the bash script, except it will use config.ps1 instead of config.sh. +# Also supports skipping the send if the message is a duplicate. +# +# Script Parameters: +# -message (Pipeline) The message you want to log into discord. +# [-distinct] Optional, distinct name, will skip duplicate messages. +# [-webhook] Optional, Webhook URL, defaults to config. +# [-botName] Optional, Webhook Name, default to config. +# +### Example +# Run from CMD or Batch file to transmit the message to Discord: +# CMD> powershell.exe -File .\Discord.ps1 -message "Here is some content to send to Discord." +# or pipeline in powershell: +# PS1> echo "Here is some content to send to Discord" | .\Discord.ps1 +# +# You can also pass the "-distinct" option to prevent duplicate messages: +# PS1> echo "same message twice" | .\Discord.ps1 -distinct "my-key" +# # message sent +# PS1> echo "same message twice" | .\Discord.ps1 -distinct "my-key" +# # duplicate message ignored +# + +param ( + [parameter (ValueFromPipeline = $true)] [string[]] $message, + [string] $distinct, + [string] $webhook, + [string] $botName +) +begin { + $chunk = "" + [string[]] $chunks = New-Object string[] 0 + + # load in defaults from config + $configFile = "$PSScriptRoot\\Config.ps1" + if (Test-Path -Path $configFile) { + . $configFile + + if ( ! $webhook) { + $webhook = $DISCORD_WINDOWS_HOOK + } + if ( ! $botName) { + $botName = $DISCORD_SERVER_NAME + } + } + + # load internal function + . "$PSScriptRoot\\SendDiscordChunk.ps1" +} +process { + # build up the full message + foreach ($line in $message) { + if ($chunk.length + $line.length -gt 1800) { + # if adding the line will make it too long, queue existing chunk and reset + $chunks += $chunk + $chunk = "" + } + $chunk += $line + "`n" + } +} +end { + # complete last chunk, by queuing it up + $chunks += $chunk + + if ($distinct) { + $distinctFile = "$PSScriptRoot\\distinct\\$distinct.msg" + if (Test-Path -Path $distinctFile) { + [string[]] $oldMessage = Get-Content -Path $distinctFile + } + } + + if (($oldMessage -join "`n") -ne ($message -join "`n")) { + # finally send each chunk of the message + foreach ($chunk in $chunks) { + SendDiscordMessage -message $chunk -webhook $webhook -botName $botName + } + + # if distinct, store the updated message for future checking + if ($distinct) { + Out-File -FilePath $distinctFile -InputObject $message + } + } +} + diff --git a/Dynv6.ps1 b/Dynv6.ps1 index 3c2f235..46882ea 100644 --- a/Dynv6.ps1 +++ b/Dynv6.ps1 @@ -1,39 +1,25 @@ ################### # UpdateDynv6.ps1 # ################### -# Windows Powershell Script for updating -# Dynamic DNS on Dynv6.com using the RESTful -# interface. Use the windows task schedualer -# to automatically run. # -# !!!WARNING!!!! -# This is a Proof Of Consept script! -# The next version will be turned into a proper -# cmdlet and packed into a Posershell Module. +# Windows Powershell Script for updating Dynamic DNS on Dynv6.com using the +# RESTful interface. Use the windows task schedualer to automatically run. # # Script Parameters: -# -zone -# DNS Zone (domain name) to update. -# -# -token -# HTTP Token. https://dynv6.com/keys#token -# -# [-logfile] -# Path to update log file. By default the file will be placed in: -# $env:USERPROFILE\\DDNS_UPDATE_LOG -# -# [-isIPV6] -# Attempt to update the zone using an IPV6 address. +# -zone DNS Zone (domain name) to update. +# -token HTTP Token, see: https://dynv6.com/keys#token +# [-netmask] Optional, IPv6 netmask, defaults to 128. +# [-logfile] Optional, filename to log to, defaults to "~/.dynv6.log". +# [-ipv4] Optional, IPv4 override, to skip resolving. +# [-ipv6] Optional, IPv6 override, to skip resolving. # ### Example -# Run from CMD or Batch file to update with an IPV4: -# Powershell -ExecutionPolicy Unrestricted -File ./UpdateDynv6.ps1 -zone 'ExampleDomain.com' -token 'XXXXXXXXXXXXXXXXXXXXXXXX' -# -### Run from CMD or Batch file to update with an IPV6: -# Powershell -ExecutionPolicy Unrestricted -File ./UpdateDynv6.ps1 -zone 'ExampleDomain.com' -token 'XXXXXXXXXXXXXXXXXXXXXXXX' -isIPV6 +# Run from CMD or Batch file to IPv4 and IPv6 with automatic lookup: +# powershell.exe -File ./Dynv6.ps1 -zone "ExampleDomain.com" -token "XXXXXX" # ################### # Copyright 2020 Joe Herbert ( djneonc@gmail.com ) +# Copyright 2023 Andrew Stowell ( andrew@digitaladapt.com ) # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -88,12 +74,12 @@ $update6 = [System.Uri]'https://dynv6.com/api/update' Get-Date | Tee-Object -FilePath $logfile -Append | Out-Host # lookup IPv4, will be skipped if variable already set -if ($ipv4 -eq "") { +if ( ! $ipv4) { $ipv4 = Invoke-RestMethod -Method Get -Uri $lookup4 } # lookup IPv6, will be skipped if variable already set -if ($ipv6 -eq "") { +if ( ! $ipv6) { $ipv6 = Invoke-RestMethod -Method Get -Uri $lookup6 } $ipv6 = "$ipv6/$netmask" diff --git a/SendDiscordChunk.ps1 b/SendDiscordChunk.ps1 new file mode 100644 index 0000000..23f046a --- /dev/null +++ b/SendDiscordChunk.ps1 @@ -0,0 +1,35 @@ +# internal function to transmit a discord chunk +function SendDiscordMessage +{ + param ( + [string] $message = $(throw "-message is required"), + [string] $webhook = $(throw "-webhook is required"), + [string] $botName = $(throw "-botName is required") + ) + + # force utf-8, because that is what Discord needs + $OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding + + $header = "Content-Type: application/json" + + # convert string into json, escaping the given message + $message = ConvertTo-Json -InputObject $message + $botName = ConvertTo-Json -InputObject $botName + + # rewrite json string, because "\u001b[m" needs to "\u001b[0m" instead + # windows is fine with the missing zero, but discord needs it + $message = $message -Replace "\\u001b\[m", "\u001b[0m" + + # remove wrapping quotes around json string, replace with color-enabled block quotes + $message = '"```ansi\n' + $message.SubString(1, $message.length - 2) + '\n```"' + + # {"username": "$botName", "content": "$message"} + $content = "{"; + if ($botName) { + $content += '"username": ' + $botName + ', '; + } + $content += '"content": ' + $message + '}'; + + echo "$content" | curl.exe -s -H "$header" -X "POST" -d "@-" "$webhook" | ConvertFrom-Json | Select-Object -Property id | Out-Host +} + diff --git a/config.example.ps1 b/config.example.ps1 new file mode 100644 index 0000000..e8b9f45 --- /dev/null +++ b/config.example.ps1 @@ -0,0 +1,6 @@ +# copy to config.ps1 and update with your information + +$DISCORD_SERVER_NAME = "" + +$DISCORD_WINDOWS_HOOK = "?wait=true" + diff --git a/config.example.sh b/config.example.sh index 3d756bd..1a29015 100644 --- a/config.example.sh +++ b/config.example.sh @@ -26,7 +26,7 @@ PRUNE_DOWN_TO=0 SERVER_DOMAIN="localhost" -DISCORD_SERVER_NAME="" +DISCORD_SERVER_NAME="" DISCORD_GENERAL_HOOK="?wait=true"