slacker

package module
v2.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2023 License: MIT Imports: 12 Imported by: 0

README

slacker Slack Go Report Card GoDoc Mentioned in Awesome Go

Built on top of the Slack API github.com/slack-go/slack, Slacker is a low-friction framework for creating Slack Bots.

Features

  • Supports Slack Apps using Socket Mode
  • Easy definitions of commands and their input
  • Built-in help command
  • Bot responds to mentions and direct messages
  • Simple parsing of String, Integer, Float and Boolean parameters
  • Customizable, intuitive and with many examples to follow
  • Replies can be new messages or in threads
  • Replies can be ephemeral, scheduled, updated or deleted
  • Supports Slash Commands and Interactive Messages
  • Supports context.Context
  • Supports middlewares & grouping of commands
  • Supports Cron Jobs using https://github.com/robfig/cron
  • Handlers run concurrently via goroutines
  • Full access to the Slack API github.com/slack-go/slack

Install

go get github.com/shomali11/slacker/v2

Examples

We wrote extensive examples to help you familiarize yourself with Slacker!

Preparing your Slack App

To use Slacker you'll need to create a Slack App, either manually or with an app manifest. The app manifest feature is easier, but is a beta feature from Slack and thus may break/change without much notice.

Manual Steps

Slacker works by communicating with the Slack Events API using the Socket Mode connection protocol.

To get started, you must have or create a Slack App and enable Socket Mode, which will generate your app token (SLACK_APP_TOKEN in the examples) that will be needed to authenticate.

Additionally, you need to subscribe to events for your bot to respond to under the Event Subscriptions section. Common event subscriptions for bots include app_mention or message.im.

After setting up your subscriptions, add scopes necessary to your bot in the OAuth & Permissions. The following scopes are recommended for getting started, though you may need to add/remove scopes depending on your bots purpose:

  • app_mentions:read
  • channels:history
  • chat:write
  • groups:history
  • im:history
  • mpim:history

Once you've selected your scopes install your app to the workspace and navigate back to the OAuth & Permissions section. Here you can retrieve yor bot's OAuth token (SLACK_BOT_TOKEN in the examples) from the top of the page.

With both tokens in hand, you can now proceed with the examples below.

App Manifest

Slack App Manifests make it easy to share a app configurations. We provide a simple manifest that should work with all the examples provided below.

The manifest provided will send all messages in channels your bot is in to the bot (including DMs) and not just ones that actually mention them in the message.

If you wish to only have your bot respond to messages they are directly messaged in, you will need to add the app_mentions:read scope, and remove:

  • im:history # single-person dm
  • mpim:history # multi-person dm
  • channels:history # public channels
  • groups:history # private channels

You'll also need to adjust the event subscriptions, adding app_mention and removing:

  • message.channels
  • message.groups
  • message.im
  • message.mpim

Contributing / Submitting an Issue

Please review our Contribution Guidelines if you have found an issue with Slacker or wish to contribute to the project.

Troubleshooting

My bot is not responding to events

There are a few common issues that can cause this:

  • The OAuth (bot) Token may be incorrect. In this case authentication does not fail like it does if the App Token is incorrect, and the bot will simply have no scopes and be unable to respond.
  • Required scopes are missing from the OAuth (bot) Token. Similar to the incorrect OAuth Token, without the necessary scopes, the bot cannot respond.
  • The bot does not have the correct event subscriptions setup, and is not receiving events to respond to.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BotMode

type BotMode int

BotMode instruct the bot on how to handle incoming events that originated from a bot.

const (
	// BotModeIgnoreAll instructs our bot to ignore any activity coming
	// from other bots, including our self.
	BotModeIgnoreAll BotMode = iota

	// BotModeIgnoreApp will ignore any events that originate from a
	// bot that is associated with the same App (ie. share the same App ID) as
	// this bot. OAuth scope `user:read` is required for this mode.
	BotModeIgnoreApp

	// BotModeIgnoreNone will not ignore any bots, including our self.
	// This can lead to bots "talking" to each other so care must be taken when
	// selecting this option.
	BotModeIgnoreNone
)

type ClientOption

type ClientOption func(*clientOptions)

ClientOption an option for client values

func WithAPIURL

func WithAPIURL(url string) ClientOption

WithAPIURL sets the API URL (for testing)

func WithBotMode

func WithBotMode(mode BotMode) ClientOption

WithBotMode instructs Slacker on how to handle message events coming from a bot.

func WithCronLocation

func WithCronLocation(location *time.Location) ClientOption

WithCronLocation overrides the timezone of the cron instance.

