EvotecIT / PSTeams

PSTeams is a PowerShell Module working on Windows / Linux and Mac. It allows sending notifications to Microsoft Teams via WebHook Notifications. It's pretty flexible and provides a bunch of options. Initially, it only supported one sort of Team Cards but since version 2.X.X it supports Adaptive Cards, Hero Cards, List Cards, and Thumbnail Cards. All those new cards have their own cmdlets and the old version of creating Teams Cards stays as-is for compatibility reasons.
MIT License
409 stars 41 forks source link

-Text strings ignore '_' underscore character. #30

Open TechDufus opened 3 years ago

TechDufus commented 3 years ago

When including the underscore character in any -Text value, the underscores are replaced with null space.

Example:

$PoolName = "App_Pool_01"
$SectionParams = @{
    ActivityTitle = "**Application Pool Recycle**"
    ActivitySubtitle = "@$env:USERNAME - $(Get-Date)"
    ActivityText = "Recycled Pool: $PoolName"
    SectionInput = [scriptblock] {
        New-TeamsButton -Name 'View Logs' -Type OpenUri -Link 'https://some.link.com'
    }
    Text = "An app pool recycle of $PoolName was initiated by $env:USERNAME"
}
Send-TeamsMessage {
    New-TeamsSection @SectionParams
} -Uri $Uri -Color DarkSeaGreen -MessageSummary 'Pool Recycle'

You can see in the following screenshot that it was removed the underscores from the app pool names.

image

PrzemyslawKlys commented 3 years ago

Actually, they don't ignore it, but in my opinion, they try to convert it to markdown.

Teams support basic markdown. _test_ should give you italics. And that's what I see on the screen, that Pool01 is converted to italics. Is it possible the name is App_Pool_01? If so, you would need to escape it.

PrzemyslawKlys commented 3 years ago

I can see in issue https://github.com/jenkinsci/office-365-connector-plugin/issues/82 someone proposed using ticks

facts:
- name: "With back ticks"
  value: "`{{ this_is_it }}`"

Try it out.

PrzemyslawKlys commented 3 years ago
New-AdaptiveCard -Uri $Env:TEAMSPESTERID -VerticalContentAlignment center {
    New-AdaptiveColumnSet {
        New-AdaptiveColumn {
            New-AdaptiveTextBlock -Size 'Medium' -Text 'Test Card _Title_ 1' -Color Warning
            New-AdaptiveTextBlock -Size 'Medium' -Text "Test Card \_Title_ 1" -Color Warning # This works
            New-AdaptiveTextBlock -Size 'Medium' -Text "Test Card \_Title\_ 1" -Color Warning # This works
            $Text = "Test Card _Title_ 1" -replace '_','\_'
            New-AdaptiveTextBlock -Size 'Medium' -Text $Text -Color Warning # This works
        }
    }
} -Verbose

So potentially we could add a switch called -EscapeMarkdown which would find all possible options that markdown triggers on and have it automatically fix it for a user. For now, my suggestion is to simply use the replacement proposed.

TechDufus commented 3 years ago

Good call.. I wrote this function to fix this...

        #Region Invoke-EscapeCharacters

        Function Invoke-EscapeCharacters() {
            [CmdletBinding()]
            Param(
                [Parameter()]
                [Char] $Character,

                [Parameter(Mandatory)]
                [System.String] $InputString
            )

            Process {
                [System.String] $Character = $Character.ToString()
                $InputString.Replace($Character, "\$Character")
            }
        }
        #EndRegion Invoke-EscapeCharacters

My code looks something like this for now...

$PoolName = "App_Pool_01"
$SectionParams = @{
    ActivityTitle = "**Application Pool Recycle**"
    ActivitySubtitle = "@$env:USERNAME - $(Get-Date)"
    ActivityText = (Invoke-EscapeCharacters -Character _ -InputString "Recycled Pool: $PoolName")
    SectionInput = [scriptblock] {
        New-TeamsButton -Name 'View Logs' -Type OpenUri -Link 'https://some.link.com'
    }
    Text = "An app pool recycle of $(Invoke-EscapeCharacters -Character _ -InputString $PoolName) was initiated by $env:USERNAME"
}
Send-TeamsMessage {
    New-TeamsSection @SectionParams
} -Uri $Uri -Color DarkSeaGreen -MessageSummary 'Pool Recycle'
PrzemyslawKlys commented 3 years ago

You don't need to do this inside Text. You can do it for the whole text. That is my point. As long as you don't plan using markdown you can escape all _ it can find. Same for * and other markdown chars. This way you don't have to "think" about it.

TechDufus commented 3 years ago

How exactly would you do this for the whole Text at once? o.O

PrzemyslawKlys commented 3 years ago

Using your function and example:

Function Invoke-EscapeCharacters() {
    [CmdletBinding()]
    Param(
        [Parameter()]
        [Char] $Character,

        [Parameter(Mandatory)]
        [System.String] $InputString
    )

    Process {
        [System.String] $Character = $Character.ToString()
        $InputString.Replace($Character, "\$Character")
    }
}
#EndRegion Invoke-EscapeCharacters

$PoolName = "App_Pool_01"
$SectionParams = @{
    ActivityTitle    = "**Application Pool Recycle**"
    ActivitySubtitle = "@$env:USERNAME - $(Get-Date)"
    ActivityText     = (Invoke-EscapeCharacters -Character _ -InputString "Recycled Pool: $PoolName")
    SectionInput     = [scriptblock] {
        New-TeamsButton -Name 'View Logs' -Type OpenUri -Link 'https://some.link.com'
    }
    Text             = Invoke-EscapeCharacters -Character _ -InputString "An app pool recycle of $PoolName was initiated by $env:USERNAME"
}
Send-TeamsMessage {
    New-TeamsSection @SectionParams
} -Uri $Uri -Color DarkSeaGreen -MessageSummary 'Pool Recycle'

image

In other words it would be possible to easily extend all text functions to turn off Markdown. In theory it would be possible to "disable" markdown on Send-TeamsMessage level as well - I guess.

I hope someone will try to PR this. Otherwise if I will have a need for it I'll fix it myself.