Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [Unreleased]

### New Features
- Relay: added `call.ring()` — send 180 Ringing on an inbound call without answering it, satisfying an upstream carrier's post-dial-delay timer. The call stays unanswered and unbilled.

## [3.2.0] - 2026-07-14

### New Features
Expand Down
9 changes: 9 additions & 0 deletions relay/docs/call-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ Answer an inbound call.
await call.answer()
```

### `ring(**kwargs) -> dict`

Send **180 Ringing** on an inbound call without answering it, so an upstream carrier's post-dial-delay timer is satisfied. Signalling only: no media, no answer, no billing. Ringing a call takes control of it, so it can no longer be passed to another consumer.

<!-- snippet: no-compile await-fragment -->
```python
await call.ring()
```

### `hangup(reason="hangup") -> dict`

End the call.
Expand Down
4 changes: 4 additions & 0 deletions signalwire/signalwire/relay/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,10 @@ async def answer(self, **kwargs: Any) -> dict[str, Any]:
"""Answer an inbound call."""
return await self._execute("answer", kwargs or None)

async def ring(self, **kwargs: Any) -> dict[str, Any]:
"""Send 180 Ringing on an inbound call without answering it."""
return await self._execute("ring", kwargs or None)

async def hangup(self, reason: str = "hangup") -> dict[str, Any]:
"""End/hang up the call."""
return await self._execute("end", {"reason": reason})
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/relay/test_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ async def test_answer(self, call: Call, mock_client: MagicMock) -> None:
"calling.answer", {"node_id": "node-1", "call_id": "call-1"}
)

@pytest.mark.asyncio
async def test_ring(self, call: Call, mock_client: MagicMock) -> None:
await call.ring()
mock_client.execute.assert_called_once_with(
"calling.ring", {"node_id": "node-1", "call_id": "call-1"}
)

@pytest.mark.asyncio
async def test_hangup(self, call: Call, mock_client: MagicMock) -> None:
await call.hangup(reason="busy")
Expand Down