apps

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2021 License: Apache-2.0 Imports: 10 Imported by: 35

Documentation

Overview

Package apps provides the data types, constants, and convenience functions for the Mattermost Apps API.

Main documentation: https://developers.mattermost.com/integrate/apps/

Function

Functions are invoked in response to a user or a notification event. A Function to invoke is described by a Call, and is passed a CallRequest when invoked. For user-invoked functions, the inputs can be collected from the user with a Form, either as a modal, or as a /command with autocomplete.

Call

A Call is a general request to an App server. Calls are used to fetch App's bindings, and to process user input, webhook events, and dynamic data lookups. The Call struct defines what function to invoke, and how.

CallRequest is passed to functions at invocation time. It includes the originating Call, and adds user-input values, Context, etc. CallResponse is the result of a call.

Context and Expand

Context of a CallRequest sent to the App includes the IDs of relevant Mattermost entities, such as the Location the call originated from, acting user ID, channel ID, etc. It also includes the Mattermost site URL, and the access tokens requested by the Call. This allows the function to use the Mattermost REST API.

Context may be further expanded using the Expand attribute of a call to include the detailed data on the User, Channel, Team, and other relevant entities. Expanded context may also contain 3rd party OAuth2 access token previously maintained and stored in Mattermost.

Expand specifies what entities should be included in the call's expanded context, and how much data should be included. Expanding a call requests result in ExpandedContext filled in.

Special Notes

  • TODO Use of router packages in Apps - Go (gorilla mux) - JavaScript

  • TODO Call vs Notification

  • TODO AWS Lambda packaging

Index

Constants

View Source
const (
	MinAppIDLength = 3
	MaxAppIDLength = 32
)
View Source
const (
	// Text field. "subtype":"textarea" for multi-line text input (Modal only?).
	// min_length, max_length - self explanatory. Value (default) is expected to be type string, or nil.
	FieldTypeText FieldType = "text"

	// Static select field. The options are specified in "options"
	FieldTypeStaticSelect FieldType = "static_select"

	// Dynamic select's options are fetched by making a call to the Form's Call,
	// in lookup mode. It responds with the list of options to display.
	FieldTypeDynamicSelect FieldType = "dynamic_select"

	// Boolean (checkbox) field.
	FieldTypeBool FieldType = "bool"

	// A mattermost @username.
	FieldTypeUser FieldType = "user"

	// A mattermost channel reference (~name).
	FieldTypeChannel FieldType = "channel"

	TextFieldSubtypeInput     TextFieldSubtype = "input"
	TextFieldSubtypeTextarea  TextFieldSubtype = "textarea"
	TextFieldSubtypeNumber    TextFieldSubtype = "number"
	TextFieldSubtypeEmail     TextFieldSubtype = "email"
	TextFieldSubtypeTelephone TextFieldSubtype = "tel"
	TextFieldSubtypeURL       TextFieldSubtype = "url"
	TextFieldSubtypePassword  TextFieldSubtype = "password"
)
View Source
const OutgoingAuthHeader = "Mattermost-App-Authorization"
View Source
const PathWebhook = "/webhook"

Root Call path for incoming webhooks from remote (3rd party) systems. Each webhook URL should be in the form: "{PluginURL}/apps/{AppID}/webhook/{PATH}/.../?secret=XYZ", and it will invoke a Call with "/webhook/{PATH}"."

View Source
const (
	PropAppBindings = "app_bindings"
)
View Source
const StaticFolder = "static"

Where static assets are.

View Source
const VersionFormat = "v00_00_000"

Variables

View Source
var DefaultBindings = &Call{
	Path: "/bindings",
}
View Source
var DefaultGetOAuth2ConnectURL = &Call{
	Path: "/oauth2/connect",
	Expand: &Expand{
		ActingUser:            ExpandSummary,
		ActingUserAccessToken: ExpandAll,
		OAuth2App:             ExpandAll,
	},
}
View Source
var DefaultOnInstall = &Call{
	Path: "/install",
	Expand: &Expand{
		App: ExpandAll,
	},
}
View Source
var DefaultOnOAuth2Complete = &Call{
	Path: "/oauth2/complete",
	Expand: &Expand{
		ActingUser:            ExpandSummary,
		ActingUserAccessToken: ExpandAll,
		OAuth2App:             ExpandAll,
		OAuth2User:            ExpandAll,
	},
}

Functions

This section is empty.

Types

type AWSLambda added in v0.7.0

type AWSLambda struct {
	// The lambda function with its Path the longest-matching prefix of the
	// call's Path will be invoked for a call.
	Path string `json:"path"`

	// TODO @iomodo
	Name    string `json:"name"`
	Handler string `json:"handler"`
	Runtime string `json:"runtime"`
}

AWSLambda describes a distinct AWS Lambda function defined by the app, and what path should be mapped to it. See https://developers.mattermost.com/integrate/apps/deployment/#making-your-app-runnable-as-an-aws-lambda-function for more information.

cmd/appsctl will create or update the manifest's aws_lambda functions in the AWS Lambda service.

upawslambda will use the manifest's aws_lambda functions to find the closest match for the call's path, and then to invoke the AWS Lambda function.

func (AWSLambda) IsValid added in v0.7.0