func WithDebug

func WithDebug(debug bool) ClientOption

WithDebug sets debug toggle

func WithLogger

func WithLogger(logger Logger) ClientOption

WithLogger sets slacker logger

type Command

type Command interface {
	Definition() *CommandDefinition

	Match(string) (*proper.Properties, bool)
	Tokenize() []*commander.Token
}

Command interface

type CommandContext

type CommandContext struct {
	// contains filtered or unexported fields
}

CommandContext contains information relevant to the executed command

func (*CommandContext) Context

func (r *CommandContext) Context() context.Context

Context returns the context

func (*CommandContext) Definition

func (r *CommandContext) Definition() *CommandDefinition

Definition returns the command definition

func (*CommandContext) Event

func (r *CommandContext) Event() *MessageEvent

Event returns the slack message event

func (*CommandContext) Logger

func (r *CommandContext) Logger() Logger

Logger returns the logger

func (*CommandContext) Request

func (r *CommandContext) Request() *Request

Request returns the command request

func (*CommandContext) Response

func (r *CommandContext) Response() *ResponseReplier

Response returns the response writer

func (*CommandContext) SlackClient

func (r *CommandContext) SlackClient() *slack.Client

SlackClient returns the slack API client

type CommandDefinition

type CommandDefinition struct {
	Command     string
	Aliases     []string
	Description string
	Examples    []string
	Middlewares []CommandMiddlewareHandler
	Handler     CommandHandler

	// HideHelp will hide this command definition from appearing in the `help` results.
	HideHelp bool
}

CommandDefinition structure contains definition of the bot command

type CommandGroup

type CommandGroup struct {
	// contains filtered or unexported fields
}

CommandGroup groups commands with a common prefix and middlewares

func (*CommandGroup) AddCommand

func (g *CommandGroup) AddCommand(definition *CommandDefinition)

AddCommand define a new command and append it to the list of group bot commands

func (*CommandGroup) AddMiddleware

func (g *CommandGroup) AddMiddleware(middleware CommandMiddlewareHandler)

AddMiddleware define a new middleware and append it to the list of group middlewares

func (*CommandGroup) GetCommands

func (g *CommandGroup) GetCommands() []Command

GetCommands returns Commands

func (*CommandGroup) GetMiddlewares

func (g *CommandGroup) GetMiddlewares() []CommandMiddlewareHandler

GetMiddlewares returns Middlewares

func (*CommandGroup) GetPrefix

func (g *CommandGroup) GetPrefix() string

GetPrefix returns the group's prefix

func (*CommandGroup) PrependCommand

func (g *CommandGroup) PrependCommand(definition *CommandDefinition)

PrependCommand define a new command and prepend it to the list of group bot commands

type CommandHandler

type CommandHandler func(*CommandContext)

CommandHandler represents the command handler function

type CommandMiddlewareHandler

type CommandMiddlewareHandler func(CommandHandler) CommandHandler

CommandMiddlewareHandler represents the command middleware handler function

type Interaction

type Interaction struct {
	// contains filtered or unexported fields
}

Interaction structure contains the bot's interaction, description and handler

func (*Interaction) Definition

func (c *Interaction) Definition() *InteractionDefinition

Definition returns the interaction definition

type InteractionContext

type InteractionContext struct {
	// contains filtered or unexported fields
}

InteractionContext contains information relevant to the executed interaction

func (*InteractionContext) Callback

Callback returns the interaction callback

func (*InteractionContext) Context

func (r *InteractionContext) Context() context.Context

Context returns the context

func (*InteractionContext) Definition

func (r *InteractionContext) Definition() *InteractionDefinition

Definition returns the interaction definition

func (*InteractionContext) Logger

func (r *InteractionContext) Logger() Logger

Logger returns the logger

func (*InteractionContext) Response

func (r *InteractionContext) Response() *ResponseReplier

Response returns the response writer

func (*InteractionContext) SlackClient

func (r *InteractionContext) SlackClient() *slack.Client

SlackClient returns the slack API client

type InteractionDefinition

type InteractionDefinition struct {
	BlockID     string
	Middlewares []InteractionMiddlewareHandler
	Handler     InteractionHandler
}

InteractionDefinition structure contains definition of the bot interaction

type InteractionHandler

type InteractionHandler func(*InteractionContext)

InteractionHandler represents the interaction handler function

type InteractionMiddlewareHandler

type InteractionMiddlewareHandler func(InteractionHandler) InteractionHandler

InteractionMiddlewareHandler represents the interaction middleware handler function

type Job

