omnibot_receiver package

Submodules

omnibot_receiver.response module

omnibot_receiver.response.extend_response(resp, extend_resp)

Extend an omnibot response dict structure.

Args:

resp (dict): An omnibot response dict. extend_resp (dict): An omnibot response dict.

Returns:

An omnibot response dict with the actions extended; example:

{
    'actions': [
        {
            'action': 'chat.postMessage',
            'kwargs': {
                'text': 'example'
            }
        },
        {
            'action': 'chat.postMessage',
            'kwargs': {
                'text': 'extended example'
            }
        }
    ]
}
omnibot_receiver.response.get_simple_post_message(text, thread=True, omnibot_parse=None, ephemeral=False)

Get a fully formed response for posting a single, simple, text message.

Args:

text (str): The text to post in the message.

Keyword Args:

thread (bool): Whether or not to post a response in a thread. omnibot_parse (list): A list of resources omnibot should parse before posting the message. ephemeral (bool): Whether to post in-channel or ephemeral.

Returns:

An actions dict, with a single chat.postMessage action; example:

{
    'actions': [
        {
            'action': 'chat.postMessage',
            'kwargs': {
                'text': 'example'
            }
        }
    ]
}
omnibot_receiver.response.get_simple_response(text, omnibot_parse=None, ephemeral=False, replace_original=False)

Get a fully formed response for responding back to a slash command or interactive component event.

Args:

text (str): The text to respond with

Keyword Args:

omnibot_parse (list): A list of resources omnibot should parse before posting the message. ephemeral (bool): Whether to post in-channel or ephemeral. replace_original (bool): Whether to replace the original message, or respond to it.

Returns:

A responses dict, with a single response; example:

{
    'responses': [
        {
            'response_type': 'ephemeral',
            'text': 'example'
        }
    ]
}

omnibot_receiver.router module

exception omnibot_receiver.router.NoMatchedRouteError

Bases: Exception

class omnibot_receiver.router.OmnibotInteractiveRouter

Bases: object

An omnibot interactive component event router. This router can map interactive component event callback IDs to functions.

Every route will be passed the event that comes from omnibot as the first argument. It’s possible to define multiple routes for a single function, but it’s important to remember that only a single default route can be defined. For details on routing, see omnibot_receiver.router.OmnibotInteractiveRouter.route(). Here’s a basic routing example:

from omnibot_receiver.router import OmnibotInteractiveRouter

interactive_router = OmnibotInteractiveRouter()

@interactive_router.route('ping_callback')
def ping(event):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'pong'}
    })
    return ret

It’s possible for multiple types of interactive components to share the same callback_id. By default, route will route all events to the defined function, but if you’d like to split specific event types out, you can specify a separate route with the event_type. Here’s a routing example:

@interactive_router.route(
    'ping_callback',
    event_type='dialog_submission'
)
def ping(event):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'pong'}
    })
    return ret

If you want the bot to default any unrecognized event to a function, you can set a function as a default route:

@interactive_router.set_default()
def unknown(event):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'Unrecognized callback.'}
    })
    return ret

The expected return structure of your routed functions is:

{'actions': [
    {'action': '<slack_api_action>',
        'kwargs': {
            'arg_to_slack_api_action': 'arg_value'
        }
    }
]}

Note in the above that you can return a list of actions, allowing you to do things like post a response to a thread, post to a channel, add reactions to a message, etc.

Once your routes are defined, you can send an omnibot event to the bot; it’ll route it to the correct function, and you’ll get a return, which you can return back to omnibot:

ret = interactive_router.handle_interactive_component(event)
return jsonify(ret)
add_event_callback(callback_id, route_func, event_type=None)

Register a function to be called for messages matching the given rule.

Args:

callback_id (str): A callback_id to match events against. event_type (str): The event type of interactive component, to match against. route_func (function): The function to call when serving this route

Usage:

from omnibot_receiver.router import OmnibotInteractiveRouter

interactive_router = OmnibotInteractiveRouter()

def ping(event):
    # return some actions

interactive_router.add_event_callback('ping_callback', ping)
handle_interactive_component(event)

