on_request

View as MarkdownOpen in Claude

Hook method called every time SWML is requested, before the document is returned to the caller. Override this in a subclass to inspect the incoming request and optionally modify the SWML document on a per-request basis. This enables dynamic SWML generation where the document content varies based on who is calling, what SIP route was matched, or any data in the POST body.

The default implementation returns None (no modifications). When you return a dictionary, its keys are merged into the top-level SWML document, allowing you to replace entire sections.

This method is called on both GET and POST requests. For GET requests, request_data is an empty dictionary. For POST requests, it contains the parsed JSON body sent by SignalWire.

Parameters

request_data
dict[str, Any] | NoneDefaults to None

The parsed POST body as a dictionary, or an empty dict for GET requests. Typically contains call metadata from SignalWire (e.g., call.to, call.from, call.headers).

callback_path
str | NoneDefaults to None

The routing callback path that matched this request, if any. This is set when the request came through a path registered via register_routing_callback(). None for requests to the main route.

Returns

dict | None — Return None to serve the document unchanged. Return a dictionary to merge modifications into the top-level SWML document (keys in the returned dict replace corresponding keys in the document).

Example

from signalwire import SWMLService
class DynamicService(SWMLService):
def __init__(self):
super().__init__(name="dynamic-ivr", route="/")
self.add_verb("answer", {})
self.add_verb("play", {"url": "https://example.com/default.mp3"})
def on_request(self, request_data=None, callback_path=None):
"""Customize the greeting based on the caller."""
if request_data and "call" in request_data:
caller = request_data["call"].get("from", "")
if caller.startswith("+1555"):
# Return modified sections for VIP callers
return {
"sections": {
"main": [
{"answer": {}},
{"play": {"url": "https://example.com/vip-greeting.mp3"}}
]
}
}
return None # Use default document
service = DynamicService()
service.serve()