type Job struct {
	// contains filtered or unexported fields
}

Job structure contains the job's spec and handler

func (*Job) Definition

func (c *Job) Definition() *JobDefinition

Definition returns the job's definition

type JobContext

type JobContext struct {
	// contains filtered or unexported fields
}

JobContext contains information relevant to the executed job

func (*JobContext) Context

func (r *JobContext) Context() context.Context

Context returns the context

func (*JobContext) Definition

func (r *JobContext) Definition() *JobDefinition

Definition returns the job definition

func (*JobContext) Logger

func (r *JobContext) Logger() Logger

Logger returns the logger

func (*JobContext) Response

func (r *JobContext) Response() *ResponseWriter

Response returns the response writer

func (*JobContext) SlackClient

func (r *JobContext) SlackClient() *slack.Client

SlackClient returns the slack API client

type JobDefinition

type JobDefinition struct {
	CronExpression string
	Name           string
	Description    string
	Middlewares    []JobMiddlewareHandler
	Handler        JobHandler

	// HideHelp will hide this job definition from appearing in the `help` results.
	HideHelp bool
}

JobDefinition structure contains definition of the job

type JobHandler

type JobHandler func(*JobContext)

JobHandler represents the job handler function

type JobMiddlewareHandler

type JobMiddlewareHandler func(JobHandler) JobHandler

JobMiddlewareHandler represents the job middleware handler function

type Logger

type Logger interface {
	Info(args ...interface{})
	Infof(format string, args ...interface{})
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})
	Error(args ...interface{})
	Errorf(format string, args ...interface{})
}

type MessageEvent

type MessageEvent struct {
	// Channel ID where the message was sent
	ChannelID string

	// Channel contains information about the channel
	Channel *slack.Channel

	// User ID of the sender
	UserID string

	// UserProfile contains all the information details of a given user
	UserProfile *slack.UserProfile

	// Text is the unalterted text of the message, as returned by Slack
	Text string

	// TimeStamp is the message timestamp. For events that do not support
	// threading (eg. slash commands) this will be unset.
	// will be left unset.
	TimeStamp string

	// ThreadTimeStamp is the message thread timestamp. For events that do not
	// support threading (eg. slash commands) this will be unset.
	ThreadTimeStamp string

	// Data is the raw event data returned from slack. Using Type, you can assert
	// this into a slackevents *Event struct.
	Data any

	// Type is the type of the event, as returned by Slack. For instance,
	// `app_mention` or `message`
	Type string

	// BotID of the bot that sent this message. If a bot did not send this
	// message, this will be an empty string.
	BotID string
}

MessageEvent contains details common to message based events, including the raw event as returned from Slack along with the corresponding event type. The struct should be kept minimal and only include data that is commonly used to prevent frequent type assertions when evaluating the event.

func (*MessageEvent) InThread

func (e *MessageEvent) InThread() bool

InThread indicates if a message event took place in a thread.

func (*MessageEvent) IsBot

func (e *MessageEvent) IsBot() bool

IsBot indicates if the message was sent by a bot

type PostOption

type PostOption func(*postOptions)

PostOption an option for post values

func SetAttachments

func SetAttachments(attachments []slack.Attachment) PostOption

SetAttachments sets message attachments

func SetEphemeral

func SetEphemeral(userID string) PostOption

SetEphemeral sets the user who receives the ephemeral message

func SetReplace

func SetReplace(originalMessageTS string) PostOption

SetReplace sets message url to be replaced

func SetSchedule

func SetSchedule(timestamp time.Time) PostOption

SetSchedule sets message's schedule

func SetThreadTS

func SetThreadTS(threadTS string) PostOption

SetThreadTS specifies whether to reply inside a thread

type Replier

type Replier struct {
	// contains filtered or unexported fields
}

Replier sends messages to the same channel the event came from

func (*Replier) Reply

func (r *Replier) Reply(message string, options ...ReplyOption) (string, error)

Reply send a message to the current channel

func (*Replier) ReplyBlocks

func (r *Replier) ReplyBlocks(blocks []slack.Block, options ...ReplyOption) (string, error)

ReplyBlocks send blocks to the current channel

func (*Replier) ReplyError

func (r *Replier) ReplyError(err error, options ...ReplyOption) (string, error)

ReplyError send an error to the current channel

type ReplyOption

type ReplyOption func(*replyOptions)

ReplyOption an option for reply values

func WithAttachments

func WithAttachments(attachments []slack.Attachment) ReplyOption

WithAttachments sets message attachments

func WithEphemeral

