Source code for slack.commands

import typing
import logging
from typing import Any, Dict, Iterator, Optional
from collections import defaultdict
from collections.abc import MutableMapping

from . import exceptions

LOG = logging.getLogger(__name__)


[docs]class Command(MutableMapping): """ MutableMapping representing a slack slash command. Args: raw_command: Decoded body of the webhook HTTP request Raises: :class:`slack.exceptions.FailedVerification`: when `verification_token` or `team_id` does not match the incoming command's """ def __init__( self, raw_command: typing.MutableMapping, verification_token: Optional[str] = None, team_id: Optional[str] = None, ) -> None: self.command = raw_command if verification_token and self.command["token"] != verification_token: raise exceptions.FailedVerification( self.command["token"], self.command["team_id"] ) if team_id and self.command["team_id"] != team_id: raise exceptions.FailedVerification( self.command["token"], self.command["team_id"] ) def __getitem__(self, item): return self.command[item] def __setitem__(self, key, value): self.command[key] = value def __delitem__(self, key): del self.command[key] def __iter__(self): return iter(self.command) def __len__(self): return len(self.command) def __repr__(self): return str(self.command)
[docs]class Router: """ When creating slash command for your applications each one can have a custom webhook url. For ease of configuration this class provide a routing mechanisms based on the command so that each command can define the same webhook url. """ def __init__(self): self._routes: Dict[str, list] = defaultdict(list)
[docs] def register(self, command: str, handler: Any): """ Register a new handler for a specific slash command Args: command: Slash command handler: Callback """ if not command.startswith("/"): command = f"/{command}" LOG.info("Registering %s to %s", command, handler) self._routes[command].append(handler)
[docs] def dispatch(self, command: Command) -> Iterator[Any]: """ Yields handlers matching the incoming :class:`slack.actions.Command`. Args: command: :class:`slack.actions.Command` Yields: handler """ LOG.debug("Dispatching command %s", command["command"]) for callback in self._routes[command["command"]]: yield callback