Giter VIP home page Giter VIP logo

csharp-bandwidth-iris's Introduction

Bandwidth C# IRIS Client

Installing

Bandwidth C# SDK uses Nuget for Package Management

Run

nuget install Bandwidth.Iris

Or install Bandwidth.Iris via UI in Visual Studio

Getting Started

  • Install Bandwidth.Iris
  • Get an account ID, user name and password from Bandwidth for your account
  • Configure the Client
var client = Client.GetInstance("accountId", "username", "password", "apiEndpoint")
//Or
//Uses the System Environment Variables as detailed below
var client = Client.GetInstance()
Environment Variable Definition
BANDWIDTH_API_ACCOUNT_ID Your Bandwidth Account Id
BANDWIDTH_API_USERNAME Your Bandwidth username
BANDWIDTH_API_PASSWORD Your Bandwidth password
BANDWIDTH_API_ENDPOINT https://dashboard.bandwidth.com/api
BANDWIDTH_API_VERSION v1.0

Usage

All static functions support 2 ways to be called: With a client instance as the first arg or without the client instance (default client instance will then be used)

var site = await Site.get(client, "siteId");
//Or
var site = await Site.get("siteId"); //This will use the default client where supported

API Objects

General Principles

When using the objects, there are generally static methods for Create, Get and List of each entity. Once you have an instance of any entity, you can call the instance methods of that entity to perform additional operations.

var sites = await Site.List(client);
var site = await Site.Get(client, "siteId");
var newSite = await Site.Create(client, new Site(){
  Name = "MyTest Site"

});
var sipPeers = await site.GetSipPeers();
site.Delete();

Error Handling Tips

When making making API calls the client can throw an AggregateException this will normally contain a BandwidthIrisException. A suggested way to handle the API calls is to catch the AggregateException that API calls can create and #Handle the BandwidthIrisException. Example:

 try
{
    var site = await Site.Get(client, "siteId");
} catch (AggregateException e)
{
    e.Handle((x) =>
    {
        if(x is BandwidthIrisException)
        {
            //Do something 
            return true;
        }

        return false;
    });
}

Available NpaNxx

var query = new Dictionary<string, object>();
query.Add("areaCode", "805");
query.Add("quantity", 3);
var items = await AvailableNpaNxx.List(_client, query);
foreach (AvailableNpaNxx npaNxx in items)
{
    Console.WriteLine(string.Format("NpaNxx: {0}",npaNxx.Npa + npaNxx.Nxx));
}

Available Numbers

var query = new Dictionary<string, object>();
query.Add("areaCode", "805");
query.Add("quantity", 3);
var result = await AvailableNumbers.List(_client, query);
foreach (string number in result.TelephoneNumberList)
{
    Console.WriteLine(string.Format("Number: {0}", number));
}

Cities

var query = new Dictionary<string, object>();
query.Add("state", "CA");
query.Add("available", true);
var result = await City.List(_client, query);
foreach (City city in result)
{
    Console.WriteLine("City Name: {0}", city.Name);
}

Rate Centers

var query = new Dictionary<string, object>();
query.Add("state", "CA");
query.Add("available", true);
var result = await RateCenter.List(query);
foreach (RateCenter rateCenter in result)
{
    Console.WriteLine("RateCenter Name: {0}", rateCenter.Name);
}

Covered Rate Centers

var query = new Dictionary<string, object>();
query.Add("zip", "27609");
var result = await CoveredRateCenter.List(_client, query);
foreach (CoveredRateCenter rateCenter in result)
{
    Console.WriteLine("RateCenter Name: {0}", rateCenter.Name);
}

Orders

Create Order

var result = await Order.Create(_client, new Order
{
    Name = "Test Order",
    SiteId = "SiteId",
    CustomerOrderId = "SomeCustomerId",
    LataSearchAndOrderType = new LataSearchAndOrderType
    {
        Lata = "224",
        Quantity = 1
    }
});

Get Order

var order = await Order.Get("orderId");

Order Instance Methods

order.Update()
order.AddNote(var note);
order.GetNotes();
order.GetAreaCodes();
order.GetNpaNxx();
order.GetTotals();
order.GetTns();
order.GetHistory();

List Orders

var query = new Dictionary<string, object>();
query.Add("page", "1");
query.Add("size", "10");
query.Add("zip", "27516");

OrderListResponse orderListResponse = await Order.List(client, query);

OrderListResponse

orderListResponse.Orders.TotalCount;
orderListResponse.Orders.Links.First;
orderListResponse.Orders.Links.Next;
orderListResponse.Orders.Links.Last;
orderListResponse.Orders.OrderDetails.Count;
orderListResponse.Orders.OrderDetails[0].CountOfTns;
orderListResponse.Orders.OrderDetails[0].OrderStatus;
orderListResponse.Orders.OrderDetails[0].OrderId;
orderListResponse.Orders.OrderDetails[0].LastModifiedDate;
orderListResponse.Orders.OrderDetails[0].OrderDate;
orderListResponse.Orders.OrderDetails[0].UserId;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.States.Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.States[0].Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.States[0].State;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.RateCenters.Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.RateCenters[0].Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.RateCenters[0].RateCenter;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Cities.Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Cities[0].Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Cities[0].City;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Tiers.Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Tiers[0].Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Tiers[0].Tier;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Vendors.Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Vendors[0].Count;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Vendors[0].VendorId;
orderListResponse.Orders.OrderDetails[0].TelephoneNumberDetailsWithCount.Vendors[0].VendorName;

Applications

Create Application