func WithEphemeral() ReplyOption

WithEphemeral sets the message as ephemeral

func WithInThread

func WithInThread(inThread bool) ReplyOption

WithInThread specifies whether to reply inside a thread of the original message

func WithReplace

func WithReplace(originalMessageTS string) ReplyOption

WithReplace replaces the original message

func WithSchedule

func WithSchedule(timestamp time.Time) ReplyOption

WithSchedule sets message's schedule

type Request

type Request struct {
	// contains filtered or unexported fields
}

Request contains the Event received and parameters

func (*Request) BooleanParam

func (r *Request) BooleanParam(key string, defaultValue bool) bool

BooleanParam attempts to look up a boolean value by key. If not found, return the default boolean value

func (*Request) FloatParam

func (r *Request) FloatParam(key string, defaultValue float64) float64

FloatParam attempts to look up a float value by key. If not found, return the default float value

func (*Request) IntegerParam

func (r *Request) IntegerParam(key string, defaultValue int) int

IntegerParam attempts to look up a integer value by key. If not found, return the default integer value

func (*Request) Param

func (r *Request) Param(key string) string

Param attempts to look up a string value by key. If not found, return the an empty string

func (*Request) Properties

func (r *Request) Properties() *proper.Properties

Properties returns the properties of the request

func (*Request) StringParam

func (r *Request) StringParam(key string, defaultValue string) string

StringParam attempts to look up a string value by key. If not found, return the default string value

type ResponseReplier

type ResponseReplier struct {
	// contains filtered or unexported fields
}

ResponseReplier sends messages to Slack

func (*ResponseReplier) Delete

func (r *ResponseReplier) Delete(channel string, messageTimestamp string) (string, error)

Delete deletes a message in a channel

func (*ResponseReplier) Post

func (r *ResponseReplier) Post(channel string, message string, options ...PostOption) (string, error)

Post send a message to a channel

func (*ResponseReplier) PostBlocks

func (r *ResponseReplier) PostBlocks(channel string, blocks []slack.Block, options ...PostOption) (string, error)

PostBlocks send blocks to a channel

func (*ResponseReplier) PostError

func (r *ResponseReplier) PostError(channel string, err error, options ...PostOption) (string, error)

PostError send an error to a channel

func (*ResponseReplier) Reply

func (r *ResponseReplier) Reply(message string, options ...ReplyOption) (string, error)

Reply send a message to the current channel

func (*ResponseReplier) ReplyBlocks

func (r *ResponseReplier) ReplyBlocks(blocks []slack.Block, options ...ReplyOption) (string, error)

ReplyBlocks send blocks to the current channel

func (*ResponseReplier) ReplyError

func (r *ResponseReplier) ReplyError(err error, options ...ReplyOption) (string, error)

ReplyError send an error to the current channel

type ResponseWriter

type ResponseWriter struct {
	// contains filtered or unexported fields
}

ResponseWriter sends messages to slack

func (*ResponseWriter) Delete

func (r *ResponseWriter) Delete(channel string, messageTimestamp string) (string, error)

Delete deletes a message in a channel

func (*ResponseWriter) Post

func (r *ResponseWriter) Post(channel string, message string, options ...PostOption) (string, error)

Post send a message to a channel

func (*ResponseWriter) PostBlocks

func (r *ResponseWriter) PostBlocks(channel string, blocks []slack.Block, options ...PostOption) (string, error)

PostBlocks send blocks to a channel

func (*ResponseWriter) PostError

func (r *ResponseWriter) PostError(channel string, err error, options ...PostOption) (string, error)

PostError send an error to a channel

type Slacker

type Slacker struct {
	// contains filtered or unexported fields
}

Slacker contains the Slack API, botCommands, and handlers

func NewClient

func NewClient(botToken, appToken string, clientOptions ...ClientOption) *Slacker

NewClient creates a new client using the Slack API

func (*Slacker) AddCommand

func (s *Slacker) AddCommand(definition *CommandDefinition)

AddCommand define a new command and append it to the list of bot commands

func (*Slacker) AddCommandGroup

func (s *Slacker) AddCommandGroup(prefix string) *CommandGroup

AddCommandGroup define a new group and append it to the list of groups

func (*Slacker) AddCommandMiddleware

func (s *Slacker) AddCommandMiddleware(middleware CommandMiddlewareHandler)

AddCommandMiddleware appends a new command middleware to the list of root level command middlewares

func (*Slacker) AddInteraction

func (s *Slacker) AddInteraction(definition *InteractionDefinition)

AddInteraction define a new interaction and append it to the list of interactions

