Documentation ¶
Overview ¶
Package slack provides utilities for implementing slack bots in go.
Index ¶
- Constants
- Variables
- func WithBotStore(b BotStore) func(*Controller) error
- func WithClientID(id string) func(*Controller) error
- func WithClientSecret(secret string) func(*Controller) error
- func WithConnector(conn Connector) func(*Controller) error
- func WithConversationStore(cs ConversationStore) func(*Controller) error
- func WithVerification(secret string) func(*Controller) error
- type Bot
- func (bot *Bot) BotUser() string
- func (bot *Bot) Reply(msg *rtm.Message, response *chat.Message) (*chat.Message, error)
- func (bot *Bot) ReplyEphemeral(msg *rtm.Message, response *chat.EphemeralMessage) (string, error)
- func (bot *Bot) ReplyInThread(msg *rtm.Message, response *chat.Message) (*chat.Message, error)
- func (bot *Bot) Say(msg *chat.Message) (*chat.Message, error)
- func (bot *Bot) SayEphemeral(msg *chat.EphemeralMessage) (string, error)
- func (bot *Bot) Start() error
- func (bot *Bot) StartConversation(user, channel, name string) error
- func (bot *Bot) Team() string
- func (bot *Bot) Token() string
- func (bot *Bot) Typing(channel string) error
- func (bot *Bot) Update(ts string, msg *chat.Message) (string, error)
- type BotStore
- type ChannelJoinMessagePair
- type Command
- func (command *Command) OpenDialog(d *dialog.Dialog, token string) error
- func (command *Command) Respond(msg *chat.Message, inChannel bool) error
- func (command *Command) RespondImmediately(msg *chat.Message, inChannel bool) error
- func (command *Command) RespondWithEmptyBody() error
- func (command *Command) RespondWithErrors(errs []*dialog.Error) error
- type Connector
- type Controller
- func (c *Controller) AmbientMessages() <-chan *MessagePair
- func (c *Controller) BotAdded() <-chan *Bot
- func (c *Controller) ChannelJoin() <-chan *ChannelJoinMessagePair
- func (c *Controller) CommandHandler() http.HandlerFunc
- func (c *Controller) Commands() <-chan *Command
- func (c *Controller) CreateAddToSlackURL(scopes []string, redirect, state string) (string, error)
- func (c *Controller) CreateBot(token string) (*Bot, error)
- func (c *Controller) DirectMentions() <-chan *MessagePair
- func (c *Controller) DirectMessages() <-chan *MessagePair
- func (c *Controller) EventHandler() http.HandlerFunc
- func (c *Controller) GroupJoin() <-chan *GroupJoinMessagePair
- func (c *Controller) InteractionHandler() http.HandlerFunc
- func (c *Controller) InteractionOptions() <-chan *InteractionOptionsPair
- func (c *Controller) InteractionOptionsHandler() http.HandlerFunc
- func (c *Controller) Interactions() <-chan *InteractionPair
- func (c *Controller) Mentions() <-chan *MessagePair
- func (c *Controller) OAuthHandler(redirect, expectedState string, ...) http.HandlerFunc
- func (c *Controller) RegisterConversation(name string, conv *Conversation) error
- func (c *Controller) UserChannelJoin() <-chan *UserChannelJoinMessagePair
- type Controls
- type Conversation
- type ConversationHandler
- type ConversationRegistry
- type ConversationStore
- type Event
- type EventPayload
- type GroupJoinMessagePair
- type Interaction
- func (iact *Interaction) OpenDialog(d *dialog.Dialog) error
- func (iact *Interaction) Respond(msg *chat.Message) error
- func (iact *Interaction) RespondImmediately(msg *chat.Message) error
- func (iact *Interaction) RespondWithEmptyBody() error
- func (iact *Interaction) RespondWithErrors(errs []*dialog.Error) error
- type InteractionOptions
- type InteractionOptionsPair
- type InteractionOptionsResponse
- type InteractionPair
- type MemoryBotStore
- type MemoryConversationStore
- func (s *MemoryConversationStore) Active(user, channel, team string) (id, state string, err error)
- func (s *MemoryConversationStore) End(user, channel, team string) error
- func (s *MemoryConversationStore) GetData(user, channel, team, key string) (string, error)
- func (s *MemoryConversationStore) IsActive(user, channel, team string) bool
- func (s *MemoryConversationStore) SetData(user, channel, team, key, value string) error
- func (s *MemoryConversationStore) SetState(user, channel, team, state string) error
- func (s *MemoryConversationStore) Start(user, channel, team, id string) error
- type MessagePair
- type UserChannelJoinMessagePair
Constants ¶
const CommandImmediateResponseTimeout = 2000 * time.Millisecond
CommandImmediateResponseTimeout is the maximum time a command invocation waits before assuming you'll reply using the ResponseURL
const InteractionImmediateResponseTimeout = 2000 * time.Millisecond
InteractionImmediateResponseTimeout is the amount of time an interaction request will wait before it returns with 200 and assumes that ResponseURL will be used to respond.
Variables ¶
var ( ErrInvalidClientID = errors.New("Invalid Client ID") ErrInvalidClientSecret = errors.New("Invalid Client Secret") ErrInvalidVerification = errors.New("Invalid Verification Token") ErrInvalidConnector = errors.New("Invalid Connector") ErrInvalidBotStorage = errors.New("Invalid Bot Storage") ErrInvalidConversationStorage = errors.New("Invalid Conversation Storage") ErrConversationExists = errors.New("Conversation Already Exists") ErrConversationNotFound = errors.New("Conversation Not Found") ErrConversationAlreadyActive = errors.New("Conversation Already Active") ErrNoStartState = errors.New("Conversation Has no start state") ErrInvalidMessage = errors.New("invalid message") ErrChannelUnset = errors.New("channel is not set") ErrExceededResponseCommand = errors.New("Can only respond upto 5 times for a command") ErrExceededResponseInteraction = errors.New("Can only respond upto 5 times for an interaction") ErrEmptyResponseURLInteraction = errors.New("Empty Response URL") ErrStateAlreadyExists = errors.New("State Already Defined") ErrBotNotFound = errors.New("Bot Not Found") ErrBotAlreadyAdded = errors.New("Bot Already Added") ErrItemNotFound = errors.New("Item Not Found") )
Functions ¶
func WithBotStore ¶
func WithBotStore(b BotStore) func(*Controller) error
WithBotStore sets a custom BotStore implementation for storing bot data.
func WithClientID ¶
func WithClientID(id string) func(*Controller) error
WithClientID can be passed to NewController to set the Slack Client ID.
func WithClientSecret ¶
func WithClientSecret(secret string) func(*Controller) error
WithClientSecret can be passed to NewController to set the Slack Client Secret.
func WithConnector ¶
func WithConnector(conn Connector) func(*Controller) error
WithConnector can set a custom Connector instance to manage WebSocket connections.
func WithConversationStore ¶
func WithConversationStore(cs ConversationStore) func(*Controller) error
WithConversationStore sets a custom ConversationStore implementation for storing conversation data.
func WithVerification ¶
func WithVerification(secret string) func(*Controller) error
WithVerification can be passed to NewController to set the slack Verification token.
Types ¶
type Bot ¶
type Bot struct {
// contains filtered or unexported fields
}
Bot represents a single slack bot unique to a slack team.
func (*Bot) ReplyEphemeral ¶
ReplyEphemeral replies to a message with an ephemeral message.
func (*Bot) ReplyInThread ¶
ReplyInThread replies to a message in a thread, creates one if not in a thread.
func (*Bot) SayEphemeral ¶
func (bot *Bot) SayEphemeral(msg *chat.EphemeralMessage) (string, error)
SayEphemeral sends an ephemeral message in a chat.
func (*Bot) Start ¶
Start opens a WebSocket connection to slack to send and receive messages through this bot.
func (*Bot) StartConversation ¶
StartConversation starts the conversation with the given name for the given user in the given channel.
type BotStore ¶
type BotStore interface { // AddBot adds a new bot AddBot(*oauth.AccessResponse) error // GetBot gets the bot payload for a team id GetBot(string) (*oauth.AccessResponse, error) // RemoveBot removes a bot given the team ID RemoveBot(string) error // AllBots gets all the bots stored ever AllBots() ([]*oauth.AccessResponse, error) }
BotStore is an interface used to store bot data.
type ChannelJoinMessagePair ¶
type ChannelJoinMessagePair struct { *rtm.ChannelJoinMessage *Bot }
ChannelJoinMessagePair is sent for channel join events.
ffjson: skip
type Command ¶
type Command struct { TeamID string `json:"team_id"` TeamDomain string `json:"team_domain"` EnterpriseID string `json:"enterprise_id"` EnterpriseName string `json:"enterprise_name"` ChannelID string `json:"channel_id"` ChannelName string `json:"channel_name"` UserID string `json:"user_id"` Command string `json:"command"` Text string `json:"text"` ResponseURL string `json:"response_url"` TriggerID string `json:"trigger_id"` // contains filtered or unexported fields }
Command is the payload sent by slack for a command. ffjson: skip
func (*Command) OpenDialog ¶
OpenDialog opens a dialog as a response to a command.
func (*Command) RespondImmediately ¶
RespondImmediately sends an immediate response to a command
func (*Command) RespondWithEmptyBody ¶
RespondWithEmptyBody responds to a command with an empty response.
type Connector ¶
type Connector interface { // add a new team and socket url to manage Add(team, url string) error // get incoming messages Messages() <-chan *connector.MessagePayload // send typing indicator for a team Typing(team, channel string) error // close the connector Close() }
Connector defines the client interface to a service that manages WebSocket connections for this application.
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller is essentially a manager for a single slack App.
ffjson: skip
func NewController ¶
func NewController(options ...func(*Controller) error) (*Controller, error)
NewController creates a new Controller using the provided functional arguments.
func (*Controller) AmbientMessages ¶
func (c *Controller) AmbientMessages() <-chan *MessagePair
AmbientMessages are messages in conversations that the bot is in, but not mentioned in the message.
func (*Controller) BotAdded ¶
func (c *Controller) BotAdded() <-chan *Bot
BotAdded returns a receive only channel that gets a payload each time a new bot is added.
func (*Controller) ChannelJoin ¶
func (c *Controller) ChannelJoin() <-chan *ChannelJoinMessagePair
ChannelJoin sends a payload each time the bot is added to a new channel.
func (*Controller) CommandHandler ¶
func (c *Controller) CommandHandler() http.HandlerFunc
CommandHandler returns a http.HandlerFunc that can handle slack Command requests.
func (*Controller) Commands ¶
func (c *Controller) Commands() <-chan *Command
Commands returns a receive only channel that'll send a value each time a new command invocation is made.
func (*Controller) CreateAddToSlackURL ¶
func (c *Controller) CreateAddToSlackURL(scopes []string, redirect, state string) (string, error)
CreateAddToSlackURL creates a slack OAuth authorize URL.
func (*Controller) CreateBot ¶
func (c *Controller) CreateBot(token string) (*Bot, error)
CreateBot adds a new Bot given a slack access token.
func (*Controller) DirectMentions ¶
func (c *Controller) DirectMentions() <-chan *MessagePair
DirectMentions returns messages which are sent by mentioning the bot as the first term.
func (*Controller) DirectMessages ¶
func (c *Controller) DirectMessages() <-chan *MessagePair
DirectMessages returns a receive only channel to get direct messages.
func (*Controller) EventHandler ¶
func (c *Controller) EventHandler() http.HandlerFunc
EventHandler returns a http.HandlerFunc that can listen to slack events.
func (*Controller) GroupJoin ¶
func (c *Controller) GroupJoin() <-chan *GroupJoinMessagePair
GroupJoin sends a payload each time a user joins a group chat.
func (*Controller) InteractionHandler ¶
func (c *Controller) InteractionHandler() http.HandlerFunc
InteractionHandler returns a http.HandlerFunc that can be used to handle interactions from slack.
func (*Controller) InteractionOptions ¶
func (c *Controller) InteractionOptions() <-chan *InteractionOptionsPair
InteractionOptions returns a payload each time a new option is added.
func (*Controller) InteractionOptionsHandler ¶
func (c *Controller) InteractionOptionsHandler() http.HandlerFunc
InteractionOptionsHandler returns a http.HandlerFunc that can handle options requests. NOTE: this blocks calling thread
func (*Controller) Interactions ¶
func (c *Controller) Interactions() <-chan *InteractionPair
Interactions returns a payload for each new interaction
func (*Controller) Mentions ¶
func (c *Controller) Mentions() <-chan *MessagePair
Mentions are messages where the bot is mentioned somewhere in the middle.
func (*Controller) OAuthHandler ¶
func (c *Controller) OAuthHandler(redirect, expectedState string, onSuccess func(*oauth.AccessResponse, http.ResponseWriter, *http.Request)) http.HandlerFunc
OAuthHandler returns a http.HandlerFunc that can complete OAuth handshake with slack, creating new Bots.
func (*Controller) RegisterConversation ¶
func (c *Controller) RegisterConversation(name string, conv *Conversation) error
RegisterConversation registers a new conversation with the bot.
func (*Controller) UserChannelJoin ¶
func (c *Controller) UserChannelJoin() <-chan *UserChannelJoinMessagePair
UserChannelJoin sends a payload each time a user joins a new channel.
type Controls ¶
type Controls struct {
// contains filtered or unexported fields
}
Controls is an object passed to conversation handlers and allows setting, getting conversation state and data.
type Conversation ¶
type Conversation struct {
// contains filtered or unexported fields
}
Conversation is a mapping of states to ConversationHandler functions.
ffjson: skip
func NewConversation ¶
func NewConversation() *Conversation
NewConversation creates a new conversation.
func (*Conversation) On ¶
func (s *Conversation) On(state string, handler ConversationHandler) error
On adds a new handler for a particular state.
type ConversationHandler ¶
ConversationHandler is a handler for a conversation state.
type ConversationRegistry ¶
type ConversationRegistry map[string]*Conversation
ConversationRegistry is a mapping of conversation names to implementations.
func NewConversationRegistry ¶
func NewConversationRegistry() ConversationRegistry
NewConversationRegistry creates a ConversationRegistry object.
func (ConversationRegistry) Add ¶
func (c ConversationRegistry) Add(name string, conv *Conversation) error
Add adds a new name -> Conversation mapping.
func (ConversationRegistry) Get ¶
func (c ConversationRegistry) Get(name string) (*Conversation, error)
Get gets the conversation associated with a particular name.
type ConversationStore ¶
type ConversationStore interface { // Start starts a new conversation given a user, channel and team Start(user, channel, team, id string) error // IsActive checks if a conversation is active IsActive(user, channel, team string) bool // Active returns the active conversation id and state Active(user, channel, team string) (id, state string, err error) // SetState sets the state for the current conversation SetState(user, channel, team, state string) error // SetData sets a key-value pair for the current conversation SetData(user, channel, team, key, value string) error // GetData gets the value stored for a key for the current conversation GetData(user, channel, team, key string) (string, error) // End ends the current conversation. End(user, channel, team string) error }
ConversationStore defines the interface for storing conversation data.
type Event ¶
Event is a placeholder for event key payload in the Event payload
ffjson: noencoder
func (*Event) UnmarshalJSON ¶
UnmarshalJSON umarshall json - template of ffjson
func (*Event) UnmarshalJSONFFLexer ¶
UnmarshalJSONFFLexer fast json unmarshall - template ffjson
type EventPayload ¶
type EventPayload struct { Token string `json:"token"` TeamID string `json:"team_id"` APIAppID string `json:"api_app_id"` Event *Event `json:"event"` Type string `json:"type"` EventID string `json:"event_id"` EventTime int `json:"event_time"` AuthedUsers []string `json:"authed_users"` }
EventPayload represents the entire payload received for a slack event.
ffjson: noencoder
func (*EventPayload) UnmarshalJSON ¶
func (j *EventPayload) UnmarshalJSON(input []byte) error
UnmarshalJSON umarshall json - template of ffjson
func (*EventPayload) UnmarshalJSONFFLexer ¶
func (j *EventPayload) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error
UnmarshalJSONFFLexer fast json unmarshall - template ffjson
type GroupJoinMessagePair ¶
type GroupJoinMessagePair struct { *rtm.GroupJoinMessage *Bot }
GroupJoinMessagePair is sent for group join events.
ffjson: skip
type Interaction ¶
type Interaction struct { Actions []*struct { Name string `json:"name"` Value string `json:"value,omitempty"` Text string `json:"text,omitempty"` Type string `json:"type"` SelectedOptions []struct { Value string `json:"value"` } `json:"selected_options,omitempty"` } `json:"actions"` Team *struct { ID string `json:"id"` Domain string `json:"domain"` } `json:"team"` Channel *struct { ID string `json:"id"` Name string `json:"name"` } `json:"channel"` User *struct { ID string `json:"id"` Name string `json:"name"` } `json:"user"` ActionTs string `json:"action_ts"` MessageTs string `json:"message_ts"` AttachmentID string `json:"attachment_id"` CallbackID string `json:"callback_id"` IsAppUnfurl bool `json:"is_app_unfurl"` OriginalMessage *chat.Message `json:"original_message"` ResponseURL string `json:"response_url"` TriggerID string `json:"trigger_id"` Type string `json:"type"` Submission json.RawMessage `json:"submission"` // contains filtered or unexported fields }
Interaction represents the payload received for an interaction.
ffjson: skip
func (*Interaction) OpenDialog ¶
func (iact *Interaction) OpenDialog(d *dialog.Dialog) error
OpenDialog opens a dialog for the current interaction.
func (*Interaction) Respond ¶
func (iact *Interaction) Respond(msg *chat.Message) error
Respond responds to an interaction using the ResponseURL.
func (*Interaction) RespondImmediately ¶
func (iact *Interaction) RespondImmediately(msg *chat.Message) error
RespondImmediately responds immediately to an interaction.
TODO: the channel is closed after the first time, what then?
func (*Interaction) RespondWithEmptyBody ¶
func (iact *Interaction) RespondWithEmptyBody() error
RespondWithEmptyBody responds with an empty body.
func (*Interaction) RespondWithErrors ¶
func (iact *Interaction) RespondWithErrors(errs []*dialog.Error) error
RespondWithErrors responds with an error payload.
type InteractionOptions ¶
type InteractionOptions struct { Name string `json:"name"` Value string `json:"value"` CallbackID string `json:"callback_id"` Team struct { ID string `json:"id"` Domain string `json:"domain"` } `json:"team"` Channel struct { ID string `json:"id"` Name string `json:"name"` } `json:"channel"` User struct { ID string `json:"id"` Name string `json:"name"` } `json:"user"` ActionTs string `json:"action_ts"` MessageTs string `json:"message_ts"` AttachmentID string `json:"attachment_id"` // contains filtered or unexported fields }
InteractionOptions is the payload received for an Interaction Options Request.
ffjson: skip
func (*InteractionOptions) Respond ¶
func (iactopt *InteractionOptions) Respond(msg *InteractionOptionsResponse) error
Respond responds to an interaction options request.
type InteractionOptionsPair ¶
type InteractionOptionsPair struct { *InteractionOptions *Bot }
InteractionOptionsPair is sent for interaction options.
ffjson: skip
type InteractionOptionsResponse ¶
type InteractionOptionsResponse struct { Options []*chat.Option `json:"options,omitempty"` OptionGroups []*chat.OptionGroup `json:"option_groups,omitempty"` }
InteractionOptionsResponse is the response payload sent as a response to an interaction options request.
ffjson: nodecoder
func (*InteractionOptionsResponse) MarshalJSON ¶
func (j *InteractionOptionsResponse) MarshalJSON() ([]byte, error)
MarshalJSON marshal bytes to json - template
func (*InteractionOptionsResponse) MarshalJSONBuf ¶
func (j *InteractionOptionsResponse) MarshalJSONBuf(buf fflib.EncodingBuffer) error
MarshalJSONBuf marshal buff to json - template
type InteractionPair ¶
type InteractionPair struct { *Interaction *Bot }
InteractionPair is sent for interactions
ffjson: skip
type MemoryBotStore ¶
type MemoryBotStore struct {
// contains filtered or unexported fields
}
MemoryBotStore is an in-memory BotStore implementation.
ffjson: skip
func NewMemoryBotStore ¶
func NewMemoryBotStore() *MemoryBotStore
NewMemoryBotStore creates a new MemoryBotStore object.
func (*MemoryBotStore) AddBot ¶
func (bs *MemoryBotStore) AddBot(p *oauth.AccessResponse) error
AddBot adds a new paylaod to the store.
func (*MemoryBotStore) AllBots ¶
func (bs *MemoryBotStore) AllBots() ([]*oauth.AccessResponse, error)
AllBots gets all stored payloads.
func (*MemoryBotStore) GetBot ¶
func (bs *MemoryBotStore) GetBot(team string) (*oauth.AccessResponse, error)
GetBot gets a stored payload given a team.
func (*MemoryBotStore) RemoveBot ¶
func (bs *MemoryBotStore) RemoveBot(team string) error
RemoveBot removes a stored payload given the team.
type MemoryConversationStore ¶
type MemoryConversationStore struct {
// contains filtered or unexported fields
}
MemoryConversationStore is an in-memory implementation of ConversationStore.
ffjson: skip
func NewMemoryConversationStore ¶
func NewMemoryConversationStore() *MemoryConversationStore
NewMemoryConversationStore creates a new MemoryConversationStore object.
func (*MemoryConversationStore) Active ¶
func (s *MemoryConversationStore) Active(user, channel, team string) (id, state string, err error)
Active gets the active conversation.
func (*MemoryConversationStore) End ¶
func (s *MemoryConversationStore) End(user, channel, team string) error
End ends the conversation.
func (*MemoryConversationStore) GetData ¶
func (s *MemoryConversationStore) GetData(user, channel, team, key string) (string, error)
GetData gets the stored value for a key for a conversation.
func (*MemoryConversationStore) IsActive ¶
func (s *MemoryConversationStore) IsActive(user, channel, team string) bool
IsActive checks if a conversation is active.
func (*MemoryConversationStore) SetData ¶
func (s *MemoryConversationStore) SetData(user, channel, team, key, value string) error
SetData sets the value for a key in the current conversation.
func (*MemoryConversationStore) SetState ¶
func (s *MemoryConversationStore) SetState(user, channel, team, state string) error
SetState sets the state for the active conversation.
func (*MemoryConversationStore) Start ¶
func (s *MemoryConversationStore) Start(user, channel, team, id string) error
Start starts a conversation
type MessagePair ¶
MessagePair is sent as the payload when a new message is received. ffjson: skip
func (*MessagePair) Reply ¶
Reply replies with the passed message to the original message with the pair's bot.
func (*MessagePair) StartConversation ¶
func (mp *MessagePair) StartConversation(name string) error
StartConversation starts a conversation with the pair's bot.
type UserChannelJoinMessagePair ¶
type UserChannelJoinMessagePair struct { *rtm.UserChannelJoinMessage *Bot }
UserChannelJoinMessagePair is sent for user channel join events.
ffjson: skip