diff --git a/sirbot/bot.py b/sirbot/bot.py index 65cf88f..6d76ce8 100644 --- a/sirbot/bot.py +++ b/sirbot/bot.py @@ -8,11 +8,12 @@ class SirBot(aiohttp.web.Application): - def __init__(self, **kwargs): + def __init__(self, user_agent=None, **kwargs): super().__init__(**kwargs) self.plugins = dict() self.http_session = aiohttp.ClientSession(loop=kwargs.get('loop') or asyncio.get_event_loop()) + self.user_agent = user_agent or 'sir-bot-a-lot' self.router.add_route('GET', '/sirbot/plugins', endpoints.plugins) def start(self, **kwargs): diff --git a/sirbot/plugins/github/__init__.py b/sirbot/plugins/github/__init__.py new file mode 100644 index 0000000..d235254 --- /dev/null +++ b/sirbot/plugins/github/__init__.py @@ -0,0 +1 @@ +from .plugin import GithubPlugin diff --git a/sirbot/plugins/github/plugin.py b/sirbot/plugins/github/plugin.py new file mode 100644 index 0000000..0f283d8 --- /dev/null +++ b/sirbot/plugins/github/plugin.py @@ -0,0 +1,42 @@ +import os +import logging + +from gidgethub import ValidationFailure +from gidgethub.aiohttp import GitHubAPI +from gidgethub.sansio import Event +from gidgethub.routing import Router + +from aiohttp.web import Response + +LOG = logging.getLogger(__name__) + + +class GithubPlugin: + __name__ = 'github' + + def __init__(self, *, verify=None): + self.api = None + self.router = Router() + self.verify = verify or os.environ['GITHUB_VERIFY'] + + def load(self, sirbot): + LOG.info('Loading github plugin') + self.api = GitHubAPI(session=sirbot.http_session, requester=sirbot.user_agent) + + sirbot.router.add_route('POST', '/github', dispatch) + + +async def dispatch(request): + github = request.app.plugins['github'] + payload = await request.read() + + try: + event = Event.from_http(request.headers, payload, secret=github.verify) + await github.router.dispatch(event, app=request.app) + except ValidationFailure as e: + LOG.debug('Github webhook failed verification: %s, %s', request.headers, payload) + except Exception as e: + LOG.exception(e) + return Response(status=500) + else: + return Response(status=200)