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

Added YAML en(de)coding support to MessageCard #169

Merged
merged 1 commit into from Jun 29, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
114 changes: 57 additions & 57 deletions messagecard/messagecard.go
Expand Up @@ -64,11 +64,11 @@ var ErrPotentialActionsLimitReached = errors.New("potential actions collection l
type PotentialAction struct {
// Type of the potential action. Can be OpenUri, HttpPOST, ActionCard or
// InvokeAddInCommand.
Type string `json:"@type"`
Type string `json:"@type" yaml:"@type"`

// Name property defines the text that will be displayed on screen for the
// action.
Name string `json:"name"`
Name string `json:"name" yaml:"name"`

// PotentialActionOpenURI is a set of options for openUri
// potential action.
Expand All @@ -91,27 +91,27 @@ type PotentialAction struct {
type PotentialActionOpenURI struct {
// Targets is a collection of name/value pairs that defines one URI per
// target operating system. Only used for OpenUri action type.
Targets []PotentialActionOpenURITarget `json:"targets,omitempty"`
Targets []PotentialActionOpenURITarget `json:"targets,omitempty" yaml:"targets,omitempty"`
}

// PotentialActionHTTPPOST represents a HttpPOST potential action.
type PotentialActionHTTPPOST struct {
// Target defines the URL endpoint of the service that implements the
// action. Only used for HttpPOST action type.
Target string `json:"target,omitempty"`
Target string `json:"target,omitempty" yaml:"target,omitempty"`

// Headers is a collection of MessageCardPotentialActionHeader objects
// representing a set of HTTP headers that will be emitted when sending
// the POST request to the target URL. Only used for HttpPOST action type.
Headers []PotentialActionHTTPPOSTHeader `json:"headers,omitempty"`
Headers []PotentialActionHTTPPOSTHeader `json:"headers,omitempty" yaml:"headers,omitempty"`

// Body is the body of the POST request. Only used for HttpPOST action
// type.
Body string `json:"body,omitempty"`
Body string `json:"body,omitempty" yaml:"body,omitempty"`

// BodyContentType is optional and specifies the MIME type of the body in
// the POST request. Only used for HttpPOST action type.
BodyContentType string `json:"bodyContentType,omitempty"`
BodyContentType string `json:"bodyContentType,omitempty" yaml:"bodyContentType,omitempty"`
}

// PotentialActionActionCard represents an actionCard potential
Expand All @@ -120,22 +120,22 @@ type PotentialActionActionCard struct {
// Inputs is a collection of inputs an user can provide before processing
// the actions. Only used for ActionCard action type. Three types of
// inputs are available: TextInput, DateInput and MultichoiceInput
Inputs []PotentialActionActionCardInput `json:"inputs,omitempty"`
Inputs []PotentialActionActionCardInput `json:"inputs,omitempty" yaml:"inputs,omitempty"`

// Actions are the available actions. Only used for ActionCard action
// type.
Actions []PotentialActionActionCardAction `json:"actions,omitempty"`
Actions []PotentialActionActionCardAction `json:"actions,omitempty" yaml:"actions,omitempty"`
}

// PotentialActionActionCardAction is used for configuring ActionCard actions
type PotentialActionActionCardAction struct {
// Type of the action. Can be OpenUri, HttpPOST, ActionCard or
// InvokeAddInCommand.
Type string `json:"@type"`
Type string `json:"@type" yaml:"@type"`

// Name property defines the text that will be displayed on screen for the
// action.
Name string `json:"name"`
Name string `json:"name" yaml:"name"`

// PotentialActionOpenURI is used to specify a openUri action
// card's action.
Expand All @@ -151,19 +151,19 @@ type PotentialActionActionCardAction struct {
type PotentialActionInvokeAddInCommand struct {
// AddInID specifies the add-in ID of the required add-in. Only used for
// InvokeAddInCommand action type.
AddInID string `json:"addInId,omitempty"`
AddInID string `json:"addInId,omitempty" yaml:"addInId,omitempty"`

// DesktopCommandID specifies the ID of the add-in command button that
// opens the required task pane. Only used for InvokeAddInCommand action
// type.
DesktopCommandID string `json:"desktopCommandId,omitempty"`
DesktopCommandID string `json:"desktopCommandId,omitempty" yaml:"desktopCommandId,omitempty"`

// InitializationContext is an optional field which provides developers a
// way to specify any valid JSON object. The value is serialized into a
// string and made available to the add-in when the action is executed.
// This allows the action to pass initialization data to the add-in. Only
// used for InvokeAddInCommand action type.
InitializationContext interface{} `json:"initializationContext,omitempty"`
InitializationContext interface{} `json:"initializationContext,omitempty" yaml:"initializationContext,omitempty"`
}

// PotentialActionOpenURITarget is used for OpenUri action type.
Expand All @@ -173,38 +173,38 @@ type PotentialActionOpenURITarget struct {
// operating system values are default, windows, iOS and android. The
// default operating system will in most cases simply open the URI in a
// web browser, regardless of the actual operating system.
OS string `json:"os,omitempty"`
OS string `json:"os,omitempty" yaml:"os,omitempty"`

// URI defines the URI being called.
URI string `json:"uri,omitempty"`
URI string `json:"uri,omitempty" yaml:"uri,omitempty"`
}

// PotentialActionHTTPPOSTHeader defines a HTTP header used for HttpPOST action type.
type PotentialActionHTTPPOSTHeader struct {
// Name is the header name.
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`

// Value is the header value.
Value string `json:"value,omitempty"`
Value string `json:"value,omitempty" yaml:"value,omitempty"`
}

// PotentialActionActionCardInput represents an ActionCard input.
type PotentialActionActionCardInput struct {
// Type of the ActionCard input.
// Must be either TextInput, DateInput or MultichoiceInput
Type string `json:"@type"`
Type string `json:"@type" yaml:"@type"`

// ID uniquely identifies the input so it is possible to reference it in
// the URL or body of an HttpPOST action.
ID string `json:"id,omitempty"`
ID string `json:"id,omitempty" yaml:"id,omitempty"`

// Title defines a title for the input.
Title string `json:"title,omitempty"`
Title string `json:"title,omitempty" yaml:"title,omitempty"`

// Value defines the initial value of the input. For multi-choice inputs,
// value must be equal to the value property of one of the input's
// choices.
Value string `json:"value,omitempty"`
Value string `json:"value,omitempty" yaml:"value,omitempty"`

// MessageCardPotentialActionInputMultichoiceInput must be defined for
// MultichoiceInput input type.
Expand All @@ -221,19 +221,19 @@ type PotentialActionActionCardInput struct {
// IsRequired indicates whether users are required to type a value before
// they are able to take an action that would take the value of the input
// as a parameter.
IsRequired bool `json:"isRequired,omitempty"`
IsRequired bool `json:"isRequired,omitempty" yaml:"isRequired,omitempty"`
}

// PotentialActionActionCardInputTextInput represents a TextInput
// input used for potential action.
type PotentialActionActionCardInputTextInput struct {
// MaxLength indicates the maximum number of characters that can be
// entered.
MaxLength int `json:"maxLength,omitempty"`
MaxLength int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`

// IsMultiline indicates whether the text input should accept multiple
// lines of text.
IsMultiline bool `json:"isMultiline,omitempty"`
IsMultiline bool `json:"isMultiline,omitempty" yaml:"isMultiline,omitempty"`
}

// PotentialActionActionCardInputMultichoiceInput represents a
Expand All @@ -242,52 +242,52 @@ type PotentialActionActionCardInputMultichoiceInput struct {
// Choices defines the values that can be selected for the multichoice
// input.
Choices []struct {
Display string `json:"display,omitempty"`
Value string `json:"value,omitempty"`
} `json:"choices,omitempty"`
Display string `json:"display,omitempty" yaml:"display,omitempty"`
Value string `json:"value,omitempty" yaml:"value,omitempty"`
} `json:"choices,omitempty" yaml:"choices,omitempty"`

// Style defines the style of the input. When IsMultiSelect is false,
// setting the style property to expanded will instruct the host
// application to try and display all choices on the screen, typically
// using a set of radio buttons.
Style string `json:"style,omitempty"`
Style string `json:"style,omitempty" yaml:"style,omitempty"`

// IsMultiSelect indicates whether or not the user can select more than
// one choice. The specified choices will be displayed as a list of
// checkboxes. Default value is false.
IsMultiSelect bool `json:"isMultiSelect,omitempty"`
IsMultiSelect bool `json:"isMultiSelect,omitempty" yaml:"isMultiSelect,omitempty"`
}

// PotentialActionActionCardInputDateInput represents a DateInput
// input used for potential action.
type PotentialActionActionCardInputDateInput struct {
// IncludeTime indicates whether the date input should allow for the
// selection of a time in addition to the date.
IncludeTime bool `json:"includeTime,omitempty"`
IncludeTime bool `json:"includeTime,omitempty" yaml:"includeTime,omitempty"`
}

// SectionFact represents a section fact entry that is usually displayed in a
// two-column key/value format.
type SectionFact struct {

// Name is the key for an associated value in a key/value pair
Name string `json:"name"`
Name string `json:"name" yaml:"name"`

// Value is the value for an associated key in a key/value pair
Value string `json:"value"`
Value string `json:"value" yaml:"value"`
}

// SectionImage represents an image as used by the heroImage and images
// properties of a section.
type SectionImage struct {

// Image is the URL to the image.
Image string `json:"image"`
Image string `json:"image" yaml:"image"`

// Title is a short description of the image. Typically, this description
// is displayed in a tooltip as the user hovers their mouse over the
// image.
Title string `json:"title"`
Title string `json:"title" yaml:"title"`
}

// Section represents a section to include in a message card.
Expand All @@ -297,33 +297,33 @@ type Section struct {
// It is meant to introduce the section and summarize its content,
// similarly to how the card's title property is meant to summarize the
// whole card.
Title string `json:"title,omitempty"`
Title string `json:"title,omitempty" yaml:"title,omitempty"`

// Text is the section's text property. This property is very similar to
// the text property of the card. It can be used for the same purpose.
Text string `json:"text,omitempty"`
Text string `json:"text,omitempty" yaml:"text,omitempty"`

// ActivityImage is a property used to display a picture associated with
// the subject of a message card. For example, this might be the portrait
// of a person who performed an activity that the message card is
// associated with.
ActivityImage string `json:"activityImage,omitempty"`
ActivityImage string `json:"activityImage,omitempty" yaml:"activityImage,omitempty"`

// ActivityTitle is a property used to summarize the activity associated
// with a message card.
ActivityTitle string `json:"activityTitle,omitempty"`
ActivityTitle string `json:"activityTitle,omitempty" yaml:"activityTitle,omitempty"`

// ActivitySubtitle is a property used to show brief, but extended
// information about an activity associated with a message card. Examples
// include the date and time the associated activity was taken or the
// handle of a person associated with the activity.
ActivitySubtitle string `json:"activitySubtitle,omitempty"`
ActivitySubtitle string `json:"activitySubtitle,omitempty" yaml:"activitySubtitle,omitempty"`

// ActivityText is a property used to provide details about the activity.
// For example, if the message card is used to deliver updates about a
// topic, then this property would be used to hold the bulk of the content
// for the update notification.
ActivityText string `json:"activityText,omitempty"`
ActivityText string `json:"activityText,omitempty" yaml:"activityText,omitempty"`

// HeroImage is a property that allows for setting an image as the
// centerpiece of a message card. This property can also be used to add a
Expand All @@ -335,11 +335,11 @@ type Section struct {
// https://github.com/golang/go/issues/11939
// https://stackoverflow.com/questions/18088294/how-to-not-marshal-an-empty-struct-into-json-with-go
// https://stackoverflow.com/questions/33447334/golang-json-marshal-how-to-omit-empty-nested-struct
HeroImage *SectionImage `json:"heroImage,omitempty"`
HeroImage *SectionImage `json:"heroImage,omitempty" yaml:"heroImage,omitempty"`

// Facts is a collection of SectionFact values. A section entry
// usually is displayed in a two-column key/value format.
Facts []SectionFact `json:"facts,omitempty"`
Facts []SectionFact `json:"facts,omitempty" yaml:"facts,omitempty"`

// Images is a property that allows for the inclusion of a photo gallery
// inside a section.
Expand All @@ -348,70 +348,70 @@ type Section struct {
// https://github.com/golang/go/issues/11939
// https://stackoverflow.com/questions/18088294/how-to-not-marshal-an-empty-struct-into-json-with-go
// https://stackoverflow.com/questions/33447334/golang-json-marshal-how-to-omit-empty-nested-struct
Images []*SectionImage `json:"images,omitempty"`
Images []*SectionImage `json:"images,omitempty" yaml:"images,omitempty"`

// PotentialActions is a collection of actions for a Section.
// This is separate from the actions collection for the MessageCard.
PotentialActions []*PotentialAction `json:"potentialAction,omitempty"`
PotentialActions []*PotentialAction `json:"potentialAction,omitempty" yaml:"potentialAction,omitempty"`

// Markdown represents a toggle to enable or disable Markdown formatting.
// By default, all text fields in a card and its sections can be formatted
// using basic Markdown.
Markdown bool `json:"markdown,omitempty"`
Markdown bool `json:"markdown,omitempty" yaml:"markdown,omitempty"`

// StartGroup is the section's startGroup property. This property marks
// the start of a logical group of information. Typically, sections with
// startGroup set to true will be visually separated from previous card
// elements.
StartGroup bool `json:"startGroup,omitempty"`
StartGroup bool `json:"startGroup,omitempty" yaml:"startGroup,omitempty"`
}

// MessageCard represents a legacy actionable message card used via Office 365
// or Microsoft Teams connectors.
type MessageCard struct {
// Required; must be set to "MessageCard"
Type string `json:"@type"`
Type string `json:"@type" yaml:"@type"`

// Required; must be set to "https://schema.org/extensions"
Context string `json:"@context"`
Context string `json:"@context" yaml:"@context"`

// Summary is required if the card does not contain a text property,
// otherwise optional. The summary property is typically displayed in the
// list view in Outlook, as a way to quickly determine what the card is
// all about. Summary appears to only be used when there are sections defined
Summary string `json:"summary,omitempty"`
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"`

// Title is the title property of a card. is meant to be rendered in a
// prominent way, at the very top of the card. Use it to introduce the
// content of the card in such a way users will immediately know what to
// expect.
Title string `json:"title,omitempty"`
Title string `json:"title,omitempty" yaml:"title,omitempty"`

// Text is required if the card does not contain a summary property,
// otherwise optional. The text property is meant to be displayed in a
// normal font below the card's title. Use it to display content, such as
// the description of the entity being referenced, or an abstract of a
// news article.
Text string `json:"text,omitempty"`
Text string `json:"text,omitempty" yaml:"text,omitempty"`

// Specifies a custom brand color for the card. The color will be
// displayed in a non-obtrusive manner.
ThemeColor string `json:"themeColor,omitempty"`
ThemeColor string `json:"themeColor,omitempty" yaml:"themeColor,omitempty"`

// ValidateFunc is an optional user-specified validation function that is
// responsible for validating a MessageCard. If not specified, default
// validation is performed.
ValidateFunc func() error `json:"-"`
ValidateFunc func() error `json:"-" yaml:"-"`

// Sections is a collection of sections to include in the card.
Sections []*Section `json:"sections,omitempty"`
Sections []*Section `json:"sections,omitempty" yaml:"sections,omitempty"`

// PotentialActions is a collection of actions for a MessageCard.
PotentialActions []*PotentialAction `json:"potentialAction,omitempty"`
PotentialActions []*PotentialAction `json:"potentialAction,omitempty" yaml:"potentialAction,omitempty"`

// payload is a prepared MessageCard in JSON format for submission or
// pretty printing.
payload *bytes.Buffer `json:"-"`
payload *bytes.Buffer `json:"-" yaml:"-"`
}

// validatePotentialAction inspects the given *PotentialAction
Expand Down