func (f AWSLambda) IsValid() error

type App

type App struct {
	// Manifest contains the manifest data that the App was installed with. It
	// may differ from what is currently in the manifest store for the app's ID.
	Manifest

	// Disabled is set to true if the app is disabled. Disabling an app does not
	// erase any of it's data.
	Disabled bool `json:"disabled,omitempty"`

	// Secret is used to issue JWT when sending requests to HTTP apps.
	Secret string `json:"secret,omitempty"`

	// WebhookSecret is used to validate an incoming webhook secret.
	WebhookSecret string `json:"webhook_secret,omitempty"`

	// App's Mattermost Bot User credentials. An Mattermost server Bot Account
	// is created (or updated) when a Mattermost App is installed on the
	// instance.
	BotUserID        string `json:"bot_user_id,omitempty"`
	BotUsername      string `json:"bot_username,omitempty"`
	BotAccessToken   string `json:"bot_access_token,omitempty"`
	BotAccessTokenID string `json:"bot_access_token_id,omitempty"`

	// Trusted means that Mattermost will issue the Apps' users their tokens as
	// needed, without asking for the user's consent.
	Trusted bool `json:"trusted,omitempty"`

	// MattermostOAuth2 contains App's Mattermost OAuth2 credentials. An
	// Mattermost server OAuth2 app is created (or updated) when a Mattermost
	// App is installed on the instance.
	MattermostOAuth2 OAuth2App `json:"mattermost_oauth2,omitempty"`

	// RemoteOAuth2 contains App's remote OAuth2 credentials. Use
	// mmclient.StoreOAuth2App to update.
	RemoteOAuth2 OAuth2App `json:"remote_oauth2,omitempty"`

	// In V1, GrantedPermissions are simply copied from RequestedPermissions
	// upon the sysadmin's consent, during installing the App.
	GrantedPermissions Permissions `json:"granted_permissions,omitempty"`

	// GrantedLocations contains the list of top locations that the application
	// is allowed to bind to.
	//
	// In V1, GrantedLocations are simply copied from RequestedLocations upon
	// the sysadmin's consent, during installing the App.
	GrantedLocations Locations `json:"granted_locations,omitempty"`
}

App describes an App installed on a Mattermost instance. App should be abbreviated as `app`.

type AppID

type AppID string

AppID is a globally unique identifier that represents a Mattermost App. An AppID is restricted to no more than 32 ASCII letters, numbers, '-', or '_'.

func (AppID) IsValid

func (id AppID) IsValid() error

type AppMetadataForClient added in v0.3.0

type AppMetadataForClient struct {
	BotUserID   string `json:"bot_user_id,omitempty"`
	BotUsername string `json:"bot_username,omitempty"`
}

type AppType

type AppType string

AppType is the type of an app: http, aws_lambda, or builtin.

const (
	// HTTP app (default). All communications are done via HTTP requests. Paths
	// for both functions and static assets are appended to RootURL "as is".
	// Mattermost authenticates to the App with an optional shared secret based
	// JWT.
	AppTypeHTTP AppType = "http"

	// AWS Lambda app. All functions are called via AWS Lambda "Invoke" API,
	// using path mapping provided in the app's manifest. Static assets are
	// served out of AWS S3, using the "Download" method. Mattermost
	// authenticates to AWS, no authentication to the App is necessary.
	AppTypeAWSLambda AppType = "aws_lambda"

	// Builtin app. All functions and resources are served by directly invoking
	// go functions. No manifest, no Mattermost to App authentication are
	// needed.
	AppTypeBuiltin AppType = "builtin"
)

func (AppType) IsValid

func (at AppType) IsValid() error

type AppVersion

type AppVersion string

AppVersion is the version of a Mattermost App. AppVersion is expected to look like "v00_00_000".

func (AppVersion) IsValid

func (v AppVersion) IsValid() error

type Binding

type Binding struct {
	// For internal use by Mattermost, Apps do not need to set.
	AppID AppID `json:"app_id,omitempty"`

	// Location allows the App to identify where in the UX the Call request
	// comes from. It is optional. For /command bindings, Location is
	// defaulted to Label.
	//
	// TODO: default to Label, Name.
	Location Location `json:"location,omitempty"`

	// Icon is the icon to display, should be either a fully-qualified URL, or a
	// path for an app's static asset.
	Icon string `json:"icon,omitempty"`

	// Label is the (usually short) primary text to display at the location.
	//  - post menu: the item text.
	//  - channel header: the dropdown text.
	//  - command: the name of the command.
	//  - in-post: the title.
	Label string `json:"label,omitempty"`

	// Hint is the secondary text to display
	//  - post menu: not used
	//  - channel header: tooltip
	//  - command: the "Hint" line
	Hint string `json:"hint,omitempty"`

	// Description is the (optional) extended help text, used in modals and
	// autocomplete.
	//  - in-post: is the text of the embed
	Description string `json:"description,omitempty"`

	// RoleID is a role required to see the item (hidden for other users).
	RoleID string `json:"role_id,omitempty"`

	// DependsOnTeam, etc. specifies the scope of the binding and how it can be
	// shared across various user sessions.
	DependsOnTeam    bool `json:"depends_on_team,omitempty"`
	DependsOnChannel bool `json:"depends_on_channel,omitempty"`
	DependsOnUser    bool `json:"depends_on_user,omitempty"`
	DependsOnPost    bool `json:"depends_on_post,omitempty"`

	// A Binding is either to a Call, or is a "container" for other locations -
	// i.e. menu sub-items or subcommands. An app-defined Modal can be displayed
	// by setting AsModal.
	Call     *Call      `json:"call,omitempty"`
	Bindings []*Binding `json:"bindings,omitempty"`

	// Form allows to embed a form into a binding, and avoid the need to
	// Call(type=Form). At the moment, the sole use case is in-post forms, but
	// this may prove useful in other contexts.
	// TODO: Can embedded forms be mutable, and what does it mean?
	Form *Form `json:"form,omitempty"`
}

