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
Optional[dict]Defaults 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
Optional[str]Defaults 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

Optional[dict] — 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

1from signalwire import SWMLService
2
3class DynamicService(SWMLService):
4 def __init__(self):
5 super().__init__(name="dynamic-ivr", route="/")
6 self.add_verb("answer", {})
7 self.add_verb("play", {"url": "https://example.com/default.mp3"})
8
9 def on_request(self, request_data=None, callback_path=None):
10 """Customize the greeting based on the caller."""
11 if request_data and "call" in request_data:
12 caller = request_data["call"].get("from", "")
13 if caller.startswith("+1555"):
14 # Return modified sections for VIP callers
15 return {
16 "sections": {
17 "main": [
18 {"answer": {}},
19 {"play": {"url": "https://example.com/vip-greeting.mp3"}}
20 ]
21 }
22 }
23 return None # Use default document
24
25service = DynamicService()
26service.serve()