slack

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 22, 2016 License: MIT Imports: 9 Imported by: 1

README

slack

Build Status Coverage Status GoDoc Go Report Card

Issue Stats Issue Stats

Installation

go get github.com/ajm188/slack

Usage

Starting the Bot
package main

import (
    "fmt"

    "github.com/ajm188/slack"
)

func main() {
    bot := slack.NewBot("my_slack_token")
    err := bot.Start()
    if err != nil {
        fmt.Println(err)
    }
}

Note that you need to pass your Slack token to the bot, so your bot can authenticate with the Slack API.

Simple Response

The design of slack is built around a handler pattern. The bot listens for incoming events from the Slack RTM API, and then invokes any handlers for that type of event.

A valid handler takes a reference to the bot and the event and returns a reference to a Message, and a Status, which tells the main loop whether or not to continue interacting with the RTM API.

slack has some factory methods for constructing handlers for common operations, such as responding to a message or posting a reaction to a message. If you need something more fine-grained, feel free to write your own.

There are also convenience methods for registering handlers specifically for "message" type events. The Bot defines instance methods Listen - which finds text that matches the given pattern - and Respond which finds text that first mentions the bot by name and then matches the given pattern. These helper methods have Regexp variants which can take a compiled regular expression directly instead of a string.

package main

// ... imports blah, blah

func main() {
    bot := slack.NewBot("")
    bot.Respond("hi!", slack.Respond("hi!"))
    bot.Start()
}
Adding a Reaction
package main

// imports

func main() {
    bot := slack.NewBot("")
    bot.Listen("ship ?it\\?", slack.React("shipit"))
    bot.Start()
}
Logging

slack uses logrus for logging. Feel free to set your log level appropriately in an init function.

Documentation

Overview

Package slack provides a library for interacting with the Slack API and building custom bots.

Basics

The basic workflow for writing a bot goes as follows: first, create a new Bot object with your Slack API token; next, register any callbacks you want (outlined in further detail below); last, connect the bot to Slack and let it run forever. This looks like:

bot := slack.NewBot(myToken)
// register callbacks here
bot.Start()

A bot requires a Slack API token in order to connect to Slack, which you can find under the Custom Integrations for your Slack team. It's worth noting that a bot cannot add or remove itself from channels; this has to be done by you when you configure the bot.

When the bot connects, it will collect information about users and channels, and store this information in the Users and Channels maps. The reason for this is that Slack does not deal with channels and users in terms of their names (this is a good thing - channel names and nicks can change), but by a unique ID. The Users and Channels maps map in both directions; so given the human-readable name, they will return the ID, and given the ID they will return the human-readable name.

Slack RTM Basics

Slack provides a Real Time Messaging (RTM) API, for interacting with a Slack channel programmatically. The important thing to know is that all data is in a JSON format. See https://api.slack.com/rtm for more information.

Design

Communication with the RTM API is done via websockets. Package slack uses https://github.com/gorilla/websocket for websockets. From their documentation: "Connections support one concurrent reader and one concurrent writer. Applications are responsible for ensuring that no more than one goroutine calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, WriteJSON) concurrently and that no more than one goroutine calls the read methods (NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) concurrently."

For this reason, BotActions (the type for event handlers) do not take a reference to the websocket connection. Instead, a BotAction takes a reference to the bot and the event that caused the handler to fire, and it should return a tuple of (*Message, Status). If the reference to the message is nil, then nothing will be written into the connection. The Status indicates to the bot how it should continue to process. See the documentation on the Status values for more information.

The main loop listens for incoming events from the RTM websocket, and then calls any handlers that are registered to handle that kind of event. It then writes any non-nil responses into the websocket, and - depending on the various status values - may terminate or continue looping.

Events

The Slack RTM API defines a large number of events, which are listed at https://api.slack.com/events. Note that some events have subtypes. Thus, the bot supports two general purpose methods for registering an event handler, which look like:

bot := NewBot(myToken)
// Fires on any event with type `eventType`
bot.OnEvent(eventType, myHandler)
// Fires only on events with type `eventType` and subtype `eventSubtype'.
// Events with type `eventType` and no subtype will never cause this
// handler to fire.
bot.OnEventWithSubtype(eventType, eventSubtype, myOtherHandler)

Since messages are the most common kind of event, instances of Bot have two helper methods for registering handlers for messages: "Listen" and "Respond".

Listen takes a pattern and a BotAction, and only invokes the given handler if the message text matches the regular expression defined by the pattern. It has a variant, ListenRegexp, which does the same but takes a compiled regular expression rather than a string pattern.

Respond also takes a pattern and a BotAction, and only invokes the given handler if the message text "mentions" the bot, and the rest of the text matches the regular expression defined by the pattern. For a message to "mention" the bot, the message must begin with the bot's name. The leading "@" that is commonly used in Slack is optional, as is the trailing ": ". The text without the portion that was considered part of the "mention" is then compared against the pattern. Respond also has a variant, RespondRegexp, which does exactly what you would expect.

Common BotActions

Package slack provides a few helper functions for generating BotAction handlers for common tasks.

"Respond" creates a handler which will reply to a "message" event with the specified text. So, if a user named "@example" triggers the handler, the bot will say "@example: <text>".