Binding is the principal way for an App to attach its functionality to the Mattermost UI. An App can bind to top-level UI elements by implementing the (mandatory) "bindings" call. It can also add bindings to messages (posts) in Mattermost, by setting "app_bindings" property of the posts.

Mattermost UI Bindings

An App returns its bindings in response to the "bindings" call, that it must implement, and can customize in its Manifest. For each context in which it is invoked, the bindings call returns a tree of app's bindings, organized by the top-level location.

Top level bindings need to define:

location - the top-level location to bind to, e.g. "post_menu".
bindings - an array of bindings

/post_menu bindings need to define:

location - Name of this location. The whole path of locations will be added in the context.
icon - optional URL or path to the icon
label - Text to show in the item
call - Call to perform.

/channel_header bindings need to define:

location - Name of this location. The whole path of locations will be added in the context.
icon - optional URL or path to the icon
label - text to show in the item on mobile and webapp collapsed view.
hint - text to show in the webapp's tooltip.
call - Call to perform.

/command bindings can define "inner" subcommands that are collections of more bindings/subcommands, and "outer" subcommands that implement forms and can be executed. It is not possible to have command bindings that have subcommands and flags. It is possible to have positional parameters in an outer subcommand, accomplishing similar user experience.

Inner command bindings need to define:

label - the label for the command itself.
location - the location of the command, defaults to label.
hint - Hint line in autocomplete.
description - description line in autocomplete.
bindings - subcommands

Outer command bindings need to define:

label - the label for the command itself.
location - the location of the command, defaults to label.
hint - Hint line in autocomplete.
description - description line in autocomplete.
call or form - either embed a form, or provide a call to fetch it.

Bindings are currently refreshed when a user visits a channel, in the context of the current channel, from all the registered Apps. A server-side cache implementation is in the works, https://mattermost.atlassian.net/browse/MM-30472. This allows each App to dynamically add things to the UI on a per-channel basis.

Example bindings (hello world app) create a button in the channel header, and a "/helloworld send" command:

