Skip to content
1 change: 1 addition & 0 deletions bandwidth/models/bxml/verbs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .phone_number import PhoneNumber
from .play_audio import PlayAudio
from .record import Record
from .refer import Refer
from .redirect import Redirect
from .resume_recording import ResumeRecording
from .ring import Ring
Expand Down
68 changes: 68 additions & 0 deletions bandwidth/models/bxml/verbs/refer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
refer.py

Bandwidth's Refer BXML verb

@copyright Bandwidth INC
"""
from ..nestable_verb import NestableVerb
from .sip_uri import SipUri


class Refer(NestableVerb):

def __init__(
self, sip_uri: SipUri=None,
refer_complete_url: str=None, refer_complete_method: str=None,
tag: str=None
):
"""Initialize a <Refer> verb

The <Refer> verb sends a SIP REFER to the remote endpoint, asking it
to redirect the call to a new SIP URI. Unlike <Transfer>, a successful
REFER terminates the call on Bandwidth's side: the remote endpoint
redirects away from Bandwidth entirely. This is a SIP protocol
property, not a Bandwidth design choice. As a result, BXML returned in
response to the referComplete callback is only meaningful for failure
handling - there is no live call to act on after success.

Args:
sip_uri (SipUri): The SIP URI to refer the call to. Required.
Exactly one <SipUri> child element is allowed. This is the
same SipUri model used by <Transfer>.
refer_complete_url (str, optional): URL to send the Refer Complete
event to when the REFER flow finishes (success or failure).
May be a relative URL. Defaults to None.
refer_complete_method (str, optional): The HTTP method to use for
the request to referCompleteUrl. GET or POST. Default value
is POST. Defaults to None.
tag (str, optional): A custom string that will be sent with this
and all future callbacks unless overwritten by a future tag
attribute or cleared. May be cleared by setting tag="". Max
length 256 characters. Defaults to None.
"""
self.sip_uri = sip_uri
self.refer_complete_url = refer_complete_url
self.refer_complete_method = refer_complete_method
self.tag = tag
super().__init__(
tag="Refer",
nested_verbs=[sip_uri] if sip_uri is not None else []
)

@property
def _attributes(self):
return {
"referCompleteUrl": self.refer_complete_url,
"referCompleteMethod": self.refer_complete_method,
"tag": self.tag
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add something similar to ruby and node to allow the user to set the sip_uri after creation, we can't use add_verb but can write a setter


def set_sip_uri(self, sip_uri: SipUri) -> None:
"""Set the SIP URI destination for this <Refer> verb.

Args:
sip_uri (SipUri): The SIP URI to refer the call to.
"""
self.sip_uri = sip_uri
self._nested_verbs = [sip_uri]
2 changes: 2 additions & 0 deletions bandwidth/models/bxml/verbs/sip_uri.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def __init__(
):
"""Initialize a <SipUri> verb

This SipUri is shared between the <Transfer> and <Refer> verbs.

Args:
uri (str): A SIP URI to transfer the call to (e.g. sip:user@server.com)
uui (str, optional): he value of the User-To-User header to send within the initial INVITE. Must include the encoding parameter as specified in RFC 7433. Only base64 and jwt encoding are currently allowed. This value, including the encoding specifier, may not exceed 256 characters. Defaults to None.
Expand Down
37 changes: 37 additions & 0 deletions test/unit/models/bxml/test_refer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
test_refer.py

Unit tests for the <Refer> BXML verb

@copyright Bandwidth Inc.
"""
import unittest

from bandwidth.models.bxml import Refer, SipUri, Verb, NestableVerb


class TestRefer(unittest.TestCase):

def setUp(self):
self.sip_uri = SipUri(uri="sip:alice@atlanta.example.com")
self.refer = Refer(
sip_uri=self.sip_uri,
refer_complete_url="https://example.com/handleRefer",
refer_complete_method="POST",
tag="test"
)

def test_instance(self):
assert isinstance(self.refer, Refer)
assert isinstance(self.refer, NestableVerb)
assert isinstance(self.refer, Verb)

def test_to_bxml(self):
expected = '<Refer referCompleteUrl="https://example.com/handleRefer" referCompleteMethod="POST" tag="test"><SipUri>sip:alice@atlanta.example.com</SipUri></Refer>'
assert expected == self.refer.to_bxml()

def test_set_sip_uri(self):
refer = Refer()
refer.set_sip_uri(SipUri(uri="sip:bob@example.com"))
expected = '<Refer><SipUri>sip:bob@example.com</SipUri></Refer>'
assert expected == refer.to_bxml()