var application = new Application
{
    ApplicationId = "d3e418e9-1833-49c1-b6c7-ca1700f79586",
    ServiceType = "Voice-V2",
    AppName = "v1",
    CallbackCreds = new CallbackCreds
    {
        UserId = "login123"
    },
    CallStatusMethod = "GET",
    CallInitiatedMethod = "GET",
    CallInitiatedCallbackUrl = "https://a.com",
    CallStatusCallbackUrl = "https://b.com"
};

var response = await Application.Create(client, application);

List Applications

var response = await Application.List(client);

Get Application

var response = await Application.Get(client, applicationId);

Partial Update Application

var application = new Application
{
    AppName = "XgRIdP"
};

var response = await Application.PartialUpdate(client, applicationId, application);

Full Update Application

var application = new Application
{
    ServiceType = "Voice-V2",
    AppName = "v1",
    CallbackCreds = new CallbackCreds
    {
        UserId = "login123"
    },
    CallStatusMethod = "GET",
    CallInitiatedMethod = "GET",
    CallInitiatedCallbackUrl = "https://a.com",
    CallStatusCallbackUrl = "https://b.com"
};

var response = await Application.FullUpdate(client, applicationId, application);

Delete Application

var response = await Application.Delete(client, applicationId);

List Application's Associated Peers

var response = await Application.ListAssociatedSippeers(client, applicationId);

Port Ins

Port In Check

For LNP Checker, send one number at a time when using the C# SDK.

Example request and error handling iterating over each error in the response.

try
{
    var result = await LnpChecker.Check(client, new string[] { "555555" });
    Console.WriteLine(result);
}
catch (Bandwidth.Iris.BandwidthIrisException error)
{
    Console.WriteLine(error.Message);
}
catch (Exception e)
{
    Exception innerEx = e;

    while(innerEx != null)
    {
        string msg = innerEx.Message;
        Console.WriteLine(msg);
        innerEx = innerEx.InnerException;
    }
}

Create PortIn

var data = new PortIn
    {
        BillingTelephoneNumber = "+1-202-555-0158",
        Subscriber = new Subscriber
            {
                SubscriberType = "BUSINESS",
                BusinessName = "Company",
                FirstName = "John",
		LastName = "Doe",
                ServiceAddress = new Address
                    {
                        City = "City",
                        StateCode = "State",
                        Country = "Country"
                    }
            },
        PeerId = sipPeer.Id,
        SiteId = site.Id
    };
var order = await PortIn.Create(_client, data);

Get PortIn

var portInOrder = PortIn.Get("orderId");

Put File Metadata

var portIn = new PortIn { Id = "1" };
portIn.SetClient(client);

var fileMetadata = new FileMetadata {
	DocumentType = "INVOICE",
	DocumentName = "docName"
};

var r = portIn.PutFileMetadata("test", fileMetadata).Result;

PortIn Instance Methods

portInOrder.Update();
portInOrder.Delete();
portInOrder.AddNote(Note n);
portInOrder.GetNotes();

Port In LOA Management

portInOrder.CreateFile(Stream s, string mediaType);
portInOrder.CreateFile(byte[] buffer, string mediaType);
portInOrder.UpdateFile(string fileName, Stream s, string mediaType);
portInOrder.UpdateFile(string fileName, byte[] buffer, string mediaType);
portInOrder.GetFileMetaData(string fileName);
PutFileMetadata(string fileName, FileMetadata fileMetadata);
portInOrder.DeleteFile(string fileName);
portInOrder.GetFiles(bool metaData);
portInOrder.GetFile(string fileName);

Sites

Create Site

var newSite = await Site.Create(_client, new Site()
  {
      Name = "Csharp Test Site",
      Description = "A site from the C# Example",
      Address = new Address()
          {
              HouseNumber = "123",
              StreetName = "Anywhere St",
              City = "Raleigh",
              StateCode = "NC",
              Zip = "27609",
              AddressType = "Service"
          }

  });

List all sites

var sites = awaite Site.List();

Deleting a Site

site.Delete();

Sip Peers

Create a Sip Peer

var sipPeerHost = "1.2.3.4";
var newSipPeer = await SipPeer.Create(_client, new SipPeer()
    {
        IsDefaultPeer = true,
        ShortMessagingProtocol = "SMPP",
        SiteId = "SiteId,
        VoiceHosts = new []
            {
                new HostData
                    {
                        HostName = sipPeerHost
                    }
            },
        SmsHosts = new []
            {
                new HostData
                    {
                        HostName = sipPeerHost
                    }
            },
        TerminationHosts = new TerminationHost[]
            {
                new TerminationHost()
                    {
                        HostName = sipPeerHost,
                        Port = 5060
                    }
            }

    });

Get Sip Peer

var sipPeer = await SipPeer.Get("sipPeerId");

Delete Sip Peer

var sipPeer = await SipPeer.Get("sipPeerId");
sipPeer.Delete();

Sip Peer TN Methods

sipPeer.GetTn(number);
sipPeer.UpdateTns(number, data);
sipPeer.MoveTns(new string[] numbers);

Get Origination Settings for Sip Peer

var sipPeerOriginationSettingsResponse = await SipPeer.GetOriginationSettings(siteId, sipPeerId);

Set Origination Settings for Sip Peer

var sipPeerOriginationSettings = new SipPeerOriginationSettings
{
    VoiceProtocol = "HTTP",
    HttpSettings = new HttpSettings
    {
        HttpVoiceV2AppId = "469ebbac-4459-4d98-bc19-a038960e787f"
    }
};

var sipPeerOriginationSettingsResponse = await SipPeer.SetOriginationSettings(siteId, sipPeerId, sipPeerOriginationSettings);