{
    "type": "ok",
    "data": [
        {
            "location": "/channel_header",
            "bindings": [
                {
                    "location": "send-button",
                    "icon": "icon.png",
                    "label":"send hello message",
                    "call": {
                        "path": "/send-modal"
                    }
                }
            ]
        },
        {
            "location": "/command",
            "bindings": [
                {
                    "icon": "icon.png",
                    "description": "Hello World app",
                    "hint":        "[send]",
                    "bindings": [
                        {
                            "location": "send",
                            "label": "send",
                            "call": {
                                "path": "/send"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

In-post Bindings

An App can also create messages (posts) in Mattermost with in-post bindings. To do that, it invokes `CreatePost` REST API, and sets the "app_bindings" prop, as in the following example:

In post bindings are embedded into posts, and are not registered like the rest of the bindings. In order to make in post bindings appear, you must create a post with an apps_bindings property. You can add several bindings to a post, and each one will appear as a single attachment to the post. Top level bindings will define the attachment contents, with the Label becoming the title, and the Description becoming the body of the attachment. Sub-bindings will become the actions of the post. An action with no sub-bindings will be rendered as a button. An action with sub-bindings will be rendered as a select. You can identify the action triggered by the location.

{
   channel_id: "channelID",
   message: "Some message to appear before the attachment",
   props: {
       app_bindings: [{
           app_id: "my app id",
           location: "location",
           label: "title of the attachment",
           description: "body of the attachment",
           bindings: [
               {
                   location: "my_select",
                   label: "Placeholder text",
                   bindings: [
                       {
                           location: "option1",
                           label: "Option 1",
                       }, {
                           location: "option2",
                           label: "Option 2",
                       },
                   ],
                   call: {
                       path: "my/path",
                   },
               }, {
                   location: "my_button",
                   label: "Button label",
                   call: {
                       path: "my/path",
                   },
               },
           ],
       }],
   },
}

type Call

type Call struct {
	// The path of the Call. For HTTP apps, the path is appended to the app's
	// RootURL. For AWS Lambda apps, it is mapped to the appropriate Lambda name
	// to invoke, and then passed in the call request.
	Path string `json:"path,omitempty"`

	// Expand specifies what extended data should be provided to the function in
	// each request's Context. It may be various auth tokens, configuration
	// data, or details of Mattermost entities such as the acting user, current
	// team and channel, etc.
	Expand *Expand `json:"expand,omitempty"`

	// Custom data that will be passed to the function in JSON, "as is".
	State interface{} `json:"state,omitempty"`
}

Call defines a way to invoke an App's function. Calls are used to fetch App's bindings, to process notifications, and to respond to user input from forms, bindings and command line.

func NewCall added in v0.2.0

func NewCall(url string) *Call

func (*Call) WithOverrides added in v0.2.0

func (c *Call) WithOverrides(override *Call) *Call

type CallRequest added in v0.2.0

type CallRequest struct {
	// A copy of the Call struct that originated the request. Path and State are
	// of significance.
	Call

	// Values are all values entered by the user.
	Values map[string]interface{} `json:"values,omitempty"`

	// Context of execution, see the Context type for more information.
	// <>/<> TODO: remove pointer
	Context *Context `json:"context,omitempty"`

	// In case the request came from the command line, the raw text of the
	// command, as submitted by the user.
	RawCommand string `json:"raw_command,omitempty"`

	// SelectedField and Query are used in calls of type lookup, and calls type
	// form used to refresh the form upon user entry, to communicate what field
	// is selected, and what query string is already entered by the user for it.
	SelectedField string `json:"selected_field,omitempty"`
	Query         string `json:"query,omitempty"`
}

CallRequest envelops all requests sent to Apps.

func CallRequestFromJSON added in v0.2.0

func CallRequestFromJSON(data []byte) (*CallRequest, error)

func CallRequestFromJSONReader added in v0.2.0

func CallRequestFromJSONReader(in io.Reader) (*CallRequest, error)

func (*CallRequest) GetValue added in v0.2.0

func (c *CallRequest) GetValue(name, defaultValue string) string

type CallResponse

type CallResponse struct {
	Type CallResponseType `json:"type"`

	// Used in CallResponseTypeOK to return the displayble, and JSON results
	Markdown md.MD       `json:"markdown,omitempty"`
	Data     interface{} `json:"data,omitempty"`

	// Used in CallResponseTypeError
	ErrorText string `json:"error,omitempty"`

	// Used in CallResponseTypeNavigate
	NavigateToURL      string `json:"navigate_to_url,omitempty"`
	UseExternalBrowser bool   `json:"use_external_browser,omitempty"`

	// Used in CallResponseTypeCall
	Call *Call `json:"call,omitempty"`

	// Used in CallResponseTypeForm
	Form *Form `json:"form,omitempty"`
}

CallResponse is general envelope for all Call responses.

Submit requests expect ok, error, form, call, or navigate response types. Returning a "form" type in response to a submission from the user-agent triggers displaying a Modal. Returning a "call" type in response to a submission causes the call to be executed from the user-agent (NOT IMPLEMENTED YET)

Form requests expect form or error.

Lookup requests expect ok or error.

In case of an error, the returned response type is "error", ErrorText contains the overall error text. Data contains optional, field-level errors.

func NewErrorCallResponse

func NewErrorCallResponse(err error) *CallResponse

func (*CallResponse) Error

func (cr *CallResponse) Error() string

Error() makes CallResponse a valid error, for convenience

type CallResponseType

type CallResponseType string
const (
	// CallResponseTypeOK indicates that the call succeeded, returns optional
	// Markdown (message) and Data.
	CallResponseTypeOK CallResponseType = "ok"

	// CallResponseTypeOK indicates an error, returns ErrorText, and optional
	// field-level errors in Data.
	CallResponseTypeError CallResponseType = "error"

	// CallResponseTypeForm returns Form, the definition of the form to display.
	// If returned responding to a submit, causes the form to be displayed as a
	// modal.
	CallResponseTypeForm CallResponseType = "form"

	// CallResponseTypeCall indicates that another Call that should be executed
	// (all the way from the user-agent). Call is returned. NOT YET IMPLEMENTED.
	CallResponseTypeCall CallResponseType = "call"

	// CallResponseTypeNavigate indicates that the user should be forcefully
	// navigated to a URL, which may be a channel in Mattermost. NavigateToURL
	// and UseExternalBrowser are expected to be returned.
	CallResponseTypeNavigate CallResponseType = "navigate"
)

type CallType

type CallType string

CallType determines what action is expected of a function.

const (
	// CallTypeSubmit (default) indicates the intent to take action.
	CallTypeSubmit CallType = "submit"

	// CallTypeForm retrieves the form definition for the current set of values,
	// and the context.
	CallTypeForm CallType = "form"

	// CallTypeCancel is used for for the (rare?) case of when the form with
	// SubmitOnCancel set is dismissed by the user.
	CallTypeCancel CallType = "cancel"

	// CallTypeLookup is used to fetch items for dynamic select elements
	CallTypeLookup CallType = "lookup"
)

type Context

type Context struct {
	// Subject is a subject of notification, if the call originated from a
	// subscription.
	Subject Subject `json:"subject,omitempty"`

	// BotUserID of the App.
	BotUserID string `json:"bot_user_id"`

	// ActingUserID is primarily (or exclusively?) for calls originating from
	// user submissions.
	ActingUserID string `json:"acting_user_id,omitempty"`

	// UserID indicates the subject of the command. Once Mentions is
	// implemented, it may be replaced by Mentions.
	UserID string `json:"user_id,omitempty"`

	// Top-level Mattermost site URL to use for REST API calls.
	MattermostSiteURL string `json:"mattermost_site_url"`

	// App's path on the Mattermost instance (appendable to MattermostSiteURL).
	AppPath string `json:"app_path"`

	// Data accepted from the user agent
	UserAgentContext

	// More data as requested by call.Expand
	ExpandedContext
}

Context is included in CallRequest and provides App with information about Mattermost environment (configuration, authentication), and the context of the user agent (current channel, etc.)

To help reduce the need to go back to Mattermost REST API, ExpandedContext can be included by adding a corresponding Expand attribute to the originating Call.

type Expand

type Expand struct {
	// App: all. Details about the installed record of the App. Of relevance to
	// the app may be the version, and the Bot account details.
	App ExpandLevel `json:"app,omitempty"`

	// ActingUser: all for the entire model.User, summary for BotDescription,
	// DeleteAt, Email, FirstName, Id, IsBot, LastName, Locale, Nickname, Roles,
	// Timezone, Username.
	ActingUser ExpandLevel `json:"acting_user,omitempty"`

	// ActingUserAccessToken: all. Include user-level access token in the
	// request. Requires act_as_user permission to have been granted to the app.
	// This should be user's Mattermost OAuth2 token, but until it's implemented
	// the MM session token is used.
	// https://mattermost.atlassian.net/browse/MM-31117
	ActingUserAccessToken ExpandLevel `json:"acting_user_access_token,omitempty"`

	// AdminAccessToken: all. Include admin-level access token in the request.
	// Requires act_as_admin permission to have been granted to the app. This
	// should be a special Mattermost OAuth2 token, but until it's implemented
	// the MM session token is used.
	// https://mattermost.atlassian.net/browse/MM-28542
	AdminAccessToken ExpandLevel `json:"admin_access_token,omitempty"`

	// Channel: all for model.Channel, summary for Id, DeleteAt, TeamId, Type,
	// DisplayName, Name
	Channel ExpandLevel `json:"channel,omitempty"`

	// Not currently implemented
	Mentioned ExpandLevel `json:"mentioned,omitempty"`

	// Post, RootPost: all for model.Post, summary for Id, Type, UserId,
	// ChannelId, RootId, Message.
	Post     ExpandLevel `json:"post,omitempty"`
	RootPost ExpandLevel `json:"root_post,omitempty"`

	// Team: all for model.team, summary for Id, DisplayName, Name, Description,
	// Email, Type.
	Team ExpandLevel `json:"team,omitempty"`

	// User: all for model.User, summary for BotDescription, DeleteAt, Email,
	// FirstName, Id, IsBot, LastName, Locale, Nickname, Roles, Timezone,
	// Username.
	User ExpandLevel `json:"user,omitempty"`

	// OAuth2App expands the remote (3rd party) OAuth2 app configuration data.
	OAuth2App ExpandLevel `json:"oauth2_app,omitempty"`

	// OAuth2User expands the remote (3rd party) OAuth2 user (custom object,
	// previously stored with mmclient.StoreOAuthUser).
	OAuth2User ExpandLevel `json:"oauth2_user,omitempty"`
}

Expand is a clause in the Call struct that controls what additional information is to be provided in each request made.

By default only the IDs of certain entities are provided in the request's Context. Expand allows to selectively add data to ExpandedContext, including privileged information such as access tokens, and detailed data on Mattermost entities, such as users and channels.

Based on the app's GrantedPermissions, Bot, User, or Admin-level tokens may be provided in the request. If the app connects to a 3rd party, it may store authentication data in the Mattermost token store and get the token data expanded in the request.

When expanding Mattermost data entities, the apps proxy must not exceed the highest available access level in the request's Context.

type ExpandLevel

type ExpandLevel string
const (
	ExpandDefault ExpandLevel = ""
	ExpandNone    ExpandLevel = "none"
	ExpandAll     ExpandLevel = "all"
	ExpandSummary ExpandLevel = "summary"
)

type ExpandedContext

type ExpandedContext struct {
	//  BotAccessToken is always provided in expanded context
	BotAccessToken string `json:"bot_access_token,omitempty"`

	ActingUser            *model.User    `json:"acting_user,omitempty"`
	ActingUserAccessToken string         `json:"acting_user_access_token,omitempty"`
	AdminAccessToken      string         `json:"admin_access_token,omitempty"`
	OAuth2                OAuth2Context  `json:"oauth2,omitempty"`
	App                   *App           `json:"app,omitempty"`
	Channel               *model.Channel `json:"channel,omitempty"`
	Mentioned             []*model.User  `json:"mentioned,omitempty"`
	Post                  *model.Post    `json:"post,omitempty"`
	RootPost              *model.Post    `json:"root_post,omitempty"`
	Team                  *model.Team    `json:"team,omitempty"`

	// TODO replace User with mentions
	User *model.User `json:"user,omitempty"`
}

ExpandedContext contains authentication, and Mattermost entity data, as indicated by the Expand attribute of the originating Call.

type Field

type Field struct {
	// Name is the name of the JSON field to use.
	Name string `json:"name"`

	Type       FieldType `json:"type"`
	IsRequired bool      `json:"is_required,omitempty"`
	ReadOnly   bool      `json:"readonly,omitempty"`

	// Present (default) value of the field
	Value interface{} `json:"value,omitempty"`

	// Field description. Used in modal and autocomplete.
	Description string `json:"description,omitempty"`

	// Label is used in Autocomplete as the --flag name. It is ignored for
	// positional fields (with AutocompletePosition != 0).
	//
	// TODO: Label should default to Name.
	Label string `json:"label,omitempty"`

	// AutocompleteHint is used in Autocomplete as the hint line.
	AutocompleteHint string `json:"hint,omitempty"`

	// AutocompletePosition means that this is a positional argument, does not
	// have a --flag. If >0, indicates what position this field is in.
	AutocompletePosition int `json:"position,omitempty"`

	// TODO: ModalLabel should default to Label, Name
	ModalLabel string `json:"modal_label"`

	// SelectIsMulti designates whether a select field is a multiselect
	SelectIsMulti bool `json:"multiselect,omitempty"`

	// SelectRefresh means that a change in the value of this select triggers
	// reloading the form. Values of the fields with inputs that are not
	// included in the refreshed form are lost. Not yet implemented for /command
	// autocomplete.
	SelectRefresh bool `json:"refresh,omitempty"`

	// SelectStaticOptions is the list of options to display in a static select
	// field.
	SelectStaticOptions []SelectOption `json:"options,omitempty"`

	// Text props
	TextSubtype   TextFieldSubtype `json:"subtype,omitempty"`
	TextMinLength int              `json:"min_length,omitempty"`
	TextMaxLength int              `json:"max_length,omitempty"`
}

type FieldType

type FieldType string

type Form

type Form struct {
	// Title, Header, and Footer are used for Modals only.
	Title  string `json:"title,omitempty"`
	Header string `json:"header,omitempty"`
	Footer string `json:"footer,omitempty"`

	// A fully-qualified URL, or a path to the form icon.
	// TODO do we default to the App icon?
	Icon string `json:"icon,omitempty"`

	// Call is the same definition used to submit, refresh the form, and to
	// lookup dynamic select options.
	Call *Call `json:"call,omitempty"`

	// SubmitButtons refers to a field name that must be a FieldTypeStaticSelect
	// or FieldTypeDynamicSelect.
	//
	// In Modal view, the field will be rendered as a list of buttons at the
	// bottom. Clicking one of them submits the Call, providing the button
	// reference as the corresponding Field's value. Leaving this property
	// blank, displays the default "OK".
	//
	// In Autocomplete, it is ignored.
	SubmitButtons string `json:"submit_buttons,omitempty"`

	// Fields is the list of fields in the form.
	Fields []*Field `json:"fields,omitempty"`
}

Form defines what inputs a Call accepts, and how they can be gathered from the user, in Modal and Autocomplete modes.

For a Modal, the form defines the modal entirely, and displays it when returned in response to a submit Call. Modals are dynamic in the sense that they may be refreshed entirely when values of certain fields change, and may contain dynamic select fields.

For Autocomplete, a form can be bound to a sub-command. The behavior of autocomplete once the subcommand is selected is designed to mirror the functionality of the Modal. Some gaps and differences still remain.

Requests for forms are calls, can use Expand, making it easy to generate forms specific to the user, channel, etc.

When a dynamic select field is selected in a Modal, or in Autocomplete, a Lookup call request is made to the Form's Call. The app should respond with "data":[]SelectOption, and "type":"ok".

When a select field with "refresh" set changes value, it forces reloading of the form. A call request type form is made to fetch it, with the partial values provided. Expected response is a "type":"form" response.

type JWTClaims added in v0.2.0

type JWTClaims struct {
	jwt.StandardClaims
	ActingUserID string `json:"acting_user_id,omitempty"`
}

type ListedApp added in v0.2.0

type ListedApp struct {
	Manifest  *Manifest                `json:"manifest"`
	Installed bool                     `json:"installed"`
	Enabled   bool                     `json:"enabled"`
	IconURL   string                   `json:"icon_url,omitempty"`
	Labels    []model.MarketplaceLabel `json:"labels,omitempty"`
}

ListedApp is a Mattermost App listed in the Marketplace containing metadata.

type Location

type Location string
const (
	LocationPostMenu      Location = "/post_menu"
	LocationChannelHeader Location = "/channel_header"
	LocationCommand       Location = "/command"
	LocationInPost        Location = "/in_post"
)

func (Location) In

func (l Location) In(other Location) bool

func (Location) IsTop

func (l Location) IsTop() bool

func (Location) Make

func (l Location) Make(sub Location) Location

func (Location) Markdown

func (l Location) Markdown() md.MD

type Locations

type Locations []Location

type Manifest

type Manifest struct {
	// The AppID is a globally unique identifier that represents your app. IDs must be at least
	// 3 characters, at most 32 characters and must contain only alphanumeric characters, dashes, underscores and periods.
	AppID   AppID      `json:"app_id"`
	AppType AppType    `json:"app_type"`
	Version AppVersion `json:"version"`

	// HomepageURL is required.
	HomepageURL string `json:"homepage_url"`

	DisplayName string `json:"display_name,omitempty"`
	Description string `json:"description,omitempty"`

	// Icon is a relative path in the static assets folder of an png image, which is used to represent the App.
	Icon string `json:"icon,omitempty"`

	// Bindings must be implemented by the Apps to add any UX elements to the
	// Mattermost UI. The default values for its fields are,
	//  "path":"/bindings",
	Bindings *Call `json:"bindings,omitempty"`

	// OnInstall gets invoked when a sysadmin installs the App with a `/apps
	// install` command. It may return another call to the app, or a form to
	// display. The default values for its fields are,
	//  "path":"/install",
	//  "expand":{
	//    "app":"all",
	//	  "admin_access_token":"all"
	//   }
	OnInstall *Call `json:"on_install,omitempty"`

	// OnVersionChanged gets invoked when the Mattermost-recommended version of
	// the app no longer matches the previously installed one, and the app needs
	// to be upgraded/downgraded. It is not called unless explicitly provided in
	// the manifest.
	OnVersionChanged *Call `json:"on_version_changed,omitempty"`

	// OnUninstall gets invoked when a sysadmin uses the `/apps uninstall`
	// command, before the app is actually removed. It is not called unless
	// explicitly provided in the manifest.
	OnUninstall *Call `json:"on_uninstall,omitempty"`

	// OnEnable, OnDisable are not yet supported
	OnDisable *Call `json:"on_disable,omitempty"`
	OnEnable  *Call `json:"on_enable,omitempty"`

	// GetOAuth2ConnectURL is called when the App's "connect to 3rd party" link
	// is clicked, to be redirected to the OAuth flow. It must return Data set
	// to the remote OAuth2 redirect URL. A "state" string is created by the
	// proxy, and is passed to the app as a value. The state is  a 1-time secret
	// that is included in the connect URL, and will be used to validate OAuth2
	// complete callback.
	GetOAuth2ConnectURL *Call `json:"get_oauth2_connect_url,omitempty"`

	// OnOAuth2Complete gets called upon successful completion of the remote
	// (3rd party) OAuth2 flow, and after the "state" has already been
	// validated. It gets passed the URL query as Values. The App should obtain
	// the OAuth2 user token, and store it persistently for future use using
	// mmclient.StoreOAuth2User.
	OnOAuth2Complete *Call `json:"on_oauth2_complete,omitempty"`

	RequestedPermissions Permissions `json:"requested_permissions,omitempty"`

	// RequestedLocations is the list of top-level locations that the
	// application intends to bind to, e.g. `{"/post_menu", "/channel_header",
	// "/command/apptrigger"}“.
	RequestedLocations Locations `json:"requested_locations,omitempty"`

	// For HTTP Apps all paths are relative to the RootURL.
	HTTPRootURL string `json:"root_url,omitempty"`

	// AWSLambda must be included by the developer in the published manifest for
	// AWS apps. These declarations are used to:
	// - create AWS Lambda functions that will service requests in Mattermost
	// Cloud;
	// - define path->function mappings, aka "routes". The function with the
	// path matching as the longest prefix is used to handle a Call request.
	AWSLambda []AWSLambda `json:"aws_lambda,omitempty"`
}

func ManifestFromJSON added in v0.2.0

func ManifestFromJSON(data []byte) (*Manifest, error)

func (Manifest) IsValid added in v0.2.0

func (m Manifest) IsValid() error

type OAuth2App added in v0.3.0

type OAuth2App struct {
	ClientID     string `json:"client_id,omitempty"`
	ClientSecret string `json:"client_secret,omitempty"`
}

OAuth2App contains the setored settings for an "OAuth2 app" used by the App. It is used to describe the OAuth2 connections both to Mattermost, and optionally to a 3rd party remote system.

type OAuth2Context added in v0.3.0

type OAuth2Context struct {
	// Expanded with "oauth2_app". Config must be previously stored with
	// mmclient.StoreOAuth2App
	OAuth2App
	ConnectURL  string `json:"connect_url,omitempty"`
	CompleteURL string `json:"complete_url,omitempty"`

	User interface{} `json:"user,omitempty"`
}

type Permission added in v0.2.0

type Permission string
const (
	// PermissionUserJoinedChannelNotification means that the app is allowed to
	// receive user_joined_channel notifications
	PermissionUserJoinedChannelNotification Permission = "user_joined_channel_notification"

	// PermissionActAsBot means that a Bot User will be created when the App is
	// installed. Call requests will then include the Bot access token, the app
	// can use them with the Mattermost REST API. The bot will not automatically
	// receive permissions to any resources, need to be added explicitly.
	PermissionActAsBot Permission = "act_as_bot"

	// PermissionActAsUser means that the app is allowed to connect users'
	// OAuth2 accounts, and then use user API tokens.
	PermissionActAsUser Permission = "act_as_user"

	// PermissionActAsAdmin means that the app is allowed to request admin-level
	// access tokens in its calls.
	PermissionActAsAdmin Permission = "act_as_admin"

	// PermissionRemoteOAuth2 means that the app is allowed to use remote (3rd
	// party) OAuth2 support, and will store secrets to 3rd party system(s).
	PermissionRemoteOAuth2 Permission = "remote_oauth2"

	// PermissionRemoteWebhooks means that the app is allowed to receive webhooks from a remote (3rd
	// party) system, and process them as Bot.
	PermissionRemoteWebhooks Permission = "remote_webhooks"
)

func (Permission) String added in v0.3.0

func (p Permission) String() md.MD

type Permissions

type Permissions []Permission

func (Permissions) Contains

func (p Permissions) Contains(permission Permission) bool

func (Permissions) IsValid added in v0.3.0

func (p Permissions) IsValid() error

type ProxyCallResponse added in v0.3.0

type ProxyCallResponse struct {
	*CallResponse

	// Used to provide info about the App to client, e.g. the bot user id
	AppMetadata *AppMetadataForClient `json:"app_metadata"`
}

ProxyCallResponse contains everything the CallResponse struct contains, plus some additional data for the client, such as information about the App's bot account.

Apps will use the CallResponse struct to respond to a CallRequest, and the proxy will decorate the response using the ProxyCallResponse to provide additional information.

func NewProxyCallResponse added in v0.3.0

func NewProxyCallResponse(response *CallResponse, metadata *AppMetadataForClient) *ProxyCallResponse

type SelectOption

type SelectOption struct {
	// Label is the display name/label for the option's value.
	Label string `json:"label"`

	Value    string `json:"value"`
	IconData string `json:"icon_data"`
}

type Subject

type Subject string
const (
	// SubjectUserCreated subscribes to UserHasBeenCreated plugin events. By
	// default, fully expanded User object is included in the notifications.
	// There is no other data to expand.
	SubjectUserCreated Subject = "user_created"

	// SubjectUserJoinedChannel and SubjectUserLeftChannel subscribes to
	// respective plugin events, for the specified channel. By default
	// notifications include ActingUserID, UserID, and ChannelID, but only
	// ActingUser is fully expanded. Expand can be used to expand other
	// entities.
	SubjectUserJoinedChannel Subject = "user_joined_channel"
	SubjectUserLeftChannel   Subject = "user_left_channel"

	// SubjectUserJoinedTeam and SubjectUserLeftTeam subscribes to respective
	// plugin events, for the specified team. By default notifications include
	// ActingUserID, UserID, and TeamID, but only ActingUser is fully expanded.
	// Expand can be used to expand other entities.
	SubjectUserJoinedTeam Subject = "user_joined_team"
	SubjectUserLeftTeam   Subject = "user_left_team"

	// SubjectChannelCreated subscribes to ChannelHasBeenCreated plugin events,
	// for the specified team. By default notifications include UserID (creator),
	// ChannelID, and TeamID, but only Channel is fully expanded. Expand can be
	// used to expand other entities.
	SubjectChannelCreated Subject = "channel_created"

	// SubjectPostCreated subscribes to MessageHasBeenPosted plugin events, for
	// the specified channel. By default notifications include UserID (author), PostID,
	// RootPostID, ChannelID, but only Post is fully expanded. Expand can be
	// used to expand other entities.
	SubjectPostCreated Subject = "post_created"
)

type Subscription

type Subscription struct {
	// AppID is used internally by Mattermost. It does not need to be set by app
	// developers.
	AppID AppID `json:"app_id,omitempty"`

	// Subscription subject. See type Subject godoc (linked) for details.
	Subject Subject `json:"subject"`

	// ChannelID and TeamID are the subscription scope, as applicable to the subject.
	ChannelID string `json:"channel_id,omitempty"`
	TeamID    string `json:"team_id,omitempty"`

	// Call is the (one-way) call to make upon the event.
	Call *Call
}

Subscription is submitted by an app to the Subscribe API. It determines what events the app would like to be notified on, and how these notifications should be invoked.

func (*Subscription) EqualScope

func (sub *Subscription) EqualScope(other *Subscription) bool

func (*Subscription) ToJSON

func (sub *Subscription) ToJSON() string

type SubscriptionResponse

type SubscriptionResponse struct {
	Error  string            `json:"error,omitempty"`
	Errors map[string]string `json:"errors,omitempty"`
}

func SubscriptionResponseFromJSON

func SubscriptionResponseFromJSON(data io.Reader) *SubscriptionResponse

func (*SubscriptionResponse) ToJSON

func (r *SubscriptionResponse) ToJSON() []byte

type TextFieldSubtype added in v0.5.0

type TextFieldSubtype string

type UserAgentContext added in v0.5.0

type UserAgentContext struct {
	// The optional IDs of Mattermost entities associated with the call: Team,
	// Channel, Post, RootPost.
	TeamID     string `json:"team_id"`
	ChannelID  string `json:"channel_id,omitempty"`
	PostID     string `json:"post_id,omitempty"`
	RootPostID string `json:"root_post_id,omitempty"`

	// AppID is used for handling CallRequest internally.
	AppID AppID `json:"app_id"`

	// Fully qualified original Location of the user action (if applicable),
	// e.g. "/command/helloworld/send" or "/channel_header/send".
	Location Location `json:"location,omitempty"`

	// UserAgent used to perform the call. It can be either "webapp" or "mobile".
	// Non user interactions like notifications will have this field empty.
	UserAgent string `json:"user_agent,omitempty"`
}

UserAgentContext is a subset of fields from Context that are accepted from the user agent The values are vetted, and all fields present in the provided Context that are not in UserAgentContext are discarded when the Call comes from an acting user.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL