Skip to content
Draft
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
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ namespace Example
}
}
}
```

<a id="documentation-for-api-endpoints"></a>
## Documentation for API Endpoints

Expand Down Expand Up @@ -374,6 +372,11 @@ Class | Method | HTTP request | Description
- [Model.WebhookSubscriptionsListBody](docs/WebhookSubscriptionsListBody.md)


<a id="documentation-for-bxml-verbs"></a>
## Documentation for BXML Verbs

- [Bxml.Verbs.Refer](docs/Refer.md)

<a id="documentation-for-authorization"></a>
## Documentation for Authorization

Expand Down
40 changes: 40 additions & 0 deletions docs/Refer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Bandwidth.Standard.Model.Bxml.Verbs.Refer

The `<Refer>` verb is used to hand off a call to a SIP endpoint via a SIP REFER. The call is transferred to the specified SIP URI, and an optional callback is sent when the transfer completes.

For more details, see the [Bandwidth BXML Refer documentation](https://dev.bandwidth.com/docs/voice/bxml/refer.html).

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**ReferCompleteUrl** | **string** | URL to receive the `referComplete` callback when the REFER is finished. | [optional]
**ReferCompleteMethod** | **string** | HTTP method to use for the `referComplete` callback. Must be `GET` or `POST`. | [optional] [default to `POST`]
**Tag** | **string** | Optional custom string to include in callbacks. Max 4096 characters. | [optional]
**SipUriElement** | [**Refer.SipUri**](#sipuri-nested-class) | The SIP URI destination for the REFER. Must start with `sip:`. |

## SipUri Nested Class

The `<SipUri>` element specifies the destination SIP URI for the REFER.

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Uri** | **string** | The SIP URI to refer the call to. Must start with `sip:`. |

## Methods

Name | Description
------------ | -------------
`WithSipUri(string sipUri)` | Sets the SIP URI destination from a string. Returns the `Refer` instance for chaining.
`WithSipUri(SipUri sipUri)` | Sets the SIP URI destination from a `SipUri` object. Returns the `Refer` instance for chaining.
`WithReferCompleteUrl(string referCompleteUrl)` | Sets the `referCompleteUrl` attribute. Returns the `Refer` instance for chaining.
`WithReferCompleteMethod(string referCompleteMethod)` | Sets the `referCompleteMethod` attribute (`GET` or `POST`). Returns the `Refer` instance for chaining.
`WithTag(string tag)` | Sets the `tag` attribute. Returns the `Refer` instance for chaining.

## Validation

- `SipUri.Uri` must start with `sip:` (case-insensitive). An `ArgumentException` is thrown if the value does not match.
- `ReferCompleteMethod` must be either `GET` or `POST`. An `ArgumentException` is thrown for any other value.

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

70 changes: 70 additions & 0 deletions src/Bandwidth.Standard.Test/Unit/Model/Bxml/TestRefer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.IO;
using System.Xml.Serialization;
using Bandwidth.Standard.Model.Bxml;
using Bandwidth.Standard.Model.Bxml.Verbs;
using Xunit;

namespace Bandwidth.Standard.Test.Unit.Model.Bxml
{
public class TestRefer
{
[Fact]
public void ReferRoundTripTest()
{
var expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Response> <Refer referCompleteUrl=\"https://example.com/handleRefer\" referCompleteMethod=\"POST\" tag=\"refer-tag\"> <SipUri>sip:alice@atlanta.example.com</SipUri> </Refer></Response>";

var refer = new Refer()
.WithSipUri("sip:alice@atlanta.example.com")
.WithReferCompleteUrl("https://example.com/handleRefer")
.WithReferCompleteMethod("POST")
.WithTag("refer-tag");

var actual = new Response(refer).ToBXML();
Assert.Equal(expected, actual.Replace("\n", "").Replace("\r", ""));

const string referOnlyXml = "<Refer referCompleteUrl=\"https://example.com/handleRefer\" referCompleteMethod=\"POST\" tag=\"refer-tag\"><SipUri>sip:alice@atlanta.example.com</SipUri></Refer>";
var serializer = new XmlSerializer(typeof(Refer), "");
Refer deserializedRefer;
using (var reader = new StringReader(referOnlyXml))
{
deserializedRefer = (Refer)serializer.Deserialize(reader);
}

Assert.Equal("sip:alice@atlanta.example.com", deserializedRefer.SipUriElement.Uri);
var roundTrip = new Response(deserializedRefer).ToBXML();
Assert.Equal(expected, roundTrip.Replace("\n", "").Replace("\r", ""));
}

[Fact]
public void ReferSipUriMustStartWithSipScheme()
{
var refer = new Refer();
Assert.Throws<ArgumentException>(() => refer.WithSipUri("tel:+15551234567"));
}

[Fact]
public void ReferInvalidMethodThrows()
{
var refer = new Refer();
Assert.Throws<ArgumentException>(() => refer.WithReferCompleteMethod("DELETE"));
}

[Fact]
public void ReferWithSipUriObjectOverload()
{
var sipUri = new Refer.SipUri { Uri = "sip:alice@atlanta.example.com" };
var refer = new Refer().WithSipUri(sipUri);
Assert.Equal("sip:alice@atlanta.example.com", refer.SipUriElement.Uri);
}

[Fact]
public void ReferMinimalOnlySipUri()
{
var refer = new Refer().WithSipUri("sip:bob@biloxi.example.com");
var bxml = new Response(refer).ToBXML();
Assert.Contains("sip:bob@biloxi.example.com", bxml);
Assert.Contains("referCompleteMethod=\"POST\"", bxml);
}
}
}
128 changes: 128 additions & 0 deletions src/Bandwidth.Standard/Model/Bxml/Verbs/Refer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using Bandwidth.Standard.Model.Bxml;
using System;
using System.Xml.Serialization;

namespace Bandwidth.Standard.Model.Bxml.Verbs
{
/// <summary>
/// The Refer verb is used to hand off a call to a SIP endpoint.
/// <para><seealso href="https://dev.bandwidth.com/docs/voice/bxml/refer.html"/></para>
/// </summary>
public class Refer : IVerb
{
private string referCompleteMethod;

/// <summary>
/// URL to receive the refer complete callback.
/// </summary>
[XmlAttribute("referCompleteUrl")]
public string ReferCompleteUrl { get; set; }

/// <summary>
/// HTTP method to send the refer complete callback. GET or POST. Default value is POST.
/// </summary>
[XmlAttribute("referCompleteMethod")]
public string ReferCompleteMethod
{
get { return referCompleteMethod; }
set
{
if (value != null && value != "GET" && value != "POST")
{
throw new ArgumentException("ReferCompleteMethod must be either 'GET' or 'POST'.");
}
referCompleteMethod = value;
}
}

/// <summary>
/// Optional custom string to include in callbacks.
/// </summary>
[XmlAttribute("tag")]
public string Tag { get; set; }

/// <summary>
/// SIP URI destination for the REFER.
/// </summary>
[XmlElement("SipUri")]
public SipUri SipUriElement { get; set; }

/// <summary>
/// Initializes a new instance of the Refer class.
/// </summary>
public Refer()
{
ReferCompleteMethod = "POST";
}

/// <summary>
/// Sets the SIP URI destination from a string.
/// </summary>
public Refer WithSipUri(string sipUri)
{
SipUriElement = new SipUri { Uri = sipUri };
return this;
}

/// <summary>
/// Sets the SIP URI destination from a SipUri object.
/// </summary>
public Refer WithSipUri(SipUri sipUri)
{
SipUriElement = sipUri;
return this;
}

/// <summary>
/// Sets referCompleteUrl.
/// </summary>
public Refer WithReferCompleteUrl(string referCompleteUrl)
{
ReferCompleteUrl = referCompleteUrl;
return this;
}

/// <summary>
/// Sets referCompleteMethod.
/// </summary>
public Refer WithReferCompleteMethod(string referCompleteMethod)
{
ReferCompleteMethod = referCompleteMethod;
return this;
}

/// <summary>
/// Sets tag.
/// </summary>
public Refer WithTag(string tag)
{
Tag = tag;
return this;
}

/// <summary>
/// BXML tag to represent a SIP URI for the refer verb.
/// </summary>
public class SipUri : IVerb
{
private string _uri;

/// <summary>
/// SIP URI to refer the call to (must start with sip:).
/// </summary>
[XmlText]
public string Uri
{
get { return _uri; }
set
{
if (value != null && !value.StartsWith("sip:", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("SipUri must start with 'sip:'.");
}
_uri = value;
}
}
}
}
}
Loading