For the given event, route the event to any routes registered that match the callback id, and return a list of actions for omnibot.

Args:

event (dict): An interactive event sent by omnibot.

Returns:

A dict with an actions attribute that contains a list of slack actions to be returned to omnibot. See slack API methods docs for actions and kwargs. Example:

{'actions': [
    {'action': 'chat.postMessage',
        'kwargs': {
            {'text': 'Hello World!'}
        }
    },
    {
        'action': 'reactions.add',
        'kwargs': {
            'name': 'heart'
        }
    }
]}
route(callback_id, **kwargs)

Register a route for this bot via a decorator.

Args:

callback_id (str): A callback_id to match messages against.
set_default(**kwargs)

Register a route as a default route. If an event isn’t matched by another registered route, it’ll fall back to this route. Only a single route can be defined as a default; setting two defaults will result in a RouteAlreadyDefinedError being raised.

class omnibot_receiver.router.OmnibotMessageRouter(help='', help_as_default=True)

Bases: object

An omnibot message router. The omnibot router can be used to map commands and regex matches to functions in your code.

Every route will be passed the message that comes from omnibot as the first argument. It’s possible to define multiple routes for a single function, but it’s important to remember that only a single default route can be defined. For details on routing, see omnibot_receiver.router.OmnibotMessageRouter.route(). Rules can also be specified more directly via omnibot_receiver.router.OmnibotMessageRouter.add_message_rule(). Here’s a basic routing example:

from omnibot_receiver.router import OmnibotMessageRouter

message_router = OmnibotMessageRouter(
    help='This bot is used for pings and pongs.'
)

@message_router.route(
    'ping',
    match_type='command',
    help='Responds to pings with pongs'
)
@message_router.route(
    '.*ping.*',
    match_type='regex',
    help='Responds to messages of pings with pongs'
)
def ping(message):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'pong'}
    })
    return ret

If you want the bot to default any unrecognized message to a function, you can set a function as a default route:

@message_router.set_default()
def unknown(message):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'Unrecognized command.'}
    })
    return ret

If no default route is defined, OmnibotMessageRouter will automatically route unmatched messages to the help documentation. If you want unmatched messages to be ignored, you can initialize OmnibotMessageRouter with help_as_default as False:

from omnibot_receiver.router import OmnibotMessageRouter

message_router = OmnibotMessageRouter(
    help='This bot is used for pings and pongs.',
    help_as_default=False
)

The router is roughly modeled after Flask, so it’s possible to define variables to capture in the route. For example, below we’re capturing a part of the command string (user), and it’s being passed into the function.

@message_router.route(
    'find <user>',
    match_type='command',
    help='Find info about a user.'
)
def find_user(message, user):
    ret = {'actions': []}
    ret['actions'].append({
        'action': 'chat.postMessage',
        'kwargs': {'text': 'example'}
    })
    return ret

The expected return structure of your routed functions is:

{'actions': [
    {'action': '<slack_api_action>',
        'kwargs': {
            'arg_to_slack_api_action': 'arg_value'
        }
    }
]}

Note in the above that you can return a list of actions, allowing you to do things like post a response to a thread, post to a channel, add reactions to a message, etc.

By default omnibot-receiver will auto-generate help documentation for your bot from the help parameters of the OmnibotMessageRouter class and the defined routes. It’s possible to override this, by setting the help:

@message_router.set_help()
def help(message):
    # This is what gets returned by default.
    return message_router.get_help(message)

Setting help doesn’t route a help command to your help function, if you wish to do so, add a command to the function:

@message_router.route(
    'help',
    match_type='command',
    help='Help for this bot'
)
@message_router.set_help()
def help(message):
    # This is what gets returned by default.
    return message_router.get_help(message)

Once your routes are defined, you can send an omnibot message to the bot, it’ll route it to the correct function, and you’ll get a return, which you can return back to omnibot:

ret = message_router.handle_message(message)
return jsonify(ret)
add_message_rule(rule, match_type, route_func, help='')

Register a function to be called for messages matching the given rule.

Args:

rule (str): A regex to match messages against. match_type (str): The type of message this route should match against:

