-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Communication] - PhoneNumberClient - Adding samples for phone number administration #16935
Changes from 16 commits
d36bcf5
4fae158
846cf86
cf56c02
9e78df8
cfeb709
735dbbe
a044c2d
113bb9d
14f32cb
cc41d52
987f4ad
1825458
ac07d86
2802d98
85a63fe
09400df
1430df8
00694d8
c727cea
251ce9a
2662c83
c3bd4f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,214 @@ | ||||||
# Searching, reserving, purchasing, releasing phone numbers | ||||||
|
||||||
This sample demonstrates how to search, reserve, purchase and release phone numbers in Azure Communication Services. | ||||||
To get started, you'll need a URI to an Azure Communication Services. See the [README](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/communication/Azure.Communication.Administration/README.md) for links and instructions. | ||||||
|
||||||
## Creating a PhoneNumberAdministrationClient | ||||||
|
||||||
To create a new `PhoneNumberAdministrationClient` you need a connection string to the Azure Communication Services resource that you can get from the Azure Portal once you create a relevant resource. | ||||||
|
||||||
You can set `connectionString` based on an environment variable, a configuration setting, or any way that works for your application. | ||||||
|
||||||
```C# Snippet:CreatePhoneNumberAdministrationClient | ||||||
// Get a connection string to our Azure Communication resource. | ||||||
var connectionString = "<connection_string>"; | ||||||
var client = new PhoneNumberAdministrationClient(connectionString); | ||||||
``` | ||||||
|
||||||
## Listing all supported countries | ||||||
|
||||||
In order to acquire a phone number you will need to know if Azure Communication Services are available in particular country. You can do that by retrieving a list of supported countries. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:GetAllSupportedCountries | ||||||
var supportedCountries = client.GetAllSupportedCountries(locale); | ||||||
foreach (var country in supportedCountries) | ||||||
{ | ||||||
Console.WriteLine($"Supported country code: {country.CountryCode}, name: {country.LocalizedName}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Listing phone plan groups | ||||||
|
||||||
Phone plan groups come in two types, Geographic and Toll-Free. | ||||||
|
||||||
```C# Snippet:GetPhonePlanGroups | ||||||
var phonePlanGroups = client.GetPhonePlanGroups(countryCode, locale); | ||||||
|
||||||
foreach (var phonePlanGroup in phonePlanGroups) | ||||||
{ | ||||||
Console.WriteLine($"Plan group: {phonePlanGroup.LocalizedName}, type: {phonePlanGroup.PhoneNumberType}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Listing phone plans | ||||||
|
||||||
Unlike Toll-Free phone plans, area codes for Geographic Phone Plans are empty. Area codes are found in the Area Codes API. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
```C# Snippet:GetPhonePlans | ||||||
var phonePlans = client.GetPhonePlans(countryCode, phonePlanGroupId, locale); | ||||||
foreach (var phonePlan in phonePlans) | ||||||
{ | ||||||
Console.WriteLine($"Plan: {phonePlan.LocalizedName}, {phonePlan.LocationType}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Get location options | ||||||
|
||||||
For Geographic phone plans, you can query the available geographic locations. The locations options are structured like the geographic hierarchy of a country. For example, the US has states and within each state are cities. | ||||||
|
||||||
```C# Snippet:GetPhonePlanLocationOptions | ||||||
var locationOptionsResponse = client.GetPhonePlanLocationOptions(countryCode, geographicPhonePlanGroup.PhonePlanGroupId, phonePlanId); | ||||||
|
||||||
void printLocationOption(LocationOptions locationOptions) | ||||||
{ | ||||||
Console.WriteLine($"LabelId: {locationOptions.LabelId}, LabelName: {locationOptions.LabelName}"); | ||||||
|
||||||
foreach (var locationOption in locationOptions.Options) | ||||||
{ | ||||||
Console.WriteLine($"Name: {locationOption.Name}, Value: {locationOption.Value}"); | ||||||
|
||||||
foreach (var subLocationOption in locationOption.LocationOptions) | ||||||
printLocationOption(subLocationOption); | ||||||
} | ||||||
} | ||||||
printLocationOption(locationOptionsResponse.Value.LocationOptions); | ||||||
``` | ||||||
|
||||||
## Get area codes | ||||||
|
||||||
Fetching area codes for geographic phone plans will require the the location options queries set. You must include the chain of geographic locations traversing down the location options object returned by the GetPhonePlanLocationOptions. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:GeographicalAreaCodes | ||||||
var locationOptionsResponse = client.GetPhonePlanLocationOptions(countryCode, geographicPhonePlanGroupId, geographicPhonePlanId); | ||||||
var state = locationOptionsResponse.Value.LocationOptions.Options.First(); | ||||||
|
||||||
var locationOptionsQueries = new List<LocationOptionsQuery>{ | ||||||
new LocationOptionsQuery | ||||||
{ | ||||||
LabelId = "state", | ||||||
OptionsValue = state.Value | ||||||
}, | ||||||
new LocationOptionsQuery | ||||||
{ | ||||||
LabelId = "city", | ||||||
OptionsValue = state.LocationOptions.First().Options.First().Value | ||||||
} | ||||||
}; | ||||||
|
||||||
var areaCodes = client.GetAllAreaCodes(geographicPhonePlan.LocationType.ToString(), countryCode, geographicPhonePlan.PhonePlanId, locationOptionsQueries); | ||||||
|
||||||
foreach (var areaCode in areaCodes.Value.PrimaryAreaCodes) | ||||||
{ | ||||||
Console.WriteLine($"Primary area code: {areaCode}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
Area codes for toll free phone plans can be found in the plan. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:TollFreePlanAreCodes | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: spelling in region and snippet title
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
var phonePlans = client.GetPhonePlans(countryCode, tollFreePhonePlanGroupId, locale); | ||||||
var tollFreePhonePlan = phonePlans.First(); | ||||||
|
||||||
foreach (var areaCode in tollFreePhonePlan.AreaCodes) | ||||||
{ | ||||||
Console.WriteLine($"Area code: {areaCode}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Reserve phone numbers | ||||||
|
||||||
Phone numbers need to be reserved for purchase. Reservation is a long running operation that can be started by CreateReservationOptions function that returns an PhoneNumberReservationOperation object. PhoneNumberReservationOperation can be used to update status of the operation and to check for completeness. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's go through the file and `` format all references to code where we use the literal name of a type or method. Just fixing one sentence here as an example.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:ReservePhoneNumbers | ||||||
var reservationName = "My reservation"; | ||||||
var reservationDescription = "reservation description"; | ||||||
var reservationOptions = new CreateReservationOptions(reservationName, reservationDescription, new[] { phonePlanId }, areaCode); | ||||||
reservationOptions.Quantity = 1; | ||||||
|
||||||
var reservationOperation = client.StartReservation(reservationOptions); | ||||||
|
||||||
while (true) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we manually polling here and not using If we give the while loop and Thread.Sleep as an example snippet, developers will copy and it and think that's the default way how to do reservations. Let's change the snippet to wait on the operation instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Saw the other comment thread below just now, let's see what Christopher says. |
||||||
{ | ||||||
reservationOperation.UpdateStatus(); | ||||||
if (reservationOperation.HasCompleted) | ||||||
{ | ||||||
break; | ||||||
} | ||||||
|
||||||
Thread.Sleep(1000); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Persist reserve phone numbers operation | ||||||
|
||||||
You can persist phone number reservation operation Id so that you can get back later to check operation status. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:PersistReservePhoneNumbersOperation | ||||||
var reservationId = reservationOperation.Id; | ||||||
|
||||||
// persist reservationOperationId and then continue with new operation | ||||||
|
||||||
var newPhoneNumberReservationOperation = new PhoneNumberReservationOperation(client, reservationId); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we shorten the name? Maybe just The context makes it clear what the operation is about and it can't be confused with another operation, that's why I think a short and less precise name reads better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made it newReserveOperation to stress that is a new object created with reservationId There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually one would only prefix variable names with To avoid a name clash with the other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Renamed it to reserveOperation |
||||||
|
||||||
while (true) | ||||||
{ | ||||||
newPhoneNumberReservationOperation.UpdateStatus(); | ||||||
if (newPhoneNumberReservationOperation.HasCompleted) | ||||||
{ | ||||||
break; | ||||||
} | ||||||
|
||||||
Thread.Sleep(1000); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @christothes is there a better recommended way to have sync tests for long running operations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @christothes @RezaJooyandeh just a reminder that this test code is copied over MD sample file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's follow how KeyVault has written the code. https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/keyvault/Azure.Security.KeyVault.Keys/samples/Sample1_HelloWorld.md#purging-a-deleted-key while (!newPhoneNumberReservationOperation.HasCompleted)
{
Thread.Sleep(2000);
operation.UpdateStatus();
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
} | ||||||
``` | ||||||
|
||||||
## Purchase phone numbers | ||||||
|
||||||
Phone numbers can be acquired by purchasing reservation. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
```C# Snippet:StartPurchaseReservation | ||||||
var reservationPurchaseOperation = client.StartPurchaseReservation(reservationId); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can shorten this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
|
||||||
while (true) | ||||||
{ | ||||||
reservationPurchaseOperation.UpdateStatus(); | ||||||
if (reservationPurchaseOperation.HasCompleted) | ||||||
{ | ||||||
break; | ||||||
} | ||||||
|
||||||
Thread.Sleep(1000); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Listing acquired phone numbers | ||||||
|
||||||
DominikMe marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
```C# Snippet:ListAcquiredPhoneNumbers | ||||||
var acquiredPhoneNumbers = client.GetAllPhoneNumbers(locale); | ||||||
|
||||||
foreach (var phoneNumber in acquiredPhoneNumbers) | ||||||
{ | ||||||
Console.WriteLine($"Phone number: {phoneNumber.PhoneNumber}, activation state: {phoneNumber.ActivationState}"); | ||||||
} | ||||||
``` | ||||||
|
||||||
## Release phone numbers | ||||||
|
||||||
If you no longer need a phone number you can release it. | ||||||
|
||||||
```C# Snippet:ReleasePhoneNumbers | ||||||
var acquiredPhoneNumber = "<acquired_phone_number>"; | ||||||
var phoneNumbers = new List<PhoneNumber> { new PhoneNumber(acquiredPhoneNumber) }; | ||||||
var phoneNumberReleaseOperation = client.StartReleasePhoneNumbers(phoneNumbers); | ||||||
|
||||||
while (true) | ||||||
{ | ||||||
phoneNumberReleaseOperation.UpdateStatus(); | ||||||
if (phoneNumberReleaseOperation.HasCompleted) | ||||||
{ | ||||||
break; | ||||||
} | ||||||
|
||||||
Thread.Sleep(1000); | ||||||
} | ||||||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done