diff --git a/synapse/config/appservice.py b/synapse/config/appservice.py
index dfe43b0b4c..d7537e8d44 100644
--- a/synapse/config/appservice.py
+++ b/synapse/config/appservice.py
@@ -86,7 +86,7 @@ def load_appservices(hostname, config_files):
def _load_appservice(hostname, as_info, config_filename):
required_string_fields = [
- "id", "url", "as_token", "hs_token", "sender_localpart"
+ "id", "as_token", "hs_token", "sender_localpart"
]
for field in required_string_fields:
if not isinstance(as_info.get(field), basestring):
@@ -94,6 +94,14 @@ def _load_appservice(hostname, as_info, config_filename):
field, config_filename,
))
+ # 'url' must either be a string or explicitly null, not missing
+ # to avoid accidentally turning off push for ASes.
+ if (not isinstance(as_info.get("url"), basestring) and
+ as_info.get("url", "") is not None):
+ raise KeyError(
+ "Required string field or explicit null: 'url' (%s)" % (config_filename,)
+ )
+
localpart = as_info["sender_localpart"]
if urllib.quote(localpart) != localpart:
raise ValueError(
@@ -132,6 +140,13 @@ def _load_appservice(hostname, as_info, config_filename):
for p in protocols:
if not isinstance(p, str):
raise KeyError("Bad value for 'protocols' item")
+
+ if as_info["url"] is None:
+ logger.info(
+ "(%s) Explicitly empty 'url' provided. This application service"
+ " will not receive events or queries.",
+ config_filename,
+ )
return ApplicationService(
token=as_info["as_token"],
url=as_info["url"],
|