Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation for CodeBlock element #298

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ A package to send messages to a Microsoft Teams channel.
- [Basic](#basic)
- [Specify proxy server](#specify-proxy-server)
- [User Mention](#user-mention)
- [CodeBlock](#codeblock)
- [Tables](#tables)
- [Set custom user agent](#set-custom-user-agent)
- [Add an Action](#add-an-action)
Expand Down Expand Up @@ -396,6 +397,14 @@ deprecated][o365-connector-retirement-announcement] `MessageCard` card format.
- File: [user-mention-verbose](./examples/adaptivecard/user-mention-verbose/main.go)
- this example does not necessarily reflect an optimal implementation

#### CodeBlock

This example illustrates the use of a [`CodeBlock`][adaptivecard-codeblock].
This feature is not available in the legacy [🚫
deprecated][o365-connector-retirement-announcement] `MessageCard` card format.

- File: [codeblock](./examples/adaptivecard/codeblock/main.go)

#### Tables

These examples illustrates the use of a [`Table`][adaptivecard-table]. This
Expand Down Expand Up @@ -511,4 +520,6 @@ using either this library or the original project.
[adaptivecard-user-mentions]: <https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format#mention-support-within-adaptive-cards>
[adaptivecard-table]: <https://adaptivecards.io/explorer/Table.html>

[adaptivecard-codeblock]: <https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format?tabs=adaptive-md%2Cdesktop%2Cconnector-html#codeblock-in-adaptive-cards>

<!-- []: PLACEHOLDER "DESCRIPTION_HERE" -->
34 changes: 32 additions & 2 deletions adaptivecard/adaptivecard.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ const (
TypeElementTextRun string = "TextRun" // Introduced in version 1.2
)

// Known exension types for an Adaptive Card element.
// Known extension types for an Adaptive Card element.
//
// - https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format?tabs=adaptive-md%2Cdesktop%2Cconnector-html#codeblock-in-adaptive-cards
const (
Expand Down Expand Up @@ -612,7 +612,7 @@ type Element struct {
// CodeSnippet provides the content for a CodeBlock element, specific to MSTeams.
CodeSnippet string `json:"codeSnippet,omitempty"`

// Language specifies the langauge of a CodeBlock element, specific to MSTeams.
// Language specifies the language of a CodeBlock element, specific to MSTeams.
Language string `json:"language,omitempty"`

// StartLineNumber specifies the initial line number of CodeBlock element, specific to MSTeams.
Expand Down Expand Up @@ -3167,6 +3167,36 @@ func (c *Card) AddContainer(prepend bool, container Container) error {

// NewCodeBlock creates a new CodeBlock element with snippet, language, and
// optional firstLine. This is an MSTeams extension element.
//
// Supported languages include:
//
// - Bash
// - C
// - C#
// - C++
// - CSS
// - DOS
// - Go
// - GraphQL
// - HTML
// - Java
// - JavaScript
// - JSON
// - Perl
// - PHP
// - PlainText
// - PowerShell
// - Python
// - SQL
// - TypeScript
// - Verilog
// - VHDL
// - Visual Basic
// - XML
//
// See
// https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format
// for additional languages that may be supported.
func NewCodeBlock(snippet string, language string, firstLine int) Element {
codeBlock := Element{
Type: TypeElementMSTeamsCodeBlock,
Expand Down
128 changes: 128 additions & 0 deletions examples/adaptivecard/codeblock/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2022 Adam Chalkley
//
// https://github.com/atc0005/go-teams-notify
//
// Licensed under the MIT License. See LICENSE file in the project root for
// full license information.

/*

This is an example of a client application which uses this library to generate
a Microsoft Teams message containing a codeblock in Adaptive Card format.

Of note:

- default timeout
- package-level logging is disabled by default
- validation of known webhook URL formats is *enabled*
- message submitted to Microsoft Teams consisting of title, formatted message
body and embedded codeblock

See these links for Adaptive Card text formatting options:

- https://docs.microsoft.com/en-us/adaptive-cards/authoring-cards/text-features
- https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-format?tabs=adaptive-md%2Cdesktop%2Cconnector-html#codeblock-in-adaptive-cards


*/

package main

import (
"log"
"os"
"strings"

goteamsnotify "github.com/atc0005/go-teams-notify/v2"
"github.com/atc0005/go-teams-notify/v2/adaptivecard"
)

func main() {

// Initialize a new Microsoft Teams client.
mstClient := goteamsnotify.NewTeamsClient()

// Set webhook url.
//
// NOTE: This is for illustration purposes only. Best practice is to NOT
// hardcode credentials of any kind.
webhookUrl := "https://example.logic.azure.com:443/workflows/GUID_HERE/triggers/manual/paths/invoke?api-version=YYYY-MM-DD&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE_HERE"

// Allow specifying webhook URL via environment variable, fall-back to
// hard-coded value in this example file.
expectedEnvVar := "WEBHOOK_URL"
envWebhookURL := os.Getenv(expectedEnvVar)
switch {
case envWebhookURL != "":
log.Printf(
"Using webhook URL %q from environment variable %q\n\n",
envWebhookURL,
expectedEnvVar,
)
webhookUrl = envWebhookURL
default:
log.Println(expectedEnvVar, "environment variable not set.")
log.Printf("Using hardcoded value %q as fallback\n\n", webhookUrl)
}

// The title for message (first TextBlock element).
msgTitle := "Hello world"

// Formatted message body.
msgText := "Here are some examples of formatted stuff like " +
"\n * this list itself \n * **bold** \n * *italic* \n * ***bolditalic***"

// Create card using provided formatted title and text. We'll modify the
// card and when finished use it to generate a message for delivery.
card, err := adaptivecard.NewTextBlockCard(msgText, msgTitle, true)
if err != nil {
log.Printf(
"failed to create card: %v",
err,
)
os.Exit(1)
}

// See also https://yourbasic.org/golang/multiline-string/ for other
// approaches to embedding formatted strings.
codeSnippet := `
package main

import "log/slog"

func main() {
slog.Info("hello, world")
}
`

// If you want to strip leading/trailing whitespace.
codeSnippet = strings.TrimSpace(codeSnippet)

// Create CodeBlock using our snippet.
codeBlock := adaptivecard.NewCodeBlock(codeSnippet, "Go", 1)

// Add CodeBlock to our Card.
if err := card.AddElement(false, codeBlock); err != nil {
log.Printf(
"failed to add codeblock to card: %v",
err,
)
os.Exit(1)
}

// Create Message from Card
msg, err := adaptivecard.NewMessageFromCard(card)
if err != nil {
log.Printf("failed to create message from card: %v", err)
os.Exit(1)
}

// Send the message with default timeout/retry settings.
if err := mstClient.Send(webhookUrl, msg); err != nil {
log.Printf(
"failed to send message: %v",
err,
)
os.Exit(1)
}
}
Loading