"React" creates a handler which will post a Slack reaction to a "message" event with the specified emoji name. Note that you do not need to put the colons around the emoji name, unlike what you would need to manually do in Slack to produce the emoji.

Index

Constants

View Source
const (
	// Version is the semantic version of this library.
	Version = "0.2.0"
)

Variables

This section is empty.

Functions

func StoreReconnectURL added in v0.1.5

func StoreReconnectURL(bot *Bot, event map[string]interface{}) (*Message, Status)

StoreReconnectURL takes a "url" from an event and stores it. This is done so that when Slack migrates a team to a new host, the bot can use the reconnect URL to reattach to the team.

Types

type Bot

type Bot struct {
	Token       string
	Name        string
	ID          string
	Handlers    map[string]([]BotAction)
	Subhandlers map[string](map[string]([]BotAction))
	Users       map[string]*User
	Channels    map[string]string
	// contains filtered or unexported fields
}

Bot encapsulates all the data needed to interact with Slack.

func NewBot

func NewBot(token string) *Bot

NewBot constructs a new bot with the passed-in Slack API token.

func (*Bot) Call

func (bot *Bot) Call(method string, data url.Values) (map[string]interface{}, error)

Call calls a Slack API method, setting the token of bot in the method call parameters.

func (*Bot) DirectMessage

func (bot *Bot) DirectMessage(userID, text string) *Message

DirectMessage constructs a Message object to send to userID. The channel is obtained by opening a direct message with the given user.

func (*Bot) Listen

func (bot *Bot) Listen(pattern string, handler BotAction)

Listen registers the given handler to fire on "message" events with no subtype which match the regexp specified in pattern.

func (*Bot) ListenRegexp

func (bot *Bot) ListenRegexp(re *regexp.Regexp, handler BotAction)

ListenRegexp functions exactly as Listen, but instead takes a compiled regexp instead of a string.

func (*Bot) Mention

func (bot *Bot) Mention(nick, text, channel string) *Message

Mention constructs a Message which mentions nick with text in channel and returns a reference to it.

func (*Bot) OnEvent

func (bot *Bot) OnEvent(event string, handler BotAction)

OnEvent registers handler to fire on the given type of event.

func (*Bot) OnEventWithSubtype

func (bot *Bot) OnEventWithSubtype(event, subtype string, handler BotAction)

OnEventWithSubtype registers handler to fire on the given type and subtype of event.

func (*Bot) OpenDirectMessage

func (bot *Bot) OpenDirectMessage(userID string) (string, error)

OpenDirectMessage opens a direct message with the given user. The newly created channel ID is returned, or an error in the case of error. If a direct message is already open between the bot and userID, then the API call still succeeds and returns the ID for the pre-existing direct message.

func (*Bot) Respond

func (bot *Bot) Respond(text string, handler BotAction)

Respond registers the given handler to fire on "message" events with no subtype, which address the bot directly and match the given text.

func (*Bot) RespondRegexp

func (bot *Bot) RespondRegexp(re *regexp.Regexp, handler BotAction)

RespondRegexp functions exactly as Respond, but instead takes a compiled regexp instead of a string.

func (*Bot) Start

func (bot *Bot) Start() error

Start initiates the bot's interaction with Slack. It obtains a websockect URL, connects to it, and then starts the main loop.

type BotAction

type BotAction func(self *Bot, event map[string]interface{}) (*Message, Status)

BotAction represents a handler for an RTM event. A valid BotAction takes a reference to the bot, as well as the event that caused it to fire. It should then return a reference to a Message (which can be nil), and a Status, which instructs the bot's main loop in whether to continue listening and sending messages or to terminate.

func React

func React(emoji string) BotAction

React creates a BotAction which reacts to the passed-in event with emoji.

func Respond

func Respond(text string) BotAction

Respond creates a BotAction which responds to the passed-in event with text.

type Error added in v0.1.1

type Error struct {
	Message string
}

Error is the struct used to create custom errors that occur within the slack package.

func (*Error) Error added in v0.1.1

func (err *Error) Error() string

type Message

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

Message represents a message to be sent to the Slack RTM API. Messages are converted to a JSON-like map before they are written to the websocket.

func NewMessage

func NewMessage(text, channel string) *Message

NewMessage constructs a new message object which will send text to channel. The Slack RTM API uses IDs to identify messages, so NewMessage uses the current time as the identifier.

type Status

type Status int

Status is an enumerated type used to communicate between BotActions and the bot's main loop.

const (
	// Continue indicates to keep listening and sending messages.
	Continue Status = iota
	// ShutdownNow indicates to terminate immediately and not send any messages
	// from possible downstream BotActions.
	ShutdownNow
	// Shutdown indicates to finish sending any messages from possible
	// downstream BotActions and then terminate.
	Shutdown
)

type User added in v0.3.0

type User struct {
	ID        string
	Nick      string
	FirstName string
	LastName  string
}

func UserFromJSON added in v0.3.0

func UserFromJSON(data map[string]interface{}) *User

func (*User) FullName added in v0.3.0

func (user *User) FullName() (fullName string)

Directories

Path Synopsis
plugins
github
Package github provides a plugin for building Github integrations into github.com/ajm188/slack.
Package github provides a plugin for building Github integrations into github.com/ajm188/slack.

Jump to

Keyboard shortcuts

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