func (*Slacker) AddInteractionMiddleware

func (s *Slacker) AddInteractionMiddleware(middleware InteractionMiddlewareHandler)

AddInteractionMiddleware appends a new interaction middleware to the list of root level interaction middlewares

func (*Slacker) AddJob

func (s *Slacker) AddJob(definition *JobDefinition)

AddJob define a new cron job and append it to the list of jobs

func (*Slacker) AddJobMiddleware

func (s *Slacker) AddJobMiddleware(middleware JobMiddlewareHandler)

AddJobMiddleware appends a new job middleware to the list of root level job middlewares

func (*Slacker) GetCommandGroups

func (s *Slacker) GetCommandGroups() []*CommandGroup

GetCommandGroups returns Command Groups

func (*Slacker) GetInteractions

func (s *Slacker) GetInteractions() []*Interaction

GetInteractions returns Groups

func (*Slacker) GetJobs

func (s *Slacker) GetJobs() []*Job

GetJobs returns Jobs

func (*Slacker) Help

func (s *Slacker) Help(definition *CommandDefinition)

Help handle the help message, it will use the default if not set

func (*Slacker) Listen

func (s *Slacker) Listen(ctx context.Context) error

Listen receives events from Slack and each is handled as needed

func (*Slacker) OnConnected

func (s *Slacker) OnConnected(onConnected func(socketmode.Event))

OnConnected handle the event when the bot is connected

func (*Slacker) OnConnecting

func (s *Slacker) OnConnecting(onConnecting func(socketmode.Event))

OnConnecting handle the event when the bot is connecting

func (*Slacker) OnConnectionError

func (s *Slacker) OnConnectionError(onConnectionError func(socketmode.Event))

OnConnectionError handle the event when the bot fails to connect

func (*Slacker) OnDisconnected

func (s *Slacker) OnDisconnected(onDisconnected func(socketmode.Event))

OnDisconnected handle the event when the bot is disconnected

func (*Slacker) OnHello

func (s *Slacker) OnHello(onHello func(socketmode.Event))

OnHello handle the event when slack sends the bot "hello"

func (*Slacker) SanitizeEventTextHandler

func (s *Slacker) SanitizeEventTextHandler(sanitizeEventTextHandler func(in string) string)

SanitizeEventTextHandler overrides the default event text sanitization

func (*Slacker) SlackClient

func (s *Slacker) SlackClient() *slack.Client

SlackClient returns the internal slack.Client of Slacker struct

func (*Slacker) SocketModeClient

func (s *Slacker) SocketModeClient() *socketmode.Client

SocketModeClient returns the internal socketmode.Client of Slacker struct

func (*Slacker) SuggestionHandler

func (s *Slacker) SuggestionHandler(suggestionHandler SuggestionHandler)

SuggestionHandler handles block_suggestion handlers since they need to have an Ack with a payload

func (*Slacker) UnsupportedCommandHandler

func (s *Slacker) UnsupportedCommandHandler(unsupportedCommandHandler CommandHandler)

UnsupportedCommandHandler handles messages when none of the commands are matched

func (*Slacker) UnsupportedEventHandler

func (s *Slacker) UnsupportedEventHandler(unsupportedEventHandler func(socketmode.Event))

UnsupportedEventHandler handles events when an unknown event is seen

func (*Slacker) UnsupportedInteractionHandler

func (s *Slacker) UnsupportedInteractionHandler(unsupportedInteractionHandler InteractionHandler)

UnsupportedInteractionHandler handles interactions when none of the callbacks are matched

type SuggestionHandler

type SuggestionHandler func(sm socketmode.Event, ic *InteractionContext)

SuggestionHandler represents the interaction handler function for block_suggestion

type SuggestionMiddlewareHandler

type SuggestionMiddlewareHandler func(SuggestionHandler) SuggestionHandler

SuggestionMiddlewareHandler represents the suggestion middleware handler function

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer sends messages to Slack

func (*Writer) Delete

func (r *Writer) Delete(channel string, messageTimestamp string) (string, error)

Delete deletes message

func (*Writer) Post

func (r *Writer) Post(channel string, message string, options ...PostOption) (string, error)

Post send a message to a channel

func (*Writer) PostBlocks

func (r *Writer) PostBlocks(channel string, blocks []slack.Block, options ...PostOption) (string, error)

PostBlocks send blocks to a channel

func (*Writer) PostError

func (r *Writer) PostError(channel string, err error, options ...PostOption) (string, error)

PostError send an error to a channel

Jump to

Keyboard shortcuts

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