Skip to main content

A simple semi-conversational, multi-step workflow slack bot framework.

Project description

SlackBorg

SlackBorg is a framework for semi-conversational, multi-step workflow Slack Bots. We’re just getting started. Have an idea? File an issue. Have some code? Open a pull request.

Concepts

SlackBorg has two main things you should care about, the @command decorator and the Conversation class.

@command

@command is a decorator you place on a function you implement to respond to a given command. A command can be multi_step, which is to say that its function is called on the given conversation each time a new message comes in, until the conversation is explicitly closed. It’s up to you how you handle a multi-step conversation. As you’ll see, the Conversation object includes all the data you need to make decisions each time your handler is called. If your command is not multi_step, the conversation is closed immediately after your handler returns.

@command parameters:

  • match_string: A RegEx string that you would pass into re.compile. Required

  • flags: Any flags from the re module you would pass into re.compile.

  • multi_step: Set to True if your command is multi-step. Default False.

Conversation

The Conversation object is the sole parameter to your command handler. Conversations are unique to a given user in a given channel. When a message comes in, the conversation manager checks to see if a conversation exists for the sending user in the channel it is posted to. If it doesn’t yet exist, a Conversation object is constructed and the command manager attempts to match a command to the Conversation. If it finds one, its handler is called on the conversation. If a conversation exists, it is updated with the latest message and its command’s handler called on the updated Conversation.

Conversation fields:

  • user_id: the sender’s Slack User ID

  • user_data: the sender’s full Slack User Data (fetched when the Conversation is first created)

  • channel_id: the Conversation’s Slack Channel ID

  • channel_data: the Conversation’s full Slack Channel Data (fetched when the Conversation is first created – only set if it’s a channel and not a DM)

  • initial_message: the message that was responsible for the creation of this Conversation.

  • messages: the rest of the messages. Does not include ``initial_message``.

  • latest_message: the most recent message.

  • context: a dictionary that you can put any data you want to persist in the conversation across messages. This is where the magic is for doing a multi-step command across a conversation.

Conversation methods:

  • say(message): send a message to the channel.

  • close(): close the conversation.

Installation

Right now, I’d probably suggest spinning up a virtualenv and running python setup.py develop inside of it.

Usage

Write yourself a script to declare your commands and run your bot, like so:

import os
import random
import re
import time

from slackborg import *

# Get Bot ID and API Token from env -- make sure to put these in your env!
BOT_ID = os.environ.get('SLACK_BOT_ID')
BOT_TOKEN = os.environ.get('SLACK_BOT_TOKEN')

# Define a default response to any non-matching commands. The default default is to silently ignore the command and close the conversation.
@default_command
def default_cmd(conversation):
    conversation.say("I see, sir {}".format(conversation.user_data['profile']['first_name']))

# Define a command by a regex string, and optionally any flags you'd give the re.compile method.
@command('hello', flags=re.IGNORECASE)
def hello(conversation):
    conversation.say("Hello! I am C-3PO, human-cyborg relations!")

# By default, a command is single-step and auto-closes its conversation upon the handler returning.
# You can override this.
@command('sum', flags=re.IGNORECASE, multi_step=True)
def do_sum(c):
    print c
    operands = c.context.setdefault('operands', [])
    if len(c.messages):
        if 'done' in c.latest_message.lower():
            c.say("The sum of {} = {}".format(
                " + ".join(str(o) for o in operands),
                str(sum(operands))
                )
            )
            c.close()
        else:
            try:
                operands.append(int(c.latest_message))
                c.say("So far: {}...".format(
                    " + ".join(str(o) for o in operands)
                ))
            except:
                c.say("That input wasn't a number. Try again!")
    else:
        c.say("Just enter your operands, one by one, and then type `done` when you're done!")

def main():
    borg = SlackBorg(BOT_ID, BOT_TOKEN)
    borg.run()

if __name__ == '__main__':
    main()

# End

Thanks

Some of the patterns used in this framework borrow ideologies from _lins05/slackbot, so I thank the existing developers of that library for their prior work. Perhaps we can bring these two libraries together, eventually! Or keep them separate :D

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slackborg-0.0.3.tar.gz (5.7 kB view details)

Uploaded Source

File details

Details for the file slackborg-0.0.3.tar.gz.

File metadata

  • Download URL: slackborg-0.0.3.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for slackborg-0.0.3.tar.gz
Algorithm Hash digest
SHA256 69eafa8211b58b3f9f86a8a96b619c66f9c3440d22d347b3c4a2eb2bca3a67e4
MD5 1b1ccb83db862a3dfba91bad3727b22f
BLAKE2b-256 07346f3f8d36c26133aa776037c80cdf3ecc701c94dfc078867056c8b6ba807e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page