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
- Variables
- type AWSLambda
- type AWSLambdaFunction
- type App
- type AppID
- type AppV0_7
- type AppVersion
- type Binding
- type Call
- func (c Call) Loggable() []interface{}
- func (c *Call) PartialCopy() *Call
- func (c Call) String() string
- func (c *Call) UnmarshalJSON(data []byte) error
- func (c *Call) WithDefault(def Call) Call
- func (c Call) WithExpand(expand Expand) *Call
- func (c Call) WithLocale() *Call
- func (c Call) WithState(state interface{}) *Call
- type CallRequest
- func (creq *CallRequest) BoolValue(name string) bool
- func (creq *CallRequest) GetValue(name, defaultValue string) string
- func (creq CallRequest) Loggable() []interface{}
- func (creq CallRequest) String() string
- func (creq CallRequest) ToHTTPCallRequestJSON() ([]byte, error)
- func (creq *CallRequest) UnmarshalJSON(data []byte) error
- type CallResponse
- type CallResponseType
- type Context
- type Deploy
- type DeployType
- type DeployTypes
- type Expand
- type ExpandLevel
- type ExpandedContext
- type Field
- type FieldType
- type Form
- type HTTP
- type HTTPCallRequest
- type HTTPCallResponse
- type JWTClaims
- type Kubeless
- type KubelessFunction
- type ListedApp
- type Location
- type Locations
- type Manifest
- type ManifestV0_7
- type OAuth2App
- type OAuth2Context
- type OpenFAAS
- type OpenFAASFunction
- type Permission
- type Permissions
- type Plugin
- type RemoteWebhookAuthType
- type SelectOption
- type Subject
- type Subscription
- type TextFieldSubtype
- type UserAgentContext
Constants ¶
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" // An arbitrary markdown text. Only visible on modals. FieldTypeMarkdown FieldType = "markdown" TextFieldSubtypeInput TextFieldSubtype = "input" TextFieldSubtypeTextarea TextFieldSubtype = "textarea" TextFieldSubtypeNumber TextFieldSubtype = "number" TextFieldSubtypeEmail TextFieldSubtype = "email" TextFieldSubtypeTelephone TextFieldSubtype = "tel" TextFieldSubtypeURL TextFieldSubtype = "url" TextFieldSubtypePassword TextFieldSubtype = "password" )
const ( MinAppIDLength = 3 MaxAppIDLength = 32 )
const ( // No authentication means that the message will be accepted, and passed to // tha app. The app can perform its own authentication then. This is also // the default type. NoAuth = RemoteWebhookAuthType("none") // Secret authentication expects the App secret to be passed in the incoming // request's query as ?secret=appsecret. SecretAuth = RemoteWebhookAuthType("secret") // JWT authentication: not implemented yet JWTAuth = RemoteWebhookAuthType("jwt") )
const MaxManifestSize = 1024 * 1024 // MaxManifestSize is the maximum size of a Manifest in bytes
const OutgoingAuthHeader = "Mattermost-App-Authorization"
const PluginAppPath = "/app"
const (
PropAppBindings = "app_bindings"
)
const VersionFormat = "v00_00_000"
Variables ¶
var DefaultBindings = Call{ Path: path.Bindings, }
var DefaultGetOAuth2ConnectURL = Call{ Path: "/oauth2/connect", Expand: &Expand{ ActingUser: ExpandSummary, ActingUserAccessToken: ExpandAll, OAuth2App: ExpandAll, }, }
var DefaultOnOAuth2Complete = Call{ Path: "/oauth2/complete", Expand: &Expand{ ActingUser: ExpandSummary, ActingUserAccessToken: ExpandAll, OAuth2App: ExpandAll, OAuth2User: ExpandAll, }, }
var DefaultOnRemoteWebhook = Call{ Path: path.Webhook, }
var DefaultPing = Call{
Path: "/ping",
}
var KnownDeployTypes = DeployTypes{ DeployAWSLambda, DeployBuiltin, DeployHTTP, DeployOpenFAAS, DeployPlugin, }
Functions ¶
This section is empty.
Types ¶
type AWSLambda ¶ added in v0.7.0
type AWSLambda struct {
Functions []AWSLambdaFunction `json:"functions,omitempty"`
}
AWSLambda contains metadata for an app that can be deployed to AWS Lambda and S3 services, and is accessed using the AWS APIs. The JSON name `aws_lambda` must match the type.
type AWSLambdaFunction ¶ added in v0.2.0
type AWSLambdaFunction 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"` Name string `json:"name"` Handler string `json:"handler"` Runtime string `json:"runtime"` }
AWSLambdaFunction 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 (AWSLambdaFunction) Validate ¶ added in v1.0.0
func (f AWSLambdaFunction) Validate() 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 // DeployType is the type of upstream that can be used to access the App. DeployType DeployType `json:"deploy_type,omitempty"` // 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"` // 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 *model.OAuthApp `json:"mattermost_oauth2,omitempty"` // RemoteOAuth2 contains App's remote OAuth2 credentials. Use // appclient.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`.
func DecodeCompatibleApp ¶ added in v1.0.0
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 '_'.
type AppV0_7 ¶ added in v1.0.0
type AppV0_7 struct { ManifestV0_7 Disabled bool `json:"disabled,omitempty"` Secret string `json:"secret,omitempty"` WebhookSecret string `json:"webhook_secret,omitempty"` 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 bool `json:"trusted,omitempty"` MattermostOAuth2 OAuth2App `json:"mattermost_oauth2,omitempty"` RemoteOAuth2 OAuth2App `json:"remote_oauth2,omitempty"` GrantedPermissions Permissions `json:"granted_permissions,omitempty"` GrantedLocations Locations `json:"granted_locations,omitempty"` }
type AppVersion ¶
type AppVersion string
AppVersion is the version of a Mattermost App. AppVersion is expected to look like "v00_00_000".
func (AppVersion) Validate ¶ added in v1.0.0
func (v AppVersion) Validate() 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"` // Submit is used to execute the action associated to this binding. Submit *Call `json:"submit,omitempty"` // Form is used to gather additional input from the user before submitting. // At a minimum, it contains the Submit call path or a Source call path. A // form may be embedded, or be a source reference meaning that a call to // the app will be made to obtain the form. Form *Form `json:"form,omitempty"` // Bindings specifies sub-location bindings. Bindings []Binding `json:"bindings,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.
IMPORTANT: update UnmarshalJSON if this struct changes.
func (*Call) PartialCopy ¶ added in v1.0.0
func (*Call) UnmarshalJSON ¶ added in v1.0.0
func (*Call) WithDefault ¶ added in v1.0.0
func (Call) WithExpand ¶ added in v1.0.0
func (Call) WithLocale ¶ added in v1.0.0
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. 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"` // In the case of a form refresh call, the field of the select value chosen. // In the case of a lookup call, the field that the user is using for autocomplete. SelectedField string `json:"selected_field,omitempty"` // In the case of a lookup call, the query the user has typed in for autocomplete. 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) BoolValue ¶ added in v1.0.0
func (creq *CallRequest) BoolValue(name string) bool
func (*CallRequest) GetValue ¶ added in v0.2.0
func (creq *CallRequest) GetValue(name, defaultValue string) string
func (CallRequest) Loggable ¶ added in v1.1.0
func (creq CallRequest) Loggable() []interface{}
func (CallRequest) String ¶ added in v1.1.0
func (creq CallRequest) String() string
func (CallRequest) ToHTTPCallRequestJSON ¶ added in v1.0.0
func (creq CallRequest) ToHTTPCallRequestJSON() ([]byte, error)
func (*CallRequest) UnmarshalJSON ¶ added in v1.0.0
func (creq *CallRequest) UnmarshalJSON(data []byte) error
UnmarshalJSON has to be defined since Call is embedded anonymously, and CallRequest inherits its UnmarshalJSON unless it defines its own.
type CallResponse ¶
type CallResponse struct { Type CallResponseType `json:"type"` // Text is used for OK and Error response, and will show the text in the // proper output. Text string `json:"text,omitempty"` // Used in CallResponseTypeOK to return the displayble, and JSON results Data interface{} `json:"data,omitempty"` // Used in CallResponseTypeNavigate 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 NewDataResponse ¶ added in v1.0.0
func NewDataResponse(data interface{}) CallResponse
func NewErrorResponse ¶ added in v1.0.0
func NewErrorResponse(err error) CallResponse
func NewFormResponse ¶ added in v1.0.0
func NewFormResponse(form Form) CallResponse
func NewLookupResponse ¶ added in v1.0.0
func NewLookupResponse(opts []SelectOption) CallResponse
func NewTextResponse ¶ added in v1.0.0
func NewTextResponse(format string, args ...interface{}) CallResponse
func (CallResponse) Error ¶
func (cresp CallResponse) Error() string
Error makes CallResponse a valid error, for convenience
func (CallResponse) Loggable ¶ added in v1.1.0
func (cresp CallResponse) Loggable() []interface{}
func (CallResponse) String ¶ added in v1.1.0
func (cresp CallResponse) String() string
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" // navigated to a URL, which may be a channel in Mattermost. NavigateToURL // and UseExternalBrowser are expected to be returned. CallResponseTypeNavigate CallResponseType = "navigate" )
type Context ¶
type Context struct { // ActingUserID is primarily (or exclusively?) for calls originating from // user submissions. // // ActingUserID is not send down to Apps. 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 is not send down to Apps. UserID string `json:"user_id,omitempty"` // Subject is a subject of notification, if the call originated from a // subscription. Subject Subject `json:"subject,omitempty"` // 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.
TODO: Refactor to an incoming Context and an outgoing Context.
type Deploy ¶ added in v1.0.0
type Deploy struct { // AWSLambda contains metadata for an app that can be deployed to AWS Lambda // and S3 services, and is accessed using the AWS APIs. The JSON name // `aws_lambda` must match the type. AWSLambda *AWSLambda `json:"aws_lambda,omitempty"` // HTTP contains metadata for an app that is already, deployed externally // and us accessed over HTTP. The JSON name `http` must match the type. HTTP *HTTP `json:"http,omitempty"` OpenFAAS *OpenFAAS `json:"open_faas,omitempty"` // Plugin contains metadata for an app that is implemented and is deployed // and accessed as a local Plugin. The JSON name `plugin` must match the // type. Plugin *Plugin `json:"plugin,omitempty"` }
Deploy contains App's deployment data, only the fields supported by the App should be populated.
func (Deploy) Contains ¶ added in v1.0.0
func (d Deploy) Contains(dtype DeployType) bool
func (*Deploy) CopyType ¶ added in v1.0.0
func (d *Deploy) CopyType(src Deploy, typ DeployType)
func (Deploy) DeployTypes ¶ added in v1.0.0
func (d Deploy) DeployTypes() (out []DeployType)
func (Deploy) MustDeployAs ¶ added in v1.0.0
func (d Deploy) MustDeployAs() DeployType
type DeployType ¶ added in v1.0.0
type DeployType string
DeployType determines how Apps are deployed and accessed.
const ( // AWS Lambda-deployable 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. DeployAWSLambda DeployType = "aws_lambda" // Builtin app. All functions and resources are served by directly invoking // go functions. No manifest, no Mattermost to App authentication are // needed. DeployBuiltin DeployType = "builtin" // HTTP-deployable app. 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. DeployHTTP DeployType = "http" // OpenFaaS-deployable app. DeployOpenFAAS DeployType = "open_faas" // An App running as a plugin. All communications are done via inter-plugin HTTP requests. // Authentication is done via the plugin.Context.SourcePluginId field. DeployPlugin DeployType = "plugin" )
func (DeployType) String ¶ added in v1.0.0
func (t DeployType) String() string
func (DeployType) Validate ¶ added in v1.0.0
func (t DeployType) Validate() error
type DeployTypes ¶ added in v1.0.0
type DeployTypes []DeployType
func (DeployTypes) Contains ¶ added in v1.0.0
func (t DeployTypes) Contains(typ DeployType) bool
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. ActingUserAccessToken ExpandLevel `json:"acting_user_access_token,omitempty"` // Locale expands the locale to use for this call. There is no difference // between all or summary. Locale ExpandLevel `json:"locale,omitempty"` // Channel: all for model.Channel, summary for Id, DeleteAt, TeamId, Type, // DisplayName, Name Channel ExpandLevel `json:"channel,omitempty"` // ChannelMember: expand model.ChannelMember if ChannelID and // ActingUserID are set. ChannelMember ExpandLevel `json:"channel_member,omitempty"` // Team: all for model.Team, summary for Id, DisplayName, Name, Description, // Email, Type. Team ExpandLevel `json:"team,omitempty"` // TeamMember: expand model.TeamMember if TeamID and ActingUserID are set. TeamMember ExpandLevel `json:"team_member,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"` // User: all for model.User, summary for BotDescription, DeleteAt, Email, // FirstName, Id, IsBot, LastName, Locale, Nickname, Roles, Timezone, // Username. Default is summary. User ExpandLevel `json:"user,omitempty"` // Not currently implemented Mentioned ExpandLevel `json:"mentioned,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 appclient.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" ExpandID ExpandLevel = "id" ExpandAll ExpandLevel = "all" ExpandSummary ExpandLevel = "summary" )
type ExpandedContext ¶
type ExpandedContext struct { // Top-level Mattermost site URL to use for REST API calls. MattermostSiteURL string `json:"mattermost_site_url"` // DeveloperMode is set if the apps plugin itself is running in Developer mode. DeveloperMode bool `json:"developer_mode,omitempty"` // App's path on the Mattermost instance (appendable to MattermostSiteURL). AppPath string `json:"app_path"` // BotUserID of the App. BotUserID string `json:"bot_user_id"` // BotAccessToken is always provided in expanded context. BotAccessToken string `json:"bot_access_token,omitempty"` App *App `json:"app,omitempty"` ActingUser *model.User `json:"acting_user,omitempty"` ActingUserAccessToken string `json:"acting_user_access_token,omitempty"` Locale string `json:"locale,omitempty"` Channel *model.Channel `json:"channel,omitempty"` ChannelMember *model.ChannelMember `json:"channel_member,omitempty"` Team *model.Team `json:"team,omitempty"` TeamMember *model.TeamMember `json:"team_member,omitempty"` Post *model.Post `json:"post,omitempty"` RootPost *model.Post `json:"root_post,omitempty"` // TODO replace User with mentions User *model.User `json:"user,omitempty"` Mentioned []*model.User `json:"mentioned,omitempty"` OAuth2 OAuth2Context `json:"oauth2,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. If =-1, // indicates that this field is the last argument. AutocompletePosition int `json:"position,omitempty"` // ModalLabel is used in the modal dialog context, has no format // limitations. It defaults to Label. ModalLabel string `json:"modal_label,omitempty"` // 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"` // SelectDynamicLookup is the call that will return the options to populate // the select. // // TODO document the Lookup format. SelectDynamicLookup *Call `json:"lookup,omitempty"` // Text props TextSubtype TextFieldSubtype `json:"subtype,omitempty"` TextMinLength int `json:"min_length,omitempty"` TextMaxLength int `json:"max_length,omitempty"` }
func (*Field) PartialCopy ¶ added in v1.0.0
PartialCopy makes a copy of a Field. It does not clone Value since it does not know the type.
type Form ¶
type Form struct { // Source is the call to make when the form's definition is required (i.e. // it has no fields, or needs to be refreshed from the app). A simple call // can be specified as a path (string). Source *Call `json:"source,omitempty"` // Title, Header, and Footer are used for Modals only. Title string `json:"title,omitempty"` Header string `json:"header,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"` // Submit is the call to make when the user clicks a submit button (or enter // for a command). A simple call can be specified as a path (string). It // will contain no expand/state. Submit *Call `json:"submit,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.
IMPORTANT: update UnmarshalJSON if this struct changes.
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.
A form can be dynamically fetched if it specifies its Source. Source may include Expand and State, allowing to create custom-fit forms for the context.
func NewBlankForm ¶ added in v1.0.0
func NewFormRef ¶ added in v1.0.0
func (*Form) IsSubmittable ¶ added in v1.0.0
func (*Form) PartialCopy ¶ added in v1.0.0
func (*Form) UnmarshalJSON ¶ added in v1.0.0
type HTTP ¶ added in v1.0.0
type HTTP struct { // All call and static paths are relative to the RootURL. RootURL string `json:"root_url,omitempty"` // UseJWT instructs the proxy to authenticate outgoing requests with a JWT. UseJWT bool `json:"use_jwt,omitempty"` }
HTTP contains metadata for an app that is already, deployed externally and us accessed over HTTP. The JSON name `http` must match the type.
type HTTPCallRequest ¶ added in v1.0.0
type HTTPCallRequest struct { Path string `json:"path"` HTTPMethod string `json:"httpMethod"` Headers map[string]string `json:"headers"` RawQuery string `json:"rawQuery,omitempty"` Body string `json:"body"` }
HTTPCallRequest is a scoped down version of https://pkg.go.dev/github.com/aws/aws-lambda-go@v1.13.3/events#APIGatewayProxyRequest
type HTTPCallResponse ¶ added in v1.0.0
type HTTPCallResponse struct { StatusCode int `json:"statusCode"` Headers map[string]string `json:"headers"` IsBase64Encoded bool `json:"isBase64Encoded"` Body string `json:"body"` }
HTTPCallResponse is a scoped down version of https://pkg.go.dev/github.com/aws/aws-lambda-go@v1.13.3/events#APIGatewayProxyResponse
func HTTPCallResponseFromJSON ¶ added in v1.0.0
func HTTPCallResponseFromJSON(data []byte) (*HTTPCallResponse, error)
type JWTClaims ¶ added in v0.2.0
type JWTClaims struct { jwt.StandardClaims ActingUserID string `json:"acting_user_id,omitempty"` }
type Kubeless ¶ added in v1.0.0
type Kubeless struct {
Functions []KubelessFunction `json:"functions,omitempty"`
}
Kubeless contains metadata for an app that can be deployed to Kubeless running on a Kubernetes cluster, and is accessed using the Kubernetes APIs and HTTP. The JSON name `kubeless` must match the type.
type KubelessFunction ¶ added in v1.0.0
type KubelessFunction struct { // Path is used to match/map incoming Call requests. Path string `json:"path"` // Handler refers to the actual language function being invoked. // TODO examples py, go Handler string `json:"handler"` // File is the file ath (relative, in the bundle) to the function (source?) // file. Checksum is the expected checksum of the file. File string `json:"file"` // DepsFile is the path to the file with runtime-specific dependency list, // e.g. go.mod. DepsFile string `json:"deps_file"` // Kubeless runtime to use. Runtime string `json:"runtime"` // Timeout for the function to complete its execution, in seconds. Timeout int `json:"timeout"` // Port is the local ipv4 port that the function listens to, default 8080. Port int32 `json:"port"` }
KubelessFunction describes a distinct Kubeless function defined by the app, and what path should be mapped to it.
cmd/appsctl will create or update the functions in a kubeless service.
upkubeless will find the closest match for the call's path, and then to invoke the kubeless function.
func (KubelessFunction) Validate ¶ added in v1.0.0
func (kf KubelessFunction) Validate() error
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 Manifest ¶
type Manifest struct { // Set to the version of the Apps plugin that stores it, e.g. "v0.8.0" SchemaVersion string `json:",omitempty"` // 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,omitempty"` // Version of the app, formatted as v00.00.000 Version AppVersion `json:"version,omitempty"` // HomepageURL is required. HomepageURL string `json:"homepage_url,omitempty"` // DisplayName and Description provide optional information about the App. 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. It is not called unless explicitly provided in the manifest. 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 // appclient.StoreOAuth2User. OnOAuth2Complete *Call `json:"on_oauth2_complete,omitempty"` // OnRemoteWebhook gets invoked when an HTTP webhook is received from a // remote system, and is optionally authenticated by Mattermost. The request // is passed to the call serialized as HTTPCallRequest (JSON). OnRemoteWebhook *Call `json:"on_remote_webhook,omitempty"` // Requested Access RequestedPermissions Permissions `json:"requested_permissions,omitempty"` // RemoteWebhookAuthType specifies how incoming webhook messages from remote // systems should be authenticated by Mattermost. RemoteWebhookAuthType RemoteWebhookAuthType `json:"remote_webhook_auth_type,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"` // Deployment information Deploy // contains filtered or unexported fields }
func DecodeCompatibleManifest ¶ added in v1.0.0
DecodeCompatibleManifest decodes any known version of manifest.json into the current format. Since App embeds Manifest anonymously, it appears impossible to implement json.Unmarshaler without introducing all kinds of complexities. Thus, custom functions to encode/decode JSON, with backwards compatibility support for App and Manifest.
type ManifestV0_7 ¶ added in v1.0.0
type ManifestV0_7 struct { AppID AppID `json:"app_id"` AppType string `json:"app_type"` Version AppVersion `json:"version"` HomepageURL string `json:"homepage_url"` DisplayName string `json:"display_name,omitempty"` Description string `json:"description,omitempty"` Icon string `json:"icon,omitempty"` Bindings *Call `json:"bindings,omitempty"` OnInstall *Call `json:"on_install,omitempty"` OnVersionChanged *Call `json:"on_version_changed,omitempty"` OnUninstall *Call `json:"on_uninstall,omitempty"` OnDisable *Call `json:"on_disable,omitempty"` OnEnable *Call `json:"on_enable,omitempty"` GetOAuth2ConnectURL *Call `json:"get_oauth2_connect_url,omitempty"` OnOAuth2Complete *Call `json:"on_oauth2_complete,omitempty"` RequestedPermissions Permissions `json:"requested_permissions,omitempty"` RequestedLocations Locations `json:"requested_locations,omitempty"` HTTPRootURL string `json:"root_url,omitempty"` AWSLambda []AWSLambdaFunction `json:"aws_lambda,omitempty"` PluginID string `json:"plugin_id,omitempty"` }
ManifestV7 is the v0.7.0 version of Manifest, see https://github.com/mattermost/mattermost-plugin-apps/blob/7069695da0c3d14ff449dd0abf8d6cdb261c0df9/apps/manifest.go#L21.
func (ManifestV0_7) Manifest ¶ added in v1.0.0
func (m7 ManifestV0_7) Manifest() *Manifest
type OAuth2App ¶ added in v0.3.0
type OAuth2App struct { RemoteRootURL string `json:"remote_root_url,omitempty"` ClientID string `json:"client_id,omitempty"` ClientSecret string `json:"client_secret,omitempty"` // Data allows apps to store custom data in their OAuth configuration. A // frequent use case is storing app-level service account credentials. Data interface{} `json:"data,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 OpenFAAS ¶ added in v1.0.0
type OpenFAAS struct {
Functions []OpenFAASFunction `json:"functions,omitempty"`
}
type OpenFAASFunction ¶ added in v1.0.0
type OpenFAASFunction struct { // Path is used to match/map incoming Call requests. Path string `json:"path"` // Name is the "short" name of the fuinction, it is combined with the app's // ID+Version when deployed, see upopenfaas.FunctionName. Name string `json:"name"` }
OpenFAASFunction defines a mapping of call paths to a function name. Functions themselves are defined in manifest.yml, in the app bundle, see upopenfaas.DeployApp for details.
func (OpenFAASFunction) Validate ¶ added in v1.0.0
func (of OpenFAASFunction) Validate() error
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" // 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() string
type Permissions ¶
type Permissions []Permission
func (Permissions) Contains ¶
func (p Permissions) Contains(permission Permission) bool
func (Permissions) Validate ¶ added in v1.0.0
func (p Permissions) Validate() error
type Plugin ¶ added in v1.0.0
type Plugin struct { // PluginID is the ID of the plugin, which manages the app, if there is one. PluginID string `json:"plugin_id,omitempty"` }
Plugin contains metadata for an app that is implemented and is deployed and accessed as a local Plugin. The JSON name `plugin` must match the type.
type RemoteWebhookAuthType ¶ added in v1.0.0
type RemoteWebhookAuthType string
type SelectOption ¶
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" // SubjectBotJoinedChannel and SubjectBotLeftChannel subscribes to // SubjectUserJoinedChannel and SubjectUserLeftChannel plugin events, // specifically when the App's bot is added or removed from the channel SubjectBotJoinedChannel Subject = "bot_joined_channel" SubjectBotLeftChannel Subject = "bot_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" // SubjectBotJoinedTeam and SubjectBotLeftTeam subscribes to // SubjectUserJoinedTeam and SubjectUserLeftTeam plugin events, // specifically when the App's bot is added or removed from the team SubjectBotJoinedTeam Subject = "bot_joined_team" SubjectBotLeftTeam Subject = "bot_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" )
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"` // UserID is used internally by Mattermost. It does not need to be set by app // developers. UserID string `json:"user_id"` // 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 `json:"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(s2 Subscription) bool
func (Subscription) Loggable ¶ added in v1.1.0
func (sub Subscription) Loggable() []interface{}
func (Subscription) Validate ¶ added in v1.0.0
func (sub Subscription) Validate() error
type TextFieldSubtype ¶ added in v0.5.0
type TextFieldSubtype string
type UserAgentContext ¶ added in v0.5.0
type UserAgentContext struct { // ChannelID is not send down to Apps. ChannelID string `json:"channel_id,omitempty"` // TeamID is not send down to Apps. TeamID string `json:"team_id,omitempty"` // PostID is not send down to Apps. PostID string `json:"post_id,omitempty"` // RootPostID is not send down to Apps. 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"` // TrackAsSubmit indicates that the call was caused by a user "submit" // action from a binding or a form. TrackAsSubmit bool `json:"track_as_submit,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.
Source Files ¶
- app.go
- binding.go
- call.go
- call_request.go
- call_response.go
- constants.go
- context.go
- deploy.go
- deploy_aws_lambda.go
- deploy_http.go
- deploy_kubeless.go
- deploy_openfaas.go
- deploy_plugin.go
- expand.go
- field.go
- form.go
- http_call_request.go
- locations.go
- manifest.go
- package.go
- permissions.go
- schema_version.go
- subscription.go