Skip to content
This repository has been archived by the owner on Jun 8, 2022. It is now read-only.

Commit

Permalink
Support for slack actions & admin only messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ovv committed Dec 23, 2017
1 parent 341437c commit db64ebe
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
36 changes: 33 additions & 3 deletions sirbot/plugins/slack/endpoints.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import asyncio
import logging

from aiohttp.web import Response
from slack.events import Event
from slack.actions import Action
from slack.commands import Command
from slack.exceptions import FailedVerification
from aiohttp.web import Response

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -60,8 +61,12 @@ def _incoming_message(event, request):

for handler in slack.routers['message'].dispatch(event):
option = slack.handlers_option[handler]
if not option['mention'] or mention:
yield asyncio.ensure_future(handler(event, request.app))
if option['mention'] and not mention:
continue
elif option['admin'] and event['user'] not in slack.admins:
continue

yield asyncio.ensure_future(handler(event, request.app))


async def incoming_command(request):
Expand All @@ -86,3 +91,28 @@ async def incoming_command(request):
return Response(status=500)

return Response(status=200)


async def incoming_actions(request):
slack = request.app.plugins['slack']
payload = await request.post()
LOG.log(5, 'Incoming action payload: %s', payload)

try:
action = Action.from_http(payload, verification_token=slack.verify)
except FailedVerification:
return Response(status=401)

LOG.debug('Incoming action: %s', action)
callbacks = list()
for callback in slack.routers['action'].dispatch(action):
callbacks.append(asyncio.ensure_future(callback(action, request.app)))

if callbacks:
try:
asyncio.wait(callbacks, return_when=asyncio.ALL_COMPLETED)
except Exception as e:
LOG.exception(e)
return Response(status=500)

return Response(status=200)
22 changes: 17 additions & 5 deletions sirbot/plugins/slack/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

from slack import methods
from slack.io.aiohttp import SlackAPI
from slack.events import EventRouter, MessageRouter
from slack.actions import Router as ActionRouter
from slack.commands import Router as CommandRouter
from slack.events import EventRouter, MessageRouter

from . import endpoints

Expand All @@ -15,9 +16,10 @@
class SlackPlugin:
__name__ = 'slack'

def __init__(self, *, token=None, verify=None, bot_id=None, bot_user_id=None):
def __init__(self, *, token=None, verify=None, bot_id=None, bot_user_id=None, admins=None):
self.api = None
self.token = token or os.environ['SLACK_TOKEN']
self.admins = admins or os.environ.get('SLACK_ADMINS', [])
self.verify = verify or os.environ['SLACK_VERIFY']
self.bot_id = bot_id or os.environ.get('SLACK_BOT_ID')
self.bot_user_id = bot_user_id or os.environ.get('SLACK_BOT_USER_ID')
Expand All @@ -29,7 +31,8 @@ def __init__(self, *, token=None, verify=None, bot_id=None, bot_user_id=None):
self.routers = {
'event': EventRouter(),
'command': CommandRouter(),
'message': MessageRouter()
'message': MessageRouter(),
'action': ActionRouter(),
}

def load(self, sirbot):
Expand All @@ -38,6 +41,7 @@ def load(self, sirbot):

sirbot.router.add_route('POST', '/slack/events', endpoints.incoming_event)
sirbot.router.add_route('POST', '/slack/commands', endpoints.incoming_command)
sirbot.router.add_route('POST', '/slack/actions', endpoints.incoming_actions)

if self.bot_user_id and not self.bot_id:
sirbot.on_startup.append(self.find_bot_id)
Expand All @@ -54,13 +58,21 @@ def on_command(self, command, handler):
handler = asyncio.coroutine(handler)
self.routers['command'].register(command, handler)

def on_message(self, pattern, handler, flags=0, channel='*', mention=False):
def on_message(self, pattern, handler, flags=0, channel='*', mention=False, admin=False):
if not asyncio.iscoroutinefunction(handler):
handler = asyncio.coroutine(handler)

self.handlers_option[handler] = {'mention': mention}
if admin and not self.admins:
LOG.warning('Slack admins ids are not set. Admin limited endpoint will not work.')

self.handlers_option[handler] = {'mention': mention, 'admin': admin}
self.routers['message'].register(pattern=pattern, handler=handler, flags=flags, channel=channel)

def on_action(self, action, handler, name='*'):
if not asyncio.iscoroutinefunction(handler):
handler = asyncio.coroutine(handler)
self.routers['action'].register(action, handler, name)

async def find_bot_id(self, app):
rep = await self.api.query(url=methods.USERS_INFO, data={'user': self.bot_user_id})
self.bot_id = rep['user']['profile']['bot_id']
Expand Down

0 comments on commit db64ebe

Please sign in to comment.