plugin

package
v5.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2018 License: AGPL-3.0, Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

The plugin package defines the primary interfaces for interacting with a Mattermost server: the API and the hook interfaces.

The API interface is used to perform actions. The Hook interface is used to respond to actions.

Plugins should define a type that implements some of the methods from the Hook interface, then pass an instance of that object into the rpcplugin package's Main function (See the HelloWorld example.).

Testing

To make testing plugins easier, you can use the plugintest package to create a mock API for your plugin to interact with. See https://godoc.org/github.com/mattermost/mattermost-server/plugin/plugintest

Example (HelloUser)

This example demonstrates a plugin that handles HTTP requests which respond by greeting the user by name.

package main

import (
	"fmt"
	"net/http"

	"github.com/mattermost/mattermost-server/plugin"
	"github.com/mattermost/mattermost-server/plugin/rpcplugin"
)

type HelloUserPlugin struct {
	api plugin.API
}

func (p *HelloUserPlugin) OnActivate(api plugin.API) error {
	// Just save api for later when we need to look up users.
	p.api = api
	return nil
}

func (p *HelloUserPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if userId := r.Header.Get("Mattermost-User-Id"); userId == "" {
		// Our visitor is unauthenticated.
		fmt.Fprintf(w, "Hello, stranger!")
	} else if user, err := p.api.GetUser(userId); err == nil {
		// Greet the user by name!
		fmt.Fprintf(w, "Welcome back, %v!", user.Username)
	} else {
		// This won't happen in normal circumstances, but let's just be safe.
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, err.Error())
	}
}

// This example demonstrates a plugin that handles HTTP requests which respond by greeting the user
// by name.
func main() {
	rpcplugin.Main(&HelloUserPlugin{})
}
Output:

Example (HelloWorld)

This example demonstrates a plugin that handles HTTP requests which respond by greeting the world.

package main

import (
	"fmt"
	"net/http"

	"github.com/mattermost/mattermost-server/plugin/rpcplugin"
)

type HelloWorldPlugin struct{}

func (p *HelloWorldPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, world!")
}

// This example demonstrates a plugin that handles HTTP requests which respond by greeting the
// world.
func main() {
	rpcplugin.Main(&HelloWorldPlugin{})
}
Output:

Index

Examples

Constants

View Source
const (
	MinIdLength = 3
	MaxIdLength = 190
)

Variables

View Source
var ValidId *regexp.Regexp

Functions

func IsValidId

func IsValidId(id string) bool

Types

type API

type API interface {
	// LoadPluginConfiguration loads the plugin's configuration. dest should be a pointer to a
	// struct that the configuration JSON can be unmarshalled to.
	LoadPluginConfiguration(dest interface{}) error

	// RegisterCommand registers a custom slash command. When the command is triggered, your plugin
	// can fulfill it via the ExecuteCommand hook.
	RegisterCommand(command *model.Command) error

	// UnregisterCommand unregisters a command previously registered via RegisterCommand.
	UnregisterCommand(teamId, trigger string) error

	// CreateUser creates a user.
	CreateUser(user *model.User) (*model.User, *model.AppError)

	// DeleteUser deletes a user.
	DeleteUser(userId string) *model.AppError

	// GetUser gets a user.
	GetUser(userId string) (*model.User, *model.AppError)

	// GetUserByEmail gets a user by their email address.
	GetUserByEmail(email string) (*model.User, *model.AppError)

	// GetUserByUsername gets a user by their username.
	GetUserByUsername(name string) (*model.User, *model.AppError)

	// UpdateUser updates a user.
	UpdateUser(user *model.User) (*model.User, *model.AppError)

	// CreateTeam creates a team.
	CreateTeam(team *model.Team) (*model.Team, *model.AppError)

	// DeleteTeam deletes a team.
	DeleteTeam(teamId string) *model.AppError

	// GetTeam gets a team.
	GetTeam(teamId string) (*model.Team, *model.AppError)

	// GetTeamByName gets a team by its name.
	GetTeamByName(name string) (*model.Team, *model.AppError)

	// UpdateTeam updates a team.
	UpdateTeam(team *model.Team) (*model.Team, *model.AppError)

	// CreateChannel creates a channel.
	CreateChannel(channel *model.Channel) (*model.Channel, *model.AppError)

	// DeleteChannel deletes a channel.
	DeleteChannel(channelId string) *model.AppError

	// GetChannel gets a channel.
	GetChannel(channelId string) (*model.Channel, *model.AppError)

	// GetChannelByName gets a channel by its name.
	GetChannelByName(name, teamId string) (*model.Channel, *model.AppError)

	// GetDirectChannel gets a direct message channel.
	GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError)

	// GetGroupChannel gets a group message channel.
	GetGroupChannel(userIds []string) (*model.Channel, *model.AppError)

	// UpdateChannel updates a channel.
	UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)

	// AddChannelMember creates a channel membership for a user.
	AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)

	// GetChannelMember gets a channel membership for a user.
	GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)

	// UpdateChannelMemberRoles updates a user's roles for a channel.
	UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError)

	// UpdateChannelMemberNotifications updates a user's notification properties for a channel.
	UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError)

	// DeleteChannelMember deletes a channel membership for a user.
	DeleteChannelMember(channelId, userId string) *model.AppError

	// CreatePost creates a post.
	CreatePost(post *model.Post) (*model.Post, *model.AppError)

	// DeletePost deletes a post.
	DeletePost(postId string) *model.AppError

	// GetPost gets a post.
	GetPost(postId string) (*model.Post, *model.AppError)

	// UpdatePost updates a post.
	UpdatePost(post *model.Post) (*model.Post, *model.AppError)

	// KeyValueStore returns an object for accessing the persistent key value storage.
	KeyValueStore() KeyValueStore
}

