diff --git a/homeassistant/components/webhook/trigger.py b/homeassistant/components/webhook/trigger.py index 3cc27a6f7e1..f651a56b2dd 100644 --- a/homeassistant/components/webhook/trigger.py +++ b/homeassistant/components/webhook/trigger.py @@ -15,6 +15,7 @@ from homeassistant.helpers import config_validation as cv from homeassistant.helpers.template import Template from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo from homeassistant.helpers.typing import ConfigType, TemplateVarsType +from homeassistant.util.json import json_loads from . import ( DEFAULT_METHODS, @@ -62,7 +63,9 @@ async def _handle_webhook( base_result: dict[str, Any] = {"platform": "webhook", "webhook_id": webhook_id} if "json" in request.headers.get(hdrs.CONTENT_TYPE, ""): - base_result["json"] = await request.json() + # Always attempt to read the body; request.text() returns "" if empty + text = await request.text() + base_result["json"] = json_loads(text) if text else {} else: base_result["data"] = await request.post() diff --git a/tests/components/webhook/test_trigger.py b/tests/components/webhook/test_trigger.py index 74a2d15b9ba..2f7f2900771 100644 --- a/tests/components/webhook/test_trigger.py +++ b/tests/components/webhook/test_trigger.py @@ -8,6 +8,7 @@ import pytest from homeassistant.core import HomeAssistant, callback from homeassistant.setup import async_setup_component +from tests.common import async_capture_events from tests.typing import ClientSessionGenerator @@ -377,3 +378,46 @@ async def test_webhook_template( assert len(events) == 1 assert events[0].data["hello"] == "yo world" + + +async def test_webhook_query_json_header_no_payload( + hass: HomeAssistant, hass_client_no_auth: ClientSessionGenerator +) -> None: + """Test requests with application/json header but no payload.""" + events = async_capture_events(hass, "test_success") + + assert await async_setup_component( + hass, + "automation", + { + "automation": { + "trigger": { + "platform": "webhook", + "webhook_id": "no_payload_webhook", + "local_only": True, + "allowed_methods": ["GET", "POST"], + }, + "action": { + "event": "test_success", + }, + } + }, + ) + await hass.async_block_till_done() + client = await hass_client_no_auth() + + # GET + response = await client.get( + "/api/webhook/no_payload_webhook", headers={"Content-Type": "application/json"} + ) + await hass.async_block_till_done() + assert response.status == 200 + + # POST + response = await client.post( + "/api/webhook/no_payload_webhook", headers={"Content-Type": "application/json"} + ) + await hass.async_block_till_done() + assert response.status == 200 + + assert len(events) == 2