command -- Match against messages directed at this bot.
regex   -- Match against messages in a channel that have
           been targetted at this bot by omnibot.

route_func (function): The function to call when serving this route **kwargs (dict): Keyword arguments (see below for more info)

Keyword Args:

help (str): Help text for this route, to be included with the help docs generated from omnibot_receiver.router.OmnibotMessageRouter.get_help()

Usage:

from omnibot_receiver.router import OmnibotMessageRouter

message_router = OmnibotMessageRouter(
    help='This bot is used for pings and pongs.'
)

def ping(message):
    # return some actions

message_router.add_message_rule(
    'ping',
    'command',
    ping,
    help='Responds to pings'
)
get_help(message, **kwargs)

Autogenerate and return a help message for this router based on the commands and regexes registered.

Args:

message (dict): An omnibot message of type help. **kwargs (dict): A dict provided for compatibility with the calling function.

Returns:

A dict of action lists to be returned to omnibot. Example:

{
    'actions' = [{
        'action': 'chat.postMessage',
        'kwargs': {
            'text': 'example message',
            'attachments': [{
                'title': 'Commands:',
                'fields': [{
                    'title': 'help',
                    'value': 'A help command.',
                    'short': False
                }]
            }]
        }
    }]
}
handle_message(message)

For the given message, route the message to any routes registered that match its attributes, and return a list of actions for omnibot.

Args:

message (dict): A message sent by omnibot.

Returns:

A dict with an actions attribute that contains a list of slack actions to be returned to omnibot. See slack API methods docs for actions and kwargs. Example:

{'actions': [
    {'action': 'chat.postMessage',
        'kwargs': {
            {'text': 'Hello World!'}
        }
    },
    {
        'action': 'reactions.add',
        'kwargs': {
            'name': 'heart'
        }
    }
]}
route(rule, **kwargs)

Register a route for this bot via a decorator.

Args:

rule (str): A regex to match messages against. **kwargs (dict): Keyword arguments (see below for more info)

Keyword Args:

match_type (str): The type of message this route should match against:

command -- Match against messages directed at this bot.
regex   -- Match against messages in a channel that have
           been targetted at this bot by omnibot.

help (str): Help text for this route, to be included with the help docs generated from omnibot_receiver.router.OmnibotMessageRouter.get_help()

set_default(**kwargs)

Register a route as a default route. If a message isn’t matched by another registered route, it’ll fall back to this route. Only a single route can be defined as a default; setting two defaults will result in a RouteAlreadyDefinedError being raised.

set_help(**kwargs)

Register a function to render help documentation. Note that this is not a route, but is the function that renders the help only. You must register a help command to route to this function.

class omnibot_receiver.router.OmnibotRouter(message_router=None, interactive_router=None)

Bases: object

A generic omnibot router. The omnibot router can be used to map any type of message, to one of the configured routers.

from omnibot_receiver.router import (
    OmnibotMessageRouter,
    OmnibotInteractiveRouter,
    OmnibotRouter,
)

message_router = OmnibotMessageRouter(
    help='This bot is used for pings and pongs.'
)
interactive_router = OmnibotInteractiveRouter()
router = OmnibotRouter(
    message_router=message_router,
    interactive_router=interactive_router
)

This makes it possible to route all omnibot payloads via a single function.

from bot_location import router

@flask_app.route('/api/v1/bot', methods=['POST'])
def pingbot_route():
    message = request.get_json()
    ret = router.handle_message(message)
    return jsonify(ret)
handle_event(event)

For the given event, route the event to the relevant configured router and to the registered function that matches the event in that router.

Args:

event (dict): An event sent by omnibot.

Returns:

A dict with an actions attribute that contains a list of slack actions to be returned to omnibot. See slack API methods docs for actions and kwargs. Example:

{'actions': [
    {'action': 'chat.postMessage',
        'kwargs': {
            {'text': 'Hello World!'}
        }
    },
    {
        'action': 'reactions.add',
        'kwargs': {
            'name': 'heart'
        }
    }
]}
exception omnibot_receiver.router.RouteAlreadyDefinedError

Bases: Exception

exception omnibot_receiver.router.UnsupportedPayloadError

Bases: Exception

Module contents