The API can be used to retrieve data or perform actions on behalf of the plugin. Most methods have direct counterparts in the REST API and very similar behavior.

Plugins can obtain access to the API by implementing the OnActivate hook.

type Hooks

type Hooks interface {
	// OnActivate is invoked when the plugin is activated. Implementations will usually want to save
	// the api argument for later use. Loading configuration for the first time is also a commonly
	// done here.
	OnActivate(API) error

	// OnDeactivate is invoked when the plugin is deactivated. This is the plugin's last chance to
	// use the API, and the plugin will be terminated shortly after this invocation.
	OnDeactivate() error

	// OnConfigurationChange is invoked when configuration changes may have been made.
	OnConfigurationChange() error

	// ServeHTTP allows the plugin to implement the http.Handler interface. Requests destined for
	// the /plugins/{id} path will be routed to the plugin.
	//
	// The Mattermost-User-Id header will be present if (and only if) the request is by an
	// authenticated user.
	ServeHTTP(http.ResponseWriter, *http.Request)

	// ExecuteCommand executes a command that has been previously registered via the RegisterCommand
	// API.
	ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.AppError)

	// MessageWillBePosted is invoked when a message is posted by a user before it is commited
	// to the database. If you also want to act on edited posts, see MessageWillBeUpdated.
	// Return values should be the modified post or nil if rejected and an explanation for the user.
	//
	// If you don't need to modify or reject posts, use MessageHasBeenPosted instead.
	//
	// Note that this method will be called for posts created by plugins, including the plugin that
	// created the post.
	MessageWillBePosted(post *model.Post) (*model.Post, string)

	// MessageWillBeUpdated is invoked when a message is updated by a user before it is commited
	// to the database. If you also want to act on new posts, see MessageWillBePosted.
	// Return values should be the modified post or nil if rejected and an explanation for the user.
	// On rejection, the post will be kept in its previous state.
	//
	// If you don't need to modify or rejected updated posts, use MessageHasBeenUpdated instead.
	//
	// Note that this method will be called for posts updated by plugins, including the plugin that
	// updated the post.
	MessageWillBeUpdated(newPost, oldPost *model.Post) (*model.Post, string)

	// MessageHasBeenPosted is invoked after the message has been commited to the databse.
	// If you need to modify or reject the post, see MessageWillBePosted
	// Note that this method will be called for posts created by plugins, including the plugin that
	// created the post.
	MessageHasBeenPosted(post *model.Post)

	// MessageHasBeenUpdated is invoked after a message is updated and has been updated in the databse.
	// If you need to modify or reject the post, see MessageWillBeUpdated
	// Note that this method will be called for posts created by plugins, including the plugin that
	// created the post.
	MessageHasBeenUpdated(newPost, oldPost *model.Post)
}

Methods from the Hooks interface can be used by a plugin to respond to events. Methods are likely to be added over time, and plugins are not expected to implement all of them. Instead, plugins are expected to implement a subset of them and pass an instance to plugin/rpcplugin.Main, which will take over execution of the process and add default behaviors for missing hooks.

type KeyValueStore

type KeyValueStore interface {
	// Set will store a key-value pair, unique per plugin.
	Set(key string, value []byte) *model.AppError

	// Get will retrieve a value based on the key. Returns nil for non-existent keys.
	Get(key string) ([]byte, *model.AppError)

	// Delete will remove a key-value pair. Returns nil for non-existent keys.
	Delete(key string) *model.AppError
}

type Supervisor

type Supervisor interface {
	Start(API) error
	Wait() error
	Stop() error
	Hooks() Hooks
}

Supervisor provides the interface for an object that controls the execution of a plugin. This type is only relevant to the server, and isn't used by the plugins themselves.

Directories

Path Synopsis
Package pluginenv provides high level functionality for discovering and launching plugins.
Package pluginenv provides high level functionality for discovering and launching plugins.
The plugintest package provides mocks that can be used to test plugins.
The plugintest package provides mocks that can be used to test plugins.
mock
This package provides aliases for the contents of "github.com/stretchr/testify/mock".
This package provides aliases for the contents of "github.com/stretchr/testify/mock".

Jump to

Keyboard shortcuts

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