# Buggy code
async def slack_interactions_handler(self, request):
    """Handle interactive events in Slack.

    For each entry in request, it will check if the entry is one of the four main
    interaction types in slack: block_actions, message_actions, view_submissions
    and view_closed. Then it will process all the incoming messages.

    Return:
        A 200 OK response. The Messenger Platform will resend the webhook
        event every 20 seconds, until a 200 OK response is received.
        Failing to return a 200 OK may cause your webhook to be
        unsubscribed by the Messenger Platform.

    """

    req_data = await request.post()
    payload = json.loads(req_data["payload"])

    if "type" in payload:
        if payload["type"] == "block_actions":
            for action in payload["actions"]:
                block_action = BlockActions(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["channel"]["id"],
                    connector=self,
                )
                await block_action.update_entity("value", action["value"])
                await self.opsdroid.parse(block_action)
        elif payload["type"] == "message_action":
            await self.opsdroid.parse(
                MessageAction(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["channel"]["id"],
                    connector=self,
                )
            )
        elif payload["type"] == "view_submission":
            await self.opsdroid.parse(
                ViewSubmission(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["user"]["id"],
                    connector=self,
                )
            )
        elif payload["type"] == "view_closed":
            await self.opsdroid.parse(
                ViewClosed(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["user"]["id"],
                    connector=self,
                )
            )

    return aiohttp.web.Response(text=json.dumps("Received"), status=200)


# Traceback (KeyError)
ERROR aiohttp.server: Error handling request
Traceback (most recent call last):
File "/path/to/venv/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File "/path/to/venv/lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File "/path/to/venv/lib/python3.7/site-packages/opsdroid/connector/slack/__init__.py", line 268, in slack_interactions_handler
await block_action.update_entity("value", action["value"])
KeyError: 'value'
INFO aiohttp.access: 127.0.0.1 [14/Dec/2019:15:01:36 +0000] "POST /connector/slack/interactions HTTP/1.1" 500 244 "-" "Slackbot 1.0 (+https://api.slack.com/robots)"

# Fixed code
async def slack_interactions_handler(self, request):
    """Handle interactive events in Slack.

    For each entry in request, it will check if the entry is one of the four main
    interaction types in slack: block_actions, message_actions, view_submissions
    and view_closed. Then it will process all the incoming messages.

    Return:
        A 200 OK response. The Messenger Platform will resend the webhook
        event every 20 seconds, until a 200 OK response is received.
        Failing to return a 200 OK may cause your webhook to be
        unsubscribed by the Messenger Platform.

    """

    req_data = await request.post()
    payload = json.loads(req_data["payload"])

    if "type" in payload:
        if payload["type"] == "block_actions":
            for action in payload["actions"]:
                block_action = BlockActions(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["channel"]["id"],
                    connector=self,
                )

                action_value = None
                if action["type"] == "button":
                    action_value = action["value"]
                elif action["type"] in ["overflow", "static_select"]:
                    action_value = action["selected_option"]["value"]
                elif action["type"] == "datepicker":
                    action_value = action["selected_date"]
                elif action["type"] == "multi_static_select":
                    action_value = [v["value"] for v in action["selected_options"]]

                if action_value:
                    await block_action.update_entity("value", action_value)
                await self.opsdroid.parse(block_action)
        elif payload["type"] == "message_action":
            await self.opsdroid.parse(
                MessageAction(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["channel"]["id"],
                    connector=self,
                )
            )
        elif payload["type"] == "view_submission":
            await self.opsdroid.parse(
                ViewSubmission(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["user"]["id"],
                    connector=self,
                )
            )
        elif payload["type"] == "view_closed":
            await self.opsdroid.parse(
                ViewClosed(
                    payload,
                    user=payload["user"]["id"],
                    target=payload["user"]["id"],
                    connector=self,
                )
            )

    return aiohttp.web.Response(text=json.dumps("Received"), status=200)