Coder Social home page Coder Social logo

slackbot's Introduction

slackbot

Simple, pluggable bot framework for Slack chat.

Installation

You can grab the source code using go get github.com/trinchan/slackbot and install like usual. go install github.com/trinchan/slackbot

Setup

Slackbot uses environment variables for all configuration, with domain wide variables prefixed by the domain name in title case (e.g. MYDOMAIN_IN_URL for MyDomain's incoming webhook URL). This makes it easy to support multiple domains and deploy to Heroku. Make sure to set a PORT environment variable defining what port to run your bot on.

An example environment variable list:

BIJIN_TIMEZONE=Asia/Tokyo
MYDOMAIN_OUT_TOKEN=AVerySecretToken
MYDOMAIN_IN_URL=https://hooks.slack.com/services/AAAAAAAAA/BBBBBBBBB/AnotherVerySecretToken
PORT=5000

Setup an Incoming Webhook

If you don't already have an Incoming Webhook setup for your bot, you'll want to start here. Set one up (make sure it's enabled) and don't be afraid to read through the setup instructions. You're after the "Webhook URL" that slack generates for you.

https://hooks.slack.com/services/AAAAAAAAA/BBBBBBBBB/YourSecretToken123456789

For each domain, set an environment variable DOMAIN_IN_URL to this URL.

Send messages to your bot

This framework can respond to "slash commands" and "outgoing webhooks" If you want users to be able to silently type /ping, and have the ping-bot respond in their channel, then you'll want to set up "slash commands". Each bot will need it's own command setup. The other option is to configure an outgoing webhook with a symbol for the prefix. Exe: !ping. This option only requires one configuration, but the commands will be entered into the channel as regular messages.

Configuring an Outgoing Webhook

I use an Outgoing Webhook

  1. Add a new Outgoing Webhook Integration.
  2. Here, you can tell slack to ONLY pay attention to a specific channel, or to simply listen to all public channels. Outgoing Webhooks can not listen to private channels/direct messages.
  3. For each domain, set an environment variable DOMAIN_OUT_TOKEN to your integration's token. This is used to verify payloads come from Slack.
  4. The {trigger_word} should only be one character (preferrably a symbol, such as ! or ?) and typing {trigger_word}ping will trigger the Ping bot.
  5. The URL should follow the following format: your_address.com:port/slack_hook (no trailing /) The bot will respond to commands of the form {trigger_word}bot param param param in the specified channels
Configuring Slash Commands

Alternatively, each bot you make can respond to a corresponding Slash Command.

  1. Add a new slash command, use the bot's name as the name of the command.
  2. The URL should follow the following format: your_address.com:port/slack (no trailing /)
  3. You want to use POST.
  4. For each bot, set an environment variable BOTNAME_SLACK_TOKEN to your slash command's token. This is used to verify payloads come from Slack.
  5. Repeat for each bot you want to enable.

The bot will respond to commands of the form /bot param param param

Configuring Heroku

After setting up the proper environment variables, deploying to heroku should be as simple using the heroku-go-buildpack with a one line modification to run go generate ./... before installing to generate the plugin import file.

Adding Bots

  1. Create a new package and implement the Robot interface.
  2. In importer/importer.sh, add the path to your package to the robots array.
  3. Run go generate ./... to generate init.go which will import your bot.
  4. Rebuild slackbot and deploy.

If you use Sublime Text or another editor which supports snippets for development, then you can simply add and use the included snippet to easily generate a template Robot based on the filename. Otherwise, refer to the template below.

package test

import "github.com/trinchan/slackbot/robots"

type bot struct{}

// Registers the bot with the server for command /test.
func init() {
	r := &bot{}
	robots.RegisterRobot("test", r)
}

// All Robots must implement a Run command to be executed when the registered command is received.
func (r bot) Run(p *robots.Payload) string {
	// If you (optionally) want to do some asynchronous work (like sending API calls to slack)
	// you can put it in a go routine like this
	go r.DeferredAction(p)
	// The string returned here will be shown only to the user who executed the command
	// and will show up as a message from slackbot.
	return "Text to be returned only to the user who made the command."
}

func (r bot) DeferredAction(p *robots.Payload) {
	// Let's use the IncomingWebhook struct defined in payload.go to form and send an
	// IncomingWebhook message to slack that can be seen by everyone in the room. You can
	// read the Slack API Docs (https://api.slack.com/) to know which fields are required, etc.
	// You can also see what data is available from the command structure in definitions.go
	// Alternatively, you can make a SlashCommandResponse, with the same fields, and call
	// reponse.Send(p)
	response := &robots.IncomingWebhook{
		Channel:     p.ChannelID,
		Username:    "Test Bot",
		Text:        "Hi there!",
		IconEmoji:   ":ghost:",
		UnfurlLinks: true,
		Parse:       robots.ParseStyleFull,
	}
	response.Send()
}

func (r bot) Description() string {
	// In addition to a Run method, each Robot must implement a Description method which
	// is just a simple string describing what the Robot does. This is used in the included
	// /c command which gives users a list of commands and descriptions
	return "This is a description for TestBot which will be displayed on /bots"
}

If you are using Slash Commands, you'll need to add a new slash command integration for each bot you add.

Running

If you are not using Heroku, making a env.sh file which exports your environment variables and running slackbot via

source env.sh && slackbot

makes for a convenient one-liner.

If you see output similar to below and you have the commands enabled in your Slack integration, you're ready to go!

2015/06/07 23:26:56 Registered: wiki
2015/06/07 23:26:56 Registered: store
2015/06/07 23:26:56 Registered: roll
2015/06/07 23:26:56 Registered: ping
2015/06/07 23:26:56 Registered: nihongo
2015/06/07 23:26:56 Registered: bots
2015/06/07 23:26:56 Registered: decide
2015/06/07 23:26:56 Registered: bot
2015/06/07 23:26:56 Registered: bijin
2015/06/07 23:26:56 Starting HTTP server on 13748

Using as a Library

If you prefer to use slackbot as a library rather than a binary:

  1. Create a new package and implement the Robot interface as above
  2. use a main function instead of an init function:
package main

import (
  "github.com/trinchan/slackbot/robots"
  "github.com/trinchan/slackbot/server"
)

type bot struct{}

// Starts the server with a bot for command /test.
func main() {
	bots := map[string][]robots.Robot{"test": []robots.Robot{&bot{}}}
	server.Main(bots)
}

slackbot's People

Contributors

9len avatar cptspacetoaster avatar drnic avatar gitizenme avatar mbp avatar nikhita avatar shawnps avatar trinchan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slackbot's Issues

Remove importer, describe init.go in README

This is maybe more of a question rather than an issue:

Why not just check in init.go, and remove the importer.sh/go stuff entirely? Either way the end user has to modify a list of things, the only difference i see is the requirement of including the "_" prefix. Since the end user is probably just copy/pasting your examples, it might be nice to save them the go generate round-trip.

Just a thought.

Thanks for a great framework!

Hi there! I made some edits in a fork, would you care to collab?

Hello, I made some significant changes to the slackbot, over in my fork

You probably won't agree with everything I've done, but I'd like to start a conversation, and maybe figure out if there's anything I've done that you want, or if you want to collaborate further in any way!

In order, the commits/summaries are

  • Cleaned up some scheme errors/warnings when the server recieves an outgoing webhook/command
  • Quick hack to enable one slackbot to service multiple slack servers
  • Changed Outgoing webhook parseing to simply assume the first character is junk, and the command follows it immediatly. (e.g. !ping)
  • Significant modifications to the README.md (Hopefully to improve clarity and setup instructions)

Are you interested in some of this work? If not, that's cool. I'll happily maintain my own fork, I simply wanted to extend a hand, instead of just outright stealing the entire project...

Checkbox what you want (if anything) and I'll PR

Ignoring request from unidentified source

First off, thank you for putting together this framework! I'm having trouble getting past [DEBUG] Ignoring request from unidentified source: - ". I suspect that my environment variables are not setup correctly. In main.go line 35 is looking for %s_OUT_TOKEN. What is %s in this regard? I think my environment variables are not coming across or being referenced right.

No robots registered after uploading to Heroku

I've started learning GO not so long ago, and I try to use this project to develop Slack robots in GO :)

However I don't manage to get this working on Heroku, the robots don't register themselves... It works great when launched locally, either by hand or with foreman start...
On Heroku I don't see the Registered: ... traces, and get the No robot for that command yet :( answer.

Before deploying I do go generate ./... and go install ./....

Is there anything I do wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.