# Buggy code
async def webhook(request: Request) -> HTTPResponse:
    if request.form:
        output = request.form
        payload = json.loads(output["payload"][0])

        if self._is_interactive_message(payload):
            sender_id = payload["user"]["id"]
            text = self._get_interactive_response(payload["actions"][0])
            if text is not None:
                metadata = self.get_metadata(request)
                return await self.process_message(
                    request, on_new_message, text, sender_id, metadata
                )
            elif payload["actions"][0]["type"] == "button":
                # link buttons don't have "value", don't send their clicks to bot
                return response.text("User clicked link button")
        return response.text("The input message could not be processed.", status=500)

    elif request.json:
        output = request.json
        event = output.get("event", {})
        user_message = event.get("text", "")
        sender_id = event.get("user", "")
        metadata = self.get_metadata(request)

        if "challenge" in output:
            return response.json(output.get("challenge"))

        elif self._is_user_message(output) and self._is_supported_channel(
            output, metadata
        ):
            return await self.process_message(
                request,
                on_new_message,
                text=self._sanitize_user_message(user_message, metadata["users"]),
                sender_id=sender_id,
                metadata=metadata,
            )
        else:
            logger.warning(
                f"Received message on unsupported channel: {metadata['out_channel']}"
            )

    return response.text("Bot message delivered.")


# Traceback (ValueError)
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\sanic\request.py", line 173, in load_json
self.parsed_json = loads(self.body)
ValueError: Expected object or value

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\sanic\app.py", line 976, in handle_request
response = await response
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\rasa\core\channels\slack.py", line 356, in webhook
metadata = self.get_metadata(request)
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\rasa\core\channels\slack.py", line 329, in get_metadata
slack_event = request.json
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\sanic\request.py", line 167, in json
self.load_json()
File "c:\users\jitesh\appdata\local\programs\python\python37\lib\site-packages\sanic\request.py", line 177, in load_json
raise InvalidUsage("Failed when parsing body as json")
sanic.exceptions.InvalidUsage: Failed when parsing body as json

# Fixed code
async def webhook(request: Request) -> HTTPResponse:
    content_type = request.headers.get("content-type")
    # Slack API sends either a JSON-encoded or a URL-encoded body depending on the content

    if content_type == "application/json":
        # if JSON-encoded message is received
        output = request.json
        event = output.get("event", {})
        user_message = event.get("text", "")
        sender_id = event.get("user", "")
        metadata = self.get_metadata(request)

        if "challenge" in output:
            return response.json(output.get("challenge"))

        elif self._is_user_message(output) and self._is_supported_channel(
            output, metadata
        ):
            return await self.process_message(
                request,
                on_new_message,
                text=self._sanitize_user_message(user_message, metadata["users"]),
                sender_id=sender_id,
                metadata=metadata,
            )
        else:
            logger.warning(
                f"Received message on unsupported channel: {metadata['out_channel']}"
            )

    elif content_type == "application/x-www-form-urlencoded":
        # if URL-encoded message is received
        output = request.form
        payload = json.loads(output["payload"][0])

        if self._is_interactive_message(payload):
            sender_id = payload["user"]["id"]
            text = self._get_interactive_response(payload["actions"][0])
            if text is not None:
                metadata = self.get_metadata(request)
                return await self.process_message(
                    request, on_new_message, text, sender_id, metadata
                )
            if payload["actions"][0]["type"] == "button":
                # link buttons don't have "value", don't send their clicks to bot
                return response.text("User clicked link button")
        return response.text("The input message could not be processed.", status=500)

    return response.text("Bot message delivered.")