Update Origination Settings for Sip Peer

var sipPeerOriginationSettings = new SipPeerOriginationSettings
{
    VoiceProtocol = "HTTP",
    HttpSettings = new HttpSettings
    {
        HttpVoiceV2AppId = "469ebbac-4459-4d98-bc19-a038960e787f"
    }
};

SipPeer.UpdateOriginationSettings(siteId, sipPeerId, SipPeerOriginationSettings).Wait();

Get Termination Settings for Sip Peer

var sipPeerTerminationSettingsResponse = await SipPeer.GetTerminationSetting(siteId, sipPeerId);

Set Termination Settings for Sip Peer

var sipPeerTerminationSettings = new SipPeerTerminationSettings
{
    VoiceProtocol = "HTTP",
    HttpSettings = new HttpSettings
    {
        HttpVoiceV2AppId = "469ebbac-4459-4d98-bc19-a038960e787f"
    }
};

var sipPeerTerminationSettingsResponse = await SipPeer.GetTerminationSetting(siteId, sipPeerId, sipPeerTerminationSettings);

Update Termination Settings for Sip Peer

var sipPeerTerminationSettings = new SipPeerTerminationSettings
{
    VoiceProtocol = "HTTP",
    HttpSettings = new HttpSettings
    {
        HttpVoiceV2AppId = "469ebbac-4459-4d98-bc19-a038960e787f"
    }
};

SipPeer.UpdateTerminationSettings(client, siteId, sipPeerId, SipPeerTerminationSettings).Wait();

Get SMS Feature Settings for Sip Peer

var sipPeerSmsFeatureResponse = await SipPeer.GetSMSSetting(siteId, sipPeerId);

Set SMS Feature Setting for Sip Peer

var sipPeerSmsFeature = new SipPeerSmsFeature
{
    SipPeerSmsFeatureSettings = new SipPeerSmsFeatureSettings
    {
        TollFree = true
    },
    SmppHosts = new SmppHost[]
    {
        new SmppHost
        {
            HostName = "Host"
        }
    }
};

var sipPeerSmsFeatureResponse = await SipPeer.CreateSMSSettings(siteId, sipPeerId, sipPeerSmsFeature);

Update SMS Feature Setting for Sip Peer

var sipPeerSmsFeature = new SipPeerSmsFeature
{
    SipPeerSmsFeatureSettings = new SipPeerSmsFeatureSettings
    {
        TollFree = true
    },
    SmppHosts = new SmppHost[]
    {
        new SmppHost
        {
            HostName = "Host"
        }
    }
};

var sipPeerSmsFeatureResponse = await SipPeer.UpdateSMSSettings(siteId, sipPeerId, sipPeerSmsFeature);

Delete SMS Feature Settings for Sip Peer

SipPeer.DeleteSMSSettings(siteId, sipPeerId).Wait();

Get MMS Feature Settings for Sip Peer

var MmsFeatureResponse = await SipPeer.GetMMSSetting(siteId, sipPeerId);

Set MMS Feature Setting for Sip Peer

var mmsFeature = new MmsFeature
{
    Protocols = new Protocols
    {
        MM4 = new MM4
        {
            Tls = "OFF"
        }
    }
};

var MmsFeatureResponse = await SipPeer.CreateMMSSettings(siteId, sipPeerId, mmsFeature);

Update MMS Feature Setting for Sip Peer

var mmsFeature = new MmsFeature
{
    Protocols = new Protocols
    {
        MM4 = new MM4
        {
            Tls = "OFF"
        }
    }
};

SipPeer.UpdateMMSSettings(siteId, sipPeerId, MmsFeature).Wait();

Delete MMS Feature Settings for Sip Peer

SipPeer.DeleteMMSSettings(siteId, sipPeerId).Wait();

Get Application Settings

var applicationsSettingsResponse = await SipPeer.GetApplicationSetting(siteId, sipPeerId);

Update Application Settings

var applicationSettings = new ApplicationsSettings
{
    HttpMessagingV2AppId = "c3b0f805-06ab-4d36-8bf4-8baff7623398"
};

SipPeer.UpdateApplicationSettings(siteId, sipPeerId, applicationSettings).Wait();

Remove Application Settings

SipPeer.RemoveApplicationSettings(siteId, sipPeerId).Wait();

Subscriptions

Create Subscription

var subscription = await Subscription.Create(new Subscription()
{
    OrderType = "orders",
    OrderId = "100",
    EmailSubscription = new EmailSubscription
    {
        Email = "test@test",
        DigestRequested = "NONE"
    }
};

Get Subscription

var subscription = await Subscription.Get("subscriptionId");

List Subscriptions

var list = await Subscription.List(new Dictionary<string,object>{{"orderType", "orders"}})

Subscription Instance Methods

subscription.Update();
subscription.Delete();

TNs

Get TN Details

var result = await Tn.Get("9195551212");
var details = await result.GetDetails();

List TNs

var result = await Tn.List(new Dictionary<string, object>{{{"npa", "919"}})

TN Reservation

Create TN Reservation

var item = await TnReservation.Create(new TnReservation()
{
    AccountId = "accountId",
    ReservedTn = "9195551212",
    ReservationExpires = 0
};

Get TN Reservation

var reservation = await TnReservation.Get("Id");

Delete TN Reservation

reservation.Delete();

Dlda

Create Ddla

var dlda = new Dlda
            {
                CustomerOrderId = "Your Order Id",
                DldaTnGroups = new[]{
                new DldaTnGroup{
                  TelephoneNumbers  =  new TelephoneNumbers {Numbers =  new[]{"9195551212"}},
                  SubscriberType  =  "RESIDENTIAL",
                  ListingType  =  "LISTED",
                  ListingName  =  new ListingName{
                    FirstName  =  "John",
                    LastName  =  "Smith"
                  },
                  ListAddress  =  true,
                  Address  =  new Address{
                    HouseNumber  =  "123",
                    StreetName  =  "Elm",
                    StreetSuffix  =  "Ave",
                    City  =  "Carpinteria",
                    StateCode  =  "CA",
                    Zip  =  "93013",
                    AddressType  =  "DLDA"
                  }
                }
              }
            };

await Dlda.Create(dlda);

Get Dlda

var dlda = await Dlda.Get(id);

Get Dlda History

var list = await Dlda.GetHistory();

Lidb

Create

var item = new Lidb
    {
        CustomerOrderId = "A Test order",
        LidbTnGroups = new[] {
            new LidbTnGroup{
                TelephoneNumbers = new []{"8048030097", "8045030098"},
                SubscriberInformation = "Joes Grarage",
                UseType = "RESIDENTIAL",
                Visibility = "PUBLIC"
            }
        }
    };
await Lidb.Create(item);

Get Lidb

var item = await Lidb.Get(id);

List Lidbs

var list = await Lidb.List();

LineOptionOrder

Create an order

var item = new TnLineOptions
{
    TelephoneNumber = "5209072451",
    CallingNameDisplay = "off"
};
var numbers = await LineOptionOrder.Create(item);

InServiceNumber

List

var list = await InServiceNumber.List(new Dictionary<string, object>{{"city", "Cary"}});

Get totals

var totals = await InServiceNumber.GetTotals();

DiscNumber

List numbers

var list = await DiscNumber.List(new Dictionary<string, object>{{"type", "NPA"}});

Get totals

var totals = await DiscNumber.GetTotals();

Host

List hosts

var list = await Host.List(new Dictionary<string,object>{{"type", "SMS"}});

ImportTnOrders

Create A ImportTnOrders Reqeust

var order = new ImportTnOrder
    {
        OrderId = "fbd17609-be44-48e7-a301-90bd6cf42248",
        AccountId = "account",
        SipPeerId = 1,
        SiteId = 2
    };

var response = await ImportTnOrder.Create(client, order);

Retrieve ImportOrders List

var response = await ImportTnOrder.List(client, new Dictionary<string, object> { { "accountId", "1" } });

Get ImportOrder by OrderId

var response = await ImportTnOrder.Get(client, orderId);

Get ImportOrder History by OrderId

var response = await ImportTnOrder.GetHistory(client, orderId )

RemoveImportedTnOrders

Create A ImportTnOrders Reqeust

var order = new RemoveImportedTnOrder
    {
        OrderId = "fbd17609-be44-48e7-a301-90bd6cf42248",
        AccountId = "account"
    };

var response = await RemoveImportedTnOrder.Create(client, order);

Retrieve RemoveImportedTnOrders List

var response = await RemoveImportedTnOrder.List(client, new Dictionary<string, object> { { "accountId", "1" } });

Get RemoveImportedTnOrder by OrderId

var response = await RemoveImportedTnOrder.Get(client, orderId);

Get RemoveImportedTnOrder History by OrderId

var response = await RemoveImportedTnOrder.GetHistory(client, orderId )

ImportTnChecker

Request Portability Information on a Set of TNs

var payload = new ImportTnCheckerPayload
{
    TelephoneNumbers = new TelephoneNumber[]
    {
        new TelephoneNumber
        {
            FullNumber = "3032281000"
        }
    }
};

var response = await ImportTnChecker.Create(client, payload);

Csrs

Create Csrs Order

var csr = new Csr
{
    AccountId =  "accountId"
    //Additional information
};

var response = await Csr.Create(client, csr);

Get Csr Order

var response = await Csr.Get(client, orderId);

Replace Csr Order

var csr = new Csr
{
    AccountId =  "new accountId"
    //Additional information
};

var response = await Csr.Replace(client, orderId, csr);

List Notes on Csr Order

var response = await Csr.ListNotes(client, orderId);

Create Note on Csr Order

var note = new Note
{
    Description = "Description goes here"
};

Csr.CreateNote(client, orderId, note);

Update Note on Csr Order

var note = new Note
{
    Description = "Updated description goes here"
};

Csr.UpdateNote(client, orderId, noteId, note);

Emergency Notifications

Get Recipients

var result = await EmergencyNotification.GetRecipients(client, orderId);

List Recipients

var result = await EmergencyNotification.ListRecipients(client, new Dictionary<string, Object>
{
    {"EnrNotificationType", "SMS" }
});

Create Recipients

var result = await EmergencyNotification.CreateRecipients(client, new EmergencyNotificationRecipient
{
    ModifiedByUser = "testuser",
    Type = "EMAIL",
    EmailAddress = "[email protected]"
});

Update Recipients

var result = await EmergencyNotification.UpdateRecipients(client, id, new EmergencyNotificationRecipient
{
    ModifiedByUser = "testuser",
    Type = "EMAIL",
    EmailAddress = "[email protected]"
});

Delete Recipients

EmergencyNotification.DeleteRecipients(client, id).Wait();

Get Group Orders

var result = await EmergencyNotification.GetGroupOrders(client, id);

List Group Orders

var result = await EmergencyNotification.ListGroupOrders(client, new Dictionary<string, Object>
{
    {"EnrNotificationType", "TTS" }
});

Create Group Order

var result = await EmergencyNotification.CreateGroupOrders(client, new EmergencyNotificationGroupOrder
{
    CustomerOrderId = "test",
    AddedEmergencyNotificationGroup = new EmergencyNotificationGroup
    {
        CreatedBy = "samwise"
    }
});

Get Groups

var result = await EmergencyNotification.GetGroups(client, id);

List Groups

var result = await EmergencyNotification.ListGroups(client, new Dictionary<string, Object>
{
    {"EnrDetails", "true" },
    {"EnrEmailAddress", "[email protected]" }
});

Get Endpoint Order

var result = await EmergencyNotification.GetEndpointOrders(client, id);

List Endpoint Orders

var result = await EmergencyNotification.ListEndpointOrders(client, new Dictionary<string, Object>
{
    {"EepTns", "404" }
});

Create Endpoint Order

var result = await EmergencyNotification.CreateEndpointOrders(client, endpointOrder);

Aeuis

Get Aeui

var response = await Aeui.Get(client, id);

List Aeui

var response = await Aeui.List(client);

TN Options

Create TN Option

Create TN Option order(s) to assign line features to the telephone number

Add PortOutPasscode

var order = new TnOptionOrder
{
    CustomerOrderId = "customerOrderId",
    TnOptionGroups = new List<TnOptionGroup>
    {
        new TnOptionGroup {
            PortOutPasscode = "a1b2c3",
            TelephoneNumbers = new List<string>
            {
                "2018551020",
                "2018551025"
            }
        }
    }
};

var result = await TnOptions.Create(client, order);

Enable SMS

var order = new TnOptionOrder
{
    CustomerOrderId = "customerOrderId",
    TnOptionGroups = new List<TnOptionGroup>
    {
        new TnOptionGroup {
            Sms = "on",
            TelephoneNumbers = new List<string>
            {
                "2018551020",
                "2018551025"
            }
        }
    }
};

var result = await TnOptions.Create(client, order);

Add CallForward Number

var order = new TnOptionOrder
{
    CustomerOrderId = "customerOrderId",
    TnOptionGroups = new List<TnOptionGroup>
    {
        new TnOptionGroup {
            CallForward = "6042661720",
            TelephoneNumbers = new List<string>
            {
                "2018551020",
                "2018551025"
            }
        }
    }
};

var result = await TnOptions.Create(client, order);

Get Tn Option Order

Get Tn Option Order (No Error)

TnOptionOrder response = null;
try{
response = await TnOptions.Get(client, orderId);
} catch (Exception ex) {
    //No error thrown
}

Console.WriteLine(response.OrderCreateDate); //"2016-01-15T11:22:58.789Z"

Get Tn Option Order (With Error)

TnOptionOrder response = null;
try{
    response = await TnOptions.Get(client, orderId);
} catch (Exception ex) {
    if (ex.InnerException is BandwidthIrisException)
    {
        var exInner = (BandwidthIrisException)ex.InnerException;
        Console.WriteLine(exInner.Message); //"Telephone number is not available"
        Console.WriteLine(exInner.Body); // <TnOptionOrders><TotalCount>2</TotalCount><TnOptionOrder>..........</TnOptionOrder></TnOptionOrders>
    } 
}

List Tn Option Orders

var result = await TnOptions.List(client, new Dictionary<string, Object>
    {
        {"status", "9199918388" }
    });

csharp-bandwidth-iris's People

Contributors

ajrice6713 avatar avbel avatar bwdan avatar ckoegel avatar hamermike avatar jchavez443 avatar jgozner avatar jmulford-bw avatar juliajanu avatar matthewkmartin avatar scottbarstow avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csharp-bandwidth-iris's Issues

[BUG] AllowAutoRedirect should be false

Checklist

  • Have you provided a description of the bug?
  • Have you provided your Environment information?
  • Have you provided a sample code snippet?
  • Have you provided a stack trace?
  • Have you outlined the expected behavior?

Description

I'm calling InServiceNumber.List(client) without specifying any parameter. In this API, Bandwidth return Redirect 303, but with AllowAutoRedirect = true, Client will auto redirect to the Location header in the 303 response without adding Authorization header then it lead to 401 Unauthorized response.

AllowAutoRedirect should be set to false, redirect response would already be handled in Client.MakeGetRequest()
if (response.StatusCode == HttpStatusCode.RedirectMethod)

Environment Information

  • OS Version: Mac M1
  • SDK Version: 4.0.1
  • Environment: .NET 6

Sample Code Snippet

private HttpClient CreateHttpClient()
    {
      UriBuilder uriBuilder = new UriBuilder(this._apiEndpoint)
      {
        Path = string.Format("/{0}/", (object) this._apiVersion)
      };
      HttpClient httpClient = new HttpClient((HttpMessageHandler) new HttpClientHandler()
      {
        AllowAutoRedirect = true,
      });
      httpClient.BaseAddress = uriBuilder.Uri;
      httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", (object) this._userName, (object) this._password))));
      httpClient.DefaultRequestHeaders.Add("User-Agent", Client.USER_AGENT);
      return httpClient;
    }

Stack Trace

Bandwidth.Iris.BandwidthIrisException: Http code Unauthorized
   at Bandwidth.Iris.Client.MakeGetRequest(String path, IDictionary`2 query, String id, Boolean disposeResponse)
   at Bandwidth.Iris.Client.MakeGetRequest[TResult](String path, IDictionary`2 query, String id)
   at Bandwidth.Iris.Model.InServiceNumber.List(Client client, IDictionary`2 query)

Expected Behavior

Add Authorization into redirect request

Suggested Fix

Set AllowAutoRedirect = false like it was before https://github.com/Bandwidth/csharp-bandwidth-iris/pull/45/commits merged

TnReservation does not support multiple TN reservations

var item = await TnReservation.Create(new TnReservation()
{
AccountId = "accountId",
ReservedTn = "9195551212",
ReservationExpires = 0
};

Am I correct in thinking the TnReservation does not support the passing of an array of numbers to reserve? The API appears to support this.

So in the situation where the end user retrieves 20 numbers and wants to reserve and order 'All' - we would need to call this 20 times?

[BUG] No OrderId is returned when using the Lidb class

Checklist

  • Have you provided a description of the bug?
  • Have you provided your Environment information?
  • Have you provided a sample code snippet?
  • Have you provided a stack trace?
  • Have you outlined the expected behavior?

Description

No OrderId property is returned when using the Lidb class. This was initially discovered using Lidb.Create() method, but the same behavior occurs with Lidb.Get();

bandwidth-bug

Environment Information

  • OS Version: macOS Ventura 13.2.1
  • SDK Version: 6.0.0
  • Environment: .NET Core 6.0

Sample Code Snippet

Any regular call to Lidb should reproduce the error:

var result = await Lidb.Create(Client, new Lidb
{
    CustomerOrderId = "<any-customer-order-id>",
    LidbTnGroups = new LidbTnGroup[]
    {
        new()
        {
            TelephoneNumbers = new[]
            {
               "<any-tn>" 
            },
            SubscriberInformation = "<any-sub-info>",
            UseType = "RESIDENTIAL", 
            Visibility = "PUBLIC" 
        }
    }
});

or

var result = await Lidb.Get(Client, "<order-id>");

Stack Trace

This bug does not throw an error or exception.

Expected Behavior

The API call from Postman returns the orderId correctly, as shown:

Screenshot 2023-11-29 at 10 49 13 AM

Lidb class should mirror this behavior.

Suggested Fix

Going through the code, one can see that Lidb's orderId has a potential issue regarding case sensitivity. In the API result shown above, OrderId is returned in PascalCase, not camelCase. Removing the annotation might solve this.

Screenshot 2023-11-29 at 10 56 01 AM

ExistingTelephoneNumberOrderType and Reservation support

When using reserved TNs there is an additional possible element in this type called ReservationIdList. See example:
<Order> <Name>Available Telephone Number order</Name> <SiteId>385</SiteId> <CustomerOrderId>123456789</CustomerOrderId> <ExistingTelephoneNumberOrderType> <TelephoneNumberList> <TelephoneNumber>9193752369</TelephoneNumber> <TelephoneNumber>9193752720</TelephoneNumber> <TelephoneNumber>9193752648</TelephoneNumber> </TelephoneNumberList> <ReservationIdList> <ReservationId>[GUID]</ReservationId> <ReservationId>[GUID]</ReservationId> </ReservationIdList> </ExistingTelephoneNumberOrderType> </Order>

[BUG] Callback Subscription Expiry overflows int32

Checklist

  • Have you provided a description of the bug?
  • Have you provided a stack trace?
  • Have you outlined the expected behavior?

Description

I've created some new subscriptions in the Dashboard that were set to never expire. When listing subscriptions using the C# SDK I now encounter a deserialization error:

Calling the Subscriptions API directly with Postman, I see the new subscription:

<Subscription>
    <SubscriptionId>d0fe3a5f-d63a-4c4d-839d-7eb1c626666d</SubscriptionId>
    <OrderType>portins</OrderType>
    <CallbackSubscription>
        <URL>https://my.site/bandwidth/portins</URL>
        <Expiry>3153283188</Expiry>
        <Status>200 OK - </Status>
    </CallbackSubscription>
</Subscription>

Given that expiry value and running in DotNetFiddle you can see it throws the same expection: https://dotnetfiddle.net/nEDIpX

Stack Trace

System.InvalidOperationException: There is an error in XML document (1, 4528). ---> System.OverflowException: Value was either too large or too small for an Int32.
   at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSubscriptionsResponse.Read4_CallbackSubscription(bool isNullable, bool checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSubscriptionsResponse.Read5_Subscription(bool isNullable, bool checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSubscriptionsResponse.Read6_SubscriptionsResponse(bool isNullable, bool checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderSubscriptionsResponse.Read7_SubscriptionsResponse()   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, string encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
   at Bandwidth.Iris.Client+<MakeGetRequest>d__16<TResult>.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Bandwidth.Iris.Model.Subscription+<List>d__3.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult()

Expected Behavior

Enumerating shouldn't fail

Suggested Fix

Change CallbackSubscription from int32 to int64

Actual response from Lnp check

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><NumberPortabilityResponse><PortableNumbers><Tn>9195551212</Tn><Tn>9195551213</Tn></PortableNumbers><SupportedRateCenters><RateCenterGroup><RateCenter>RALEIGH</RateCenter><City>RALEIGH</City><State>NC</State><LATA>426</LATA><Tiers><Tier>0</Tier></Tiers><TnList><Tn>9195551212</Tn><Tn>9195551213</Tn></TnList></RateCenterGroup></SupportedRateCenters><UnsupportedRateCenters/><SupportedLosingCarriers><LosingCarrierTnList><LosingCarrierSPID>6214</LosingCarrierSPID><LosingCarrierName>Cingular</LosingCarrierName><TnList><Tn>9195551212</Tn><Tn>9195551213</Tn></TnList></LosingCarrierTnList></SupportedLosingCarriers><UnsupportedLosingCarriers/></NumberPortabilityResponse>

Note the additional undocumented elements

[BUG] ImportTnCheckerPayload has missing SiteId and SipPeerId parameters, and produces XML that doesn't conform API documentation

Checklist

  • Have you provided a description of the bug?
  • Have you provided your Environment information?
  • Have you provided a sample code snippet?
  • Have you provided a stack trace?
  • Have you outlined the expected behavior?

Description

ImportTnChecker model do not match API documentation. As a result, 400 Bad Request is returned by api/accounts/{accountId}/importTnChecker API endpoint.
Specifically, there are two issues:

  1. SiteId and SipPeerId parameters are missing in ImportTnCheckerPayload class
  2. TelephoneNumbers array is being serialized in a way that doesn't match API documentation. This in turn prevents API from recognizing numbers client is sending.

Environment Information

  • OS Version: Windows 10
  • SDK Version: 3.1.0
  • Environment: .NET Core 6.0

Sample Code Snippet

            var checkerRequest = new ImportTnCheckerPayload
            {
                TelephoneNumbers = new TelephoneNumber[]
                {
                    new TelephoneNumber
                    {
                        FullNumber = "5105551122"
                    }
                },
            };

            var xmlSerializer = new XmlSerializer(checkerRequest.GetType());
            using Utf8StringWriter writer = new Utf8StringWriter();
            xmlSerializer.Serialize(writer, checkerRequest);
            string content = writer.ToString();

Expected Behavior

API documentation at https://dev.bandwidth.com/docs/numbers/guides/hostingNumbers/ suggests that expected request format is:

<ImportTnCheckerPayload>
    <TelephoneNumbers>
        <TelephoneNumber>3032281000</TelephoneNumber>
        <TelephoneNumber>4109235436</TelephoneNumber>
        <TelephoneNumber>4104685864</TelephoneNumber>
    </TelephoneNumbers>
    <SiteId>486</SiteId>
    <SipPeerId>500025</SipPeerId>
</ImportTnCheckerPayload>

Actual behavior

The payload being produced by XmlSerializer off the defined model classes is:

<ImportTnCheckerPayload>
  <TelephoneNumbers>
    <TelephoneNumber>
      <FullNumber>5105551122</FullNumber>
    </TelephoneNumber>
  </TelephoneNumbers>
</ImportTnCheckerPayload>

Notice extra FullNumber element.

Suggested Fix

  1. Fix XML serialization hints for TelephoneNumbers .
  2. Add SiteId and SipPeerId properties
    public class ImportTnCheckerPayload
    {
        public string SiteId { get; set; } 
        public string SipPeerId { get; set; }
        [XmlArray("TelephoneNumbers")]
        [XmlArrayItem("TelephoneNumber")]
        public string[] TelephoneNumbers { get; set; }

        [XmlArray("ImportTnErrors")]
        [XmlArrayItem("ImportTnError")]
        public ImportTnError[] ImportTnErrors { get; set; }
    }

PeerId missing from `Order.Create`

Perhaps this is the wrong forum for this type of question but here goes anyway.

Playing with the C# iris SDK. The Order.Create seems to lack PeerId

var result = await Bandwidth.Iris.Model.Order.Create(client, new Bandwidth.Iris.Model.Order
{
      Name = "Test Order",
      SiteId = "1234",
      PeerId = "5626",
      CustomerOrderId = "",
       LataSearchAndOrderType = new LataSearchAndOrderType
      {
          Lata = "224",
          Quantity = 1
       }
});

PeerId is not defined in Order.Create? Curious why that restriction exists.

Also if I do submit the order above, to the correct SiteId & without the peerid, the call is successful but no number is added. And the response seems to imply that NULL was passed as the LATA

{
  "order": {
    "id": "e3702599-d3e8-4104-9f30-6bdc30aefb50",
    "orderId": "e3702599-d3e8-4104-9f30-6bdc30aefb50",
    "name": "Test Order",
    "siteId": "****",
    "backOrderRequested": false,
    "orderCreateDate": "2018-02-21T17:38:56.285Z",
    "customerOrderId": "",
    "partialAllowed": true,
    "closeOrder": false,
    "existingTelephoneNumberOrderType": null,
    "areaCodeSearchAndOrderType": null,
    "rateCenterSearchAndOrderType": null,
    "npaNxxSearchAndOrderType": null,
    "tollFreeVanitySearchAndOrderType": null,
    "tollFreeWildCharSearchAndOrderType": null,
    "stateSearchAndOrderType": null,
    "citySearchAndOrderType": null,
    "zipSearchAndOrderType": null,
    "lataSearchAndOrderType": {
      "lata": null,
      "quantity": 1
    }
  },
  "createdByUser": null,
  "completedQuantity": 0,
  "failedQuantity": 0,
  "pendingQuantity": 0,
  "orderCompleteDate": "0001-01-01T00:00:00",
  "orderStatus": "RECEIVED",
  "completedNumbers": null
}

If I search for the order on the dashboard - no order is found.

Make public modifier to Client class endpoint methods

Is it possible to make modifiers internal to public for get, post, etc. methods? This will allow implementing models that are not yet in this repository (for example, e911order), but the user needs them. As a result, when the model is ready, clients will be able to make a pull request to this repository, and not fork this repository.
If you don't mind, then I'll make an pull request. Thank you.

[BUG] De-serialization of null Tn dates

Checklist

  • Have you provided a description of the bug?
  • Have you provided your Environment information?
  • Have you provided a sample code snippet?
  • Have you provided a stack trace?
  • Have you outlined the expected behavior?

Description

Deserialization of Tns will fail if a datetime from Bandwidth is not provided.

Environment Information

  • OS Version: macOs Ventura 13.4
  • SDK Version: 5.0
  • Environment: .NET Core 6.0

Sample Code Snippet

Calling Bandwidth.Iris.Model.Tn.Get(client, phoneNumber)

Text response from api:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TelephoneNumberResponse>
  <TelephoneNumber>{phoneNumber}</TelephoneNumber>
  <Status>Inservice</Status>
  <LastModifiedDate/>
  <OrderCreateDate>2023-08-18T15:00:27.382Z</OrderCreateDate>
  <OrderId>{orderId}</OrderId>
  <OrderType>IMPORT_TN_ORDERS</OrderType>
  <InServiceDate>2023-08-18T15:00:28.175Z</InServiceDate>
  <SiteId>{siteId}</SiteId>
  <AccountId>{accountId}</AccountId>
</TelephoneNumberResponse>

Fails at Bandwidth.Iris.Client.MakeGetRequest(path, query, id):

XmlSerializer xmlSerializer = new XmlSerializer(typeof (TResult));
return stream.Length > 0L ? (TResult) xmlSerializer.Deserialize(stream) : default (TResult);

Stack Trace

System.InvalidOperationException: There is an error in XML document (1, 190).
 ---> System.FormatException: The string '' is not a valid AllXsd value.
   at System.Xml.XmlConvert.ToDateTime(String s, XmlDateTimeSerializationMode dateTimeOption)
   at System.Xml.Serialization.XmlCustomFormatter.ToDateTime(String value)
   at System.Xml.Serialization.XmlSerializationReader.ToDateTime(String value)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderTn.Read2_Tn(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderTn.Read3_TelephoneNumberResponse()
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
   at Bandwidth.Iris.Client.MakeGetRequest[TResult](String path, IDictionary`2 query, String id)
   at Bandwidth.Iris.Model.Tn.Get(Client client, String number)

Expected Behavior

The telephone number is de-serialized with a null LastModifiedDate.

Suggested Fix

Make the datetime fields nullable.

LnpChecker Updates `/accounts/{accountId}/lnpchecker`

There is a mismatch between the API and SDK. The SDK has a PortType property while the SDK doesn't.
The NumberPortabilityResponse class of the SDK is out of date compare to the response the returns:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<NumberPortabilityResponse>
  <PortType>INTERNAL</PortType>
  <PortableNumbers>
    <Tn>3154500246</Tn>
  </PortableNumbers>
  <SupportedRateCenters>
    <RateCenterGroup>
      <RateCenter>SYRACUSE</RateCenter>
      <City>SYRACUSE</City>
      <State>NY</State>
      <LATA>136</LATA>
      <Tiers>
        <Tier>0</Tier>
      </Tiers>
      <TnList>
        <Tn>3154500246</Tn>
      </TnList>
    </RateCenterGroup>
  </SupportedRateCenters>
  <UnsupportedRateCenters/>
</NumberPortabilityResponse>

See the docs for under POST /accounts/{accountId}/lnpchecker

The NumberPortabilityResponse class has the structure which is

public class NumberPortabilityResponse 
{ 
  public NumberPortabilityResponse();
  public RateCenterGroup[] SupportedRateCenters { get; set; } 
  public RateCenterGroup[] UnsupportedRateCenters { get; set; } 
  public RateCenterGroup[] PartnerSupportedRateCenters { get; set; } 
  [XmlArrayItem("Tn")] 
  public string[] PortableNumbers { get; set; } 
  public LosingCarriers SupportedLosingCarriers { get; set; } 
  public LosingCarriers UnsupportedLosingCarriers { get; set; } 
}

Is it any reason for that? if so, Is there anyway I can get the PortType property's value with the SDK?

Missing elements in LnpOrderResponse

Check the documentation. There are additional elements not in the request that are in the response. Also, things like ProcessingStatus are not in the response, only in the request

Section 12

Need to code section 12 of the API doc: Managing Orders

MANUAL_TOLLFREE needs added to PortType (and maybe some others)

After submitting an initial bulk port request in a DRAFT status with tollfree numbers, I perform a GetOrder() on the first generated portin order ID and I get the following exception when the object is cast to an LnpOrderResponse "Instance validation error: 'MANUAL_TOLLFREE' is not a valid value for PortType.". I added MANUAL_TOLLFREE to the PortType enum and it's working now. I haven't fully tested porting a toll free number in production, so I'm not sure if it's actually a valid value. But I think it's safe to say that MANUAL_TOLLFREE is a newer valid PortType. Out of the existing three (AUTOMATED, INTERNAL, MANUALOFFNET) , there may be more to add found in the chart located here: https://dev.bandwidth.com/numbers/guides/portingPhoneNumbers.html#modify-lnp

Manual Off-Net
Manual On-Net
Manual Toll Free
Automated On-Net
Automated Off-Net Pre FOC
Automated Off-Net Post FOC
Internal

AvailableNumbers with enableTNDetail=true

If I call AvailableNumbers with enableTNDetail=false I get:

TelephoneNumberList = list of telephone numbers
TelephoneNumberDetailList = NULL

If I call AvailableNumbers with enableTNDetail=true I get:

TelephoneNumberList =NULL
TelephoneNumberDetailList = detailed list of of telephone numbers BUT BUT the actual TelephoneNumber field is NULL

BW v2 API?

Are there any plans to update this to work with BW's newer "v2" APIs?

Last Sections (For now)

13.8.2
13.8.3
13.8.4
13.8.5
13.8.6
13.8.9

I will warn you that the responses in these sections will make you want to cry. The organization of the data is "interesting"

I created a Tns type in Java and just put static methods there because the response data is so varied. You can see my code in the Java project, along with sample xml for all of the responses.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.