diff --git a/CallfireApiClient.nuspec b/CallfireApiClient.nuspec index 3db0831..d7f9156 100644 --- a/CallfireApiClient.nuspec +++ b/CallfireApiClient.nuspec @@ -1,7 +1,7 @@ CallfireApiClient - 1.1.11 + 1.1.12 CallFire API v2 client Vladimir Mikhailov @@ -15,6 +15,12 @@ C# client library for integration with Callfire REST API v2 services Callfire API client Changelog ============================= +Version 1.1.12 - Dec 28 2016 +- updated CallRecord dto to include originateTime, answerTime, duration, callerName and switchId fields +- updated Webhook dto to include singleUse parameter +- minor extension of requests objects for upload and find sounds api, get contacts history api and find tollfree numbers api +- temporary turning dnc api off due to full remake of callfire dnc apis + Version 1.1.11 - Nov 18 2016 - added deleteCampaignSound api - added getCreditsHistory api diff --git a/Changelog.txt b/Changelog.txt index 7ce3739..5e93b2a 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,11 @@ Callfire API client Changelog ============================= +Version 1.1.12 - Dec 28 2016 +- updated CallRecord dto to include originateTime, answerTime, duration, callerName and switchId fields +- updated Webhook dto to include singleUse parameter +- minor extension of requests objects for upload and find sounds api, get contacts history api and find tollfree numbers api +- temporary turning dnc api off due to full remake of callfire dnc apis + Version 1.1.11 - Nov 18 2016 - added deleteCampaignSound api - added getCreditsHistory api diff --git a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs index 94ae2f2..dafca86 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs @@ -34,13 +34,13 @@ public void FindCalls() States = { StateType.FINISHED, StateType.READY }, IntervalBegin = DateTime.UtcNow.AddMonths(-2), IntervalEnd = DateTime.UtcNow, - Limit = 3 + Limit = 1 }; Page calls = Client.CallsApi.Find(request); Console.WriteLine("Calls: " + calls); - Assert.AreEqual(3, calls.Items.Count); + Assert.AreEqual(1, calls.Items.Count); } [Test] diff --git a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs index 5e87ff0..59eca47 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs @@ -13,7 +13,14 @@ public class CampaignSoundsApiIntegrationTest : AbstractIntegrationTest [Test] public void TestFind() { - FindSoundsRequest request = new FindSoundsRequest { Limit = 3, Filter = "sample" }; + FindSoundsRequest request = new FindSoundsRequest + { + Limit = 3, + Filter = "sample", + IncludeScrubbed = true, + IncludePending = true, + IncludeArchived = true + }; Page campaignSounds = Client.CampaignSoundsApi.Find(request); Assert.AreEqual(4, campaignSounds.TotalCount); @@ -92,11 +99,17 @@ public void TestUploadMp3WavFilesAndGetThem() pathToSaveNewFile = existingFilePath.Replace("train.wav", "wav_sound.wav"); File.WriteAllBytes(pathToSaveNewFile, ms.ToArray()); - CampaignSound mp3Resource = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath, soundName); + CampaignSound mp3Resource = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath, soundName, "id,name,created,lengthInSeconds,status,duplicate"); Assert.True(mp3Resource.Name.Contains("mp3_test")); Assert.AreEqual(1, mp3Resource.LengthInSeconds); Assert.True((bool) mp3Resource.Duplicate); + mp3Resource = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath); + Assert.True((bool)mp3Resource.Duplicate); + + mp3Resource = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath, soundName); + Assert.True((bool)mp3Resource.Duplicate); + CampaignSound wavResource = Client.CampaignSoundsApi.UploadAndGetSoundDetails(wavFilePath); Assert.NotNull(wavResource.Id); } diff --git a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs index bffe2bf..77c2096 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs @@ -53,7 +53,19 @@ public void CrudOperations() [Test] public void StartStopArchiveCampaign() { - var campaign = Client.TextBroadcastsApi.Get(8729792003); + var broadcast = new TextBroadcast + { + Name = "text_broadcast", + Message = "test_msg", + Recipients = new List + { + new TextRecipient { PhoneNumber = "14246525473" } + } + }; + + ResourceId id = Client.TextBroadcastsApi.Create(broadcast, false); + + var campaign = Client.TextBroadcastsApi.Get(id.Id); Console.WriteLine(campaign); Assert.NotNull(campaign); // start diff --git a/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactsApiIntegrationTest.cs index 27c0883..9703d65 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactsApiIntegrationTest.cs @@ -73,7 +73,7 @@ public void ContactsCRUD() } [Test] - public void GetContactHistory() + public void GetObsoleteContactHistory() { var request = new GetByIdRequest { Id = 1, Limit = 5 }; var contactHistory = Client.ContactsApi.GetHistory(request); @@ -81,6 +81,19 @@ public void GetContactHistory() Console.WriteLine("ContactHistory:" + contactHistory); } + + [Test] + public void GetContactHistory() + { + var request = new GetByIdRequest { Id = 1, Limit = 5 }; + var contactHistory = Client.ContactsApi.GetHistory(1, 0, 0); + Assert.AreEqual(2, contactHistory.Calls.Count); + + contactHistory = Client.ContactsApi.GetHistory(1); + Assert.AreEqual(2, contactHistory.Calls.Count); + + Console.WriteLine("ContactHistory:" + contactHistory); + } } } diff --git a/src/CallfireApiClient.IntegrationTests/Api/Contacts/DncApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Contacts/DncApiIntegrationTest.cs index 21a2d32..2e8af27 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Contacts/DncApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Contacts/DncApiIntegrationTest.cs @@ -3,63 +3,110 @@ using CallfireApiClient.Api.Contacts.Model; using CallfireApiClient.Api.Contacts.Model.Request; using CallfireApiClient.Api.Common.Model; +using System.Collections.Generic; namespace CallfireApiClient.IntegrationTests.Api.Contacts { [TestFixture] public class DncApiIntegrationTest : AbstractIntegrationTest { + //TODO vmalinovskiy: uncomment when dnc apis will be tested and available on docs site + /* [Test] public void FindDncs() { - var request = new FindDncContactsRequest(); + var request = new FindDncNumbersRequest() + { + Text = true, + Limit = 1, + Numbers = new List { "12135551189" } + }; + Page dncs = Client.DncApi.Find(request); Console.WriteLine("Page of credentials:" + dncs); Assert.NotNull(dncs); - Assert.GreaterOrEqual(dncs.Items.Count, 0); + Assert.AreEqual(dncs.Items.Count, 1); } [Test] - public void UpdateDnc() + public void CrudAndGetDnc() { - long listId = 2021478003; - string number = "13234324554"; - string prefix = "13234"; - - DoNotContact dncToUpdate = new DoNotContact + CreateDncsRequest crRequest = new CreateDncsRequest() { - ListId = listId, - Text = true, Call = true, - Number = number + Text = true, + Numbers = new List { "12135551188" }, + Source = "testSource" }; - Client.DncApi.Update(dncToUpdate); + Client.DncApi.Create(crRequest); + + DoNotContact dnc = Client.DncApi.Get("12135551188"); + Assert.AreEqual(dnc.Number, "12135551188"); + Assert.AreEqual(dnc.Call, true); + Assert.AreEqual(dnc.Text, true); - var request = new FindDncContactsRequest + UpdateDncRequest updRequest = new UpdateDncRequest() { - DncListId = listId, - Prefix = prefix, - CallDnc = true, - TextDnc = true, - Limit = 1, - Offset = 0 + Call = true, + Text = false, + Number = "12135551188" }; - Page dnc = Client.DncApi.Find(request); - Assert.NotNull(dnc); - Assert.AreEqual(dnc.Items.Count, 1); - Assert.AreEqual(dnc.Items[0].ListId, listId); - Assert.AreEqual(dnc.Items[0].Number, number); - Assert.AreEqual(dnc.Items[0].Text, true); - Assert.AreEqual(dnc.Items[0].Call, true); + Client.DncApi.Update(updRequest); + + dnc = Client.DncApi.Get("12135551188"); + Assert.AreEqual(dnc.Call, true); + Assert.AreEqual(dnc.Text, false); + + Client.DncApi.Delete("12135551188"); - //get back initial db stage as before test - dncToUpdate.Text = true; - dncToUpdate.Call = true; - Client.DncApi.Update(dncToUpdate); + dnc = Client.DncApi.Get("12135551188"); + Assert.AreEqual(dnc.Call, false); + Assert.AreEqual(dnc.Text, false); } - } + [Test] + public void DeleteDncsFromSource() + { + CreateDncsRequest crRequest = new CreateDncsRequest() + { + Call = true, + Text = true, + Numbers = new List { "12135551189" }, + Source = "testSourceForDeleteDncs" + }; + Client.DncApi.Create(crRequest); + + FindDncNumbersRequest request = new FindDncNumbersRequest() + { + Source = "testSourceForDeleteDncs" + }; + Page dncContacts = Client.DncApi.Find(request); + Assert.True(dncContacts.Items.Count > 0); -} + Client.DncApi.DeleteDncsFromSource("testSourceForDeleteDncs"); + + dncContacts = Client.DncApi.Find(request); + Assert.True(dncContacts.Items.Count == 0); + } + [Test] + public void FindUniversalDncs() + { + FindUniversalDncsRequest request = new FindUniversalDncsRequest() + { + ToNumber = "12135551188", + FromNumber = "18442800143" + }; + + var uDncs = Client.DncApi.FindUniversalDncs(request); + Assert.AreEqual("18442800143", uDncs[0].FromNumber); + Assert.AreEqual("12135551188", uDncs[0].ToNumber); + Assert.NotNull(uDncs[0].InboundCall); + Assert.NotNull(uDncs[0].InboundText); + Assert.NotNull(uDncs[0].OutboundCall); + Assert.NotNull(uDncs[0].OutboundText); + } + */ + } +} \ No newline at end of file diff --git a/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs index dc5ed06..b1d9413 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs @@ -17,7 +17,8 @@ public void CrudOperations() Name = "test_name1", Callback = "test_callback", Resource = ResourceType.TEXT_BROADCAST, - Events = new HashSet { ResourceEvent.STARTED } + Events = new HashSet { ResourceEvent.STARTED }, + SingleUse = true }; var resourceId1 = api.Create(webhook); Assert.NotNull(resourceId1.Id); @@ -28,7 +29,7 @@ public void CrudOperations() { Limit = 30L, Name = "test_name1", - Fields = "items(id,callback,name,resource,events)" + Fields = "items(id,callback,name,resource,events,singleUse)" }; var page = api.Find(findRequest); Assert.That(page.Items.Count > 1); @@ -37,12 +38,15 @@ public void CrudOperations() Assert.AreEqual(ResourceType.TEXT_BROADCAST, page.Items[0].Resource); Assert.AreEqual(1, page.Items[0].Events.Count); Assert.NotNull(page.Items[0].Id); + Assert.True(page.Items[0].SingleUse.GetValueOrDefault()); webhook = page.Items[0]; webhook.Name = "test_name2"; + webhook.SingleUse = false; api.Update(webhook); Webhook updated = api.Get((long)webhook.Id); Assert.AreEqual(webhook.Resource, updated.Resource); + Assert.False(page.Items[0].SingleUse.GetValueOrDefault()); api.Delete((long)resourceId1.Id); api.Delete((long)resourceId2.Id); diff --git a/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs b/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs index 4176f6e..ed529a8 100644 --- a/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs @@ -21,7 +21,10 @@ public void TestFind() { Limit = 5, Offset = 0, - Filter = "1234" + Filter = "1234", + IncludeArchived = true, + IncludePending = true, + IncludeScrubbed = true }; Page sounds = Client.CampaignSoundsApi.Find(request); @@ -31,6 +34,9 @@ public void TestFind() Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("5"))); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("0"))); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("filter") && p.Value.Equals("1234"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("includeArchived") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("includePending") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("includeScrubbed") && p.Value.Equals("True"))); } [Test] @@ -68,7 +74,6 @@ public void TestGet() Assert.That(Serializer.Serialize(campaignSound), Is.EqualTo(expectedJson)); Assert.AreEqual(Method.GET, restRequest.Value.Method); - Assert.That(restRequest.Value.Parameters, Has.None.Matches(p => p.Name.Equals("FIELDS") && p.Value.Equals(FIELDS))); Assert.That(restRequest.Value.Resource, Is.StringEnding("/11")); } @@ -86,7 +91,19 @@ public void TestUpload() } [Test] - public void TestUploadAndGetSoundDetails() + public void TestUploadAndGetSoundDetailsWithoutFileName() + { + string expectedJson = GetJsonPayload("/campaigns/campaignSoundsApi/response/uploadSoundWithDetails.json"); + var restRequest = MockRestResponse(expectedJson); + + string mp3FilePath = "Resources/File-examples/train.mp3"; + CampaignSound sound = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath); + Assert.That(Serializer.Serialize(sound), Is.EqualTo(expectedJson)); + Assert.AreEqual(Method.POST, restRequest.Value.Method); + } + + [Test] + public void TestUploadAndGetSoundDetailsWithFileName() { string expectedJson = GetJsonPayload("/campaigns/campaignSoundsApi/response/uploadSoundWithDetails.json"); var restRequest = MockRestResponse(expectedJson); @@ -97,6 +114,19 @@ public void TestUploadAndGetSoundDetails() Assert.AreEqual(Method.POST, restRequest.Value.Method); } + [Test] + public void TestUploadAndGetSoundDetailsWithFileNameAndFields() + { + string expectedJson = GetJsonPayload("/campaigns/campaignSoundsApi/response/uploadSoundWithDetails.json"); + var restRequest = MockRestResponse(expectedJson); + + string mp3FilePath = "Resources/File-examples/train.mp3"; + CampaignSound sound = Client.CampaignSoundsApi.UploadAndGetSoundDetails(mp3FilePath, "fname", FIELDS); + Assert.That(restRequest.Value.Parameters, Has.None.Matches(p => p.Name.Equals("FIELDS") && p.Value.Equals(FIELDS))); + Assert.That(Serializer.Serialize(sound), Is.EqualTo(expectedJson)); + Assert.AreEqual(Method.POST, restRequest.Value.Method); + } + [Test] public void TestRecordViaPhone() { diff --git a/src/CallfireApiClient.Tests/Api/Contacts/ContactsApiTest.cs b/src/CallfireApiClient.Tests/Api/Contacts/ContactsApiTest.cs index 709b116..b0eb3f3 100644 --- a/src/CallfireApiClient.Tests/Api/Contacts/ContactsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Contacts/ContactsApiTest.cs @@ -120,7 +120,7 @@ public void Delete() } [Test] - public void GetContactHistory() + public void GetObsoleteContactHistory() { var expectedJson = GetJsonPayload("/contacts/contactsApi/response/getContactHistory.json"); var restRequest = MockRestResponse(expectedJson); @@ -139,5 +139,51 @@ public void GetContactHistory() Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("1"))); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("5"))); } + + [Test] + public void GetContactHistoryById() + { + var expectedJson = GetJsonPayload("/contacts/contactsApi/response/getContactHistory.json"); + var restRequest = MockRestResponse(expectedJson); + + var contactHistory = Client.ContactsApi.GetHistory(1); + Assert.That(Serializer.Serialize(contactHistory), Is.EqualTo(expectedJson)); + + Assert.AreEqual(Method.GET, restRequest.Value.Method); + var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); + Assert.IsNull(requestBodyParam); + } + + [Test] + public void GetContactHistoryByIdAndLimit() + { + var expectedJson = GetJsonPayload("/contacts/contactsApi/response/getContactHistory.json"); + var restRequest = MockRestResponse(expectedJson); + + var contactHistory = Client.ContactsApi.GetHistory(1, 1); + Assert.That(Serializer.Serialize(contactHistory), Is.EqualTo(expectedJson)); + + Assert.AreEqual(Method.GET, restRequest.Value.Method); + var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); + Assert.IsNull(requestBodyParam); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("1"))); + } + + [Test] + public void GetContactHistoryByAllFilters() + { + var expectedJson = GetJsonPayload("/contacts/contactsApi/response/getContactHistory.json"); + var restRequest = MockRestResponse(expectedJson); + + var contactHistory = Client.ContactsApi.GetHistory(1, 1, 5); + Assert.That(Serializer.Serialize(contactHistory), Is.EqualTo(expectedJson)); + + Assert.AreEqual(Method.GET, restRequest.Value.Method); + var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); + Assert.IsNull(requestBodyParam); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("1"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("5"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("5"))); + } } } \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/Api/Contacts/DncApiTest.cs b/src/CallfireApiClient.Tests/Api/Contacts/DncApiTest.cs index 4acf33e..58bc18d 100644 --- a/src/CallfireApiClient.Tests/Api/Contacts/DncApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Contacts/DncApiTest.cs @@ -12,52 +12,171 @@ namespace CallfireApiClient.Tests.Api.Contacts [TestFixture] public class DncApiTest : AbstractApiTest { - + //TODO vmalinovskiy: uncomment when dnc apis will be tested and available on docs site + /* [Test] public void Find() { string expectedJson = GetJsonPayload("/contacts/dncApi/response/findDncs.json"); var restRequest = MockRestResponse(expectedJson); - FindDncContactsRequest request = new FindDncContactsRequest + FindDncNumbersRequest request = new FindDncNumbersRequest { Limit = 1, Offset = 5, Fields = FIELDS, Prefix = "1", - DncListId = TEST_LONG, - DncListName = TEST_STRING, - CallDnc = true, - TextDnc = true + Call = true, + Text = true, + Numbers = new List { "12135551189" } }; - Page dncs = Client.DncApi.Find(request); + var dncs = Client.DncApi.Find(request); Assert.NotNull(dncs); Assert.That(Serializer.Serialize(dncs), Is.EqualTo(expectedJson)); Assert.AreEqual(Method.GET, restRequest.Value.Method); + + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("1"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("5"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("fields") && p.Value.Equals(FIELDS))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("prefix") && p.Value.Equals("1"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("call") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("text") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("numbers") && p.Value.Equals("12135551189"))); + } + + [Test] + public void GetByNullNumberParam() + { + var ex = Assert.Throws(() => Client.DncApi.Get(null)); + Assert.That(ex.Message, Is.StringContaining("Value cannot be null")); + Assert.That(ex.Message, Is.StringContaining("Parameter name: number")); + } + + [Test] + public void Get() + { + var expectedJson = GetJsonPayload("/contacts/dncApi/response/getDnc.json"); + var restRequest = MockRestResponse(expectedJson); + + var contact = Client.DncApi.Get("12135551188"); + Assert.AreEqual(Method.GET, restRequest.Value.Method); + Assert.That(Serializer.Serialize(contact), Is.EqualTo(expectedJson)); + Assert.That(restRequest.Value.Resource, Is.StringEnding("/12135551188")); + } + + [Test] + public void UpdateByNullNumberParam() + { + UpdateDncRequest updRequest = new UpdateDncRequest() + { + Call = true, + Text = false + }; + var ex = Assert.Throws(() => Client.DncApi.Update(updRequest)); + Assert.That(ex.Message, Is.StringContaining("Value cannot be null")); + Assert.That(ex.Message, Is.StringContaining("Parameter name: number")); } [Test] public void Update() { - string requestJson = GetJsonPayload("/contacts/dncApi/request/updateDnc.json"); + var requestJson = GetJsonPayload("/contacts/dncApi/request/updateDnc.json"); var restRequest = MockRestResponse(); - DoNotContact dnc = new DoNotContact + UpdateDncRequest updRequest = new UpdateDncRequest() { Call = true, - ListId = TEST_LONG, - Number = TEST_LONG.ToString(), - Text = true + Text = false, + Number = "100500" }; - - Client.DncApi.Update(dnc); + Client.DncApi.Update(updRequest); Assert.AreEqual(Method.PUT, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); - Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); + Assert.AreEqual(requestBodyParam.Value, requestJson); + Assert.That(restRequest.Value.Resource, Is.StringEnding("/100500")); } - } -} + [Test] + public void Create() + { + var requestJson = GetJsonPayload("/contacts/dncApi/request/addDnc.json"); + var restRequest = MockRestResponse(); + + CreateDncsRequest updRequest = new CreateDncsRequest() + { + Call = true, + Text = false, + Numbers = new List { "12135551188" }, + Source = "testSource" + }; + Client.DncApi.Create(updRequest); + + Assert.AreEqual(Method.POST, restRequest.Value.Method); + var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); + Assert.AreEqual(requestBodyParam.Value, requestJson); + } + + [Test] + public void DeleteByNullNumberParam() + { + var ex = Assert.Throws(() => Client.DncApi.Delete(null)); + Assert.That(ex.Message, Is.StringContaining("Value cannot be null")); + Assert.That(ex.Message, Is.StringContaining("Parameter name: number")); + } + + [Test] + public void Delete() + { + var restRequest = MockRestResponse(); + Client.DncApi.Delete("100500"); + + Assert.AreEqual(Method.DELETE, restRequest.Value.Method); + Assert.That(restRequest.Value.Resource, Is.StringEnding("/100500")); + } + + [Test] + public void DeleteDncsFromSourceByNullSourceParam() + { + var ex = Assert.Throws(() => Client.DncApi.DeleteDncsFromSource(null)); + Assert.That(ex.Message, Is.StringContaining("Value cannot be null")); + Assert.That(ex.Message, Is.StringContaining("Parameter name: source")); + } + + [Test] + public void DeleteDncsFromSource() + { + var restRequest = MockRestResponse(); + Client.DncApi.DeleteDncsFromSource("testSource"); + + Assert.AreEqual(Method.DELETE, restRequest.Value.Method); + Assert.That(restRequest.Value.Resource, Is.StringEnding("/testSource")); + } + + [Test] + public void FindUniversalDncs() + { + string expectedJson = GetJsonPayload("/contacts/dncApi/response/findUniversalDncs.json"); + var restRequest = MockRestResponse(expectedJson); + + FindUniversalDncsRequest request = new FindUniversalDncsRequest + { + ToNumber = "12135551188", + FromNumber = "18442800143", + Fields = FIELDS + }; + + var dncs = Client.DncApi.FindUniversalDncs(request); + + Assert.NotNull(dncs); + Assert.That(Serializer.Serialize(new ListHolder(dncs)), Is.EqualTo(expectedJson)); + Assert.AreEqual(Method.GET, restRequest.Value.Method); + Assert.That(restRequest.Value.Resource, Is.StringEnding("/12135551188")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("fromNumber") && p.Value.Equals("18442800143"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("fields") && p.Value.Equals(FIELDS))); + } + */ + } +} \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/Api/Numbers/NumbersApiTest.cs b/src/CallfireApiClient.Tests/Api/Numbers/NumbersApiTest.cs index 4e748f1..73536d3 100644 --- a/src/CallfireApiClient.Tests/Api/Numbers/NumbersApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Numbers/NumbersApiTest.cs @@ -1,5 +1,4 @@ -using System; -using NUnit.Framework; +using NUnit.Framework; using CallfireApiClient.Api.Numbers.Model.Request; using RestSharp; using System.Linq; @@ -82,6 +81,7 @@ public void FindNumbersTollfree() Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("limit") && p.Value.Equals("1"))); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("offset") && p.Value.Equals("2"))); } + } } diff --git a/src/CallfireApiClient.Tests/Api/Webhooks/WebhooksApiTest.cs b/src/CallfireApiClient.Tests/Api/Webhooks/WebhooksApiTest.cs index 6792309..66d9f9f 100644 --- a/src/CallfireApiClient.Tests/Api/Webhooks/WebhooksApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Webhooks/WebhooksApiTest.cs @@ -23,7 +23,8 @@ public void Create() Name = "API hook", Resource = ResourceType.TEXT_BROADCAST, Events = new HashSet { ResourceEvent.STARTED, ResourceEvent.STOPPED }, - Callback = "http://yoursite.com/webhook" + Callback = "http://yoursite.com/webhook", + SingleUse = true }; var id = Client.WebhooksApi.Create(webhook); Assert.That(Serializer.Serialize(id), Is.EqualTo(responseJson)); @@ -85,7 +86,8 @@ public void Update() Name = "API hook", Resource = ResourceType.TEXT_BROADCAST, Events = new HashSet { ResourceEvent.STOPPED }, - Callback = "http://yoursite.com/webhook" + Callback = "http://yoursite.com/webhook", + SingleUse = true }; Client.WebhooksApi.Update(webhook); diff --git a/src/CallfireApiClient.Tests/CallfireApiClient.Tests.csproj b/src/CallfireApiClient.Tests/CallfireApiClient.Tests.csproj index eeea146..d9cb97a 100644 --- a/src/CallfireApiClient.Tests/CallfireApiClient.Tests.csproj +++ b/src/CallfireApiClient.Tests/CallfireApiClient.Tests.csproj @@ -86,6 +86,9 @@ + + + Always diff --git a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/findCalls.json b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/findCalls.json index 63847db..30cfd43 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/findCalls.json +++ b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/findCalls.json @@ -20,8 +20,13 @@ "billedAmount": 1.1667, "finishTime": 1443373425000, "toNumber": "12135551101", + "callerName": "12345", + "switchId": "1234", "labels": ["12135551102"], - "result": "AM" + "result": "AM", + "originateTime": 213231, + "answerTime": 2131223, + "duration": 20 } ], "finalCallResult": "AM", @@ -47,8 +52,13 @@ "billedAmount": 0.0, "finishTime": 1443373408000, "toNumber": "12135551101", + "callerName": "12345", + "switchId": "1234", "labels": ["12135551102"], - "result": "CARRIER_ERROR" + "result": "CARRIER_ERROR", + "originateTime": 213231, + "answerTime": 2131223, + "duration": 20 } ], "finalCallResult": "CARRIER_ERROR", diff --git a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/getCall.json b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/getCall.json index 44b8176..b09746d 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/getCall.json +++ b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/response/getCall.json @@ -18,8 +18,13 @@ "billedAmount": 1.1667, "finishTime": 1443333972000, "toNumber": "12135551101", + "callerName": "12345", + "switchId": "1234", "labels": ["12135551102"], - "result": "LA" + "result": "LA", + "originateTime": 213231, + "answerTime": 2131223, + "duration": 20 } ], "finalCallResult": "LA", diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/addDnc.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/addDnc.json new file mode 100644 index 0000000..c757dba --- /dev/null +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/addDnc.json @@ -0,0 +1,8 @@ +{ + "call": true, + "text": false, + "source": "testSource", + "numbers": [ + "12135551188" + ] +} diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/updateDnc.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/updateDnc.json index 09bc750..ac80c56 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/updateDnc.json +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/request/updateDnc.json @@ -1,8 +1,6 @@ { - "number": "100500", "call": true, - "text": true, - "listId": 100500 + "text": false } diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findDncs.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findDncs.json index 273e9b3..ced3baa 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findDncs.json +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findDncs.json @@ -1,10 +1,9 @@ { "items": [ { - "number": "100500", + "number": "12135551188", "call": true, - "text": false, - "listId": 100500 + "text": false } ], "totalCount": 1 diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findUniversalDncs.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findUniversalDncs.json new file mode 100644 index 0000000..24192ef --- /dev/null +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/findUniversalDncs.json @@ -0,0 +1,12 @@ +{ + "items": [ + { + "toNumber": "12135551188", + "fromNumber": "18442800143", + "inboundCall": false, + "inboundText": false, + "outboundCall": false, + "outboundText": true + } + ] +} diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/getDnc.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/getDnc.json new file mode 100644 index 0000000..6ac13d4 --- /dev/null +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/dncApi/response/getDnc.json @@ -0,0 +1,7 @@ +{ + "number": "12135551188", + "call": true, + "text": false +} + + diff --git a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/createWebhook.json b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/createWebhook.json index 407e3ad..9670429 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/createWebhook.json +++ b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/createWebhook.json @@ -5,5 +5,6 @@ "events": [ "Started", "Stopped" - ] + ], + "singleUse": true } \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/updateWebhook.json b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/updateWebhook.json index d779f2d..51e7f22 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/updateWebhook.json +++ b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/request/updateWebhook.json @@ -5,5 +5,6 @@ "callback": "http://yoursite.com/webhook", "events": [ "Stopped" - ] + ], + "singleUse": true } \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/findWebhooks.json b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/findWebhooks.json index 0648ca4..5713c0e 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/findWebhooks.json +++ b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/findWebhooks.json @@ -11,7 +11,8 @@ "events": [ "Started", "Stopped" - ] + ], + "singleUse": true }, { "id": 2, @@ -24,7 +25,8 @@ "events": [ "Started", "Stopped" - ] + ], + "singleUse": true } ], "limit": 1000, diff --git a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/getWebhook.json b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/getWebhook.json index 95db823..155c367 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/getWebhook.json +++ b/src/CallfireApiClient.Tests/JsonMocks/webhooks/webhooksApi/response/getWebhook.json @@ -9,5 +9,6 @@ "events": [ "Started", "Stopped" - ] + ], + "singleUse": true } \ No newline at end of file diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/ActionRecord.cs b/src/CallfireApiClient/Api/CallsTexts/Model/ActionRecord.cs index 8f36125..e0feb88 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/ActionRecord.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/ActionRecord.cs @@ -14,12 +14,16 @@ public class ActionRecord : CallfireModel public string ToNumber { get; private set; } + public string CallerName { get; private set; } + + public string SwitchId { get; private set; } + public ISet Labels { get; private set; } public override string ToString() { - return string.Format("[ActionRecord: Id={0}, billedAmount={1}, FinishTime={2}, ToNumber={3}, Labels={4}]", - Id, BilledAmount, FinishTime, ToNumber, Labels?.ToPrettyString()); + return string.Format("[ActionRecord: Id={0}, billedAmount={1}, FinishTime={2}, ToNumber={3}, CallerName={4}, SwitchId={5}, Labels={6}]", + Id, BilledAmount, FinishTime, ToNumber, CallerName, SwitchId, Labels?.ToPrettyString()); } } } diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/CallRecord.cs b/src/CallfireApiClient/Api/CallsTexts/Model/CallRecord.cs index 8e3ba32..3c30a0c 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/CallRecord.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/CallRecord.cs @@ -7,6 +7,12 @@ public class CallRecord : ActionRecord { public CallResult? Result { get; private set; } + public long? OriginateTime { get; private set; } + + public long? AnswerTime { get; private set; } + + public long? Duration { get; private set; } + public IList Notes { get; set; } public IList Recordings { get; private set; } @@ -34,8 +40,8 @@ public enum CallResult public override string ToString() { - return string.Format("{0} [CallRecord: Result={1}, Notes={2}, Recordings={3}]", base.ToString(), - Result, Notes?.ToPrettyString(), Recordings?.ToPrettyString()); + return string.Format("{0} [CallRecord: Result={1}, OriginateTime={2}, AnswerTime={3}, AnswerTime={4}, Notes={5}, Recordings={6}]", base.ToString(), + Result, OriginateTime, AnswerTime, AnswerTime, Notes?.ToPrettyString(), Recordings?.ToPrettyString()); } } } diff --git a/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs b/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs index 95b6baf..fdd262d 100644 --- a/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs +++ b/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs @@ -189,7 +189,27 @@ public ResourceId Upload(string pathToFile, string name = null) /// in case error has occurred in client. public CampaignSound UploadAndGetSoundDetails(string pathToFile, string name = null) { - return Client.PostFile(SOUNDS_FILES_PATH, name, pathToFile); + return UploadAndGetSoundDetails(pathToFile, name, null); + } + + /// + /// Upload a MP3 or WAV file to account + /// + /// contact list name + /// path to MP3 or WAV file + /// Limit text fields returned. Example fields=limit,offset,items(id,message) + /// CampaignSound object with sound details + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public CampaignSound UploadAndGetSoundDetails(string pathToFile, string name, string fields = null) + { + var queryParams = ClientUtils.BuildQueryParams("fields", fields); + return Client.PostFile(SOUNDS_FILES_PATH, name, pathToFile, queryParams); } /// diff --git a/src/CallfireApiClient/Api/Campaigns/Model/Request/FindSoundsRequest.cs b/src/CallfireApiClient/Api/Campaigns/Model/Request/FindSoundsRequest.cs index b34a6ee..2662e79 100644 --- a/src/CallfireApiClient/Api/Campaigns/Model/Request/FindSoundsRequest.cs +++ b/src/CallfireApiClient/Api/Campaigns/Model/Request/FindSoundsRequest.cs @@ -6,9 +6,15 @@ public class FindSoundsRequest : FindRequest { public string Filter { get; set; } + public bool? IncludeArchived { get; set; } + + public bool? IncludePending { get; set; } + + public bool? IncludeScrubbed { get; set; } + public override string ToString() { - return string.Format("[FindSoundsRequest: {0}, filter={1}]", base.ToString(), Filter); + return string.Format("[FindSoundsRequest: {0}, Filter={1}, IncludeArchived={2}, IncludePending={3}, IncludeScrubbed={4}]", base.ToString(), Filter, IncludeArchived, IncludePending, IncludeScrubbed); } } } diff --git a/src/CallfireApiClient/Api/Common/Model/ListHolder.cs b/src/CallfireApiClient/Api/Common/Model/ListHolder.cs index e540dd0..880960a 100644 --- a/src/CallfireApiClient/Api/Common/Model/ListHolder.cs +++ b/src/CallfireApiClient/Api/Common/Model/ListHolder.cs @@ -1,7 +1,4 @@ using System.Collections.Generic; -using Newtonsoft.Json; -using System; -using System.Linq; namespace CallfireApiClient.Api.Common.Model { diff --git a/src/CallfireApiClient/Api/Contacts/ContactsApi.cs b/src/CallfireApiClient/Api/Contacts/ContactsApi.cs index 409e1d5..6e8e419 100644 --- a/src/CallfireApiClient/Api/Contacts/ContactsApi.cs +++ b/src/CallfireApiClient/Api/Contacts/ContactsApi.cs @@ -120,11 +120,32 @@ public void Delete(long id) /// in case HTTP response code is 500 - Internal Server Error. /// in case HTTP response code is something different from codes listed above. /// in case error has occurred in client. + [Obsolete] public ContactHistory GetHistory(GetByIdRequest request) { String path = CONTACTS_ITEM_HISTORY_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, request.Id.ToString()); return Client.Get(path, request); } - } -} + /// + /// Find all texts and calls attributed to a contact. + /// + /// request to get particular contact's history + /// a list of calls and texts a contact has been involved with. + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public ContactHistory GetHistory(long id, long? limit = null, long? offset = null) + { + String path = CONTACTS_ITEM_HISTORY_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, id.ToString()); + var queryParams = new List>(2); + ClientUtils.AddQueryParamIfSet("limit", limit, queryParams); + ClientUtils.AddQueryParamIfSet("offset", offset, queryParams); + return Client.Get(path, queryParams); + } + } +} \ No newline at end of file diff --git a/src/CallfireApiClient/Api/Contacts/DncApi.cs b/src/CallfireApiClient/Api/Contacts/DncApi.cs index 9aa3298..9e120cf 100644 --- a/src/CallfireApiClient/Api/Contacts/DncApi.cs +++ b/src/CallfireApiClient/Api/Contacts/DncApi.cs @@ -1,12 +1,18 @@ using CallfireApiClient.Api.Contacts.Model; using CallfireApiClient.Api.Contacts.Model.Request; using CallfireApiClient.Api.Common.Model; +using System.Collections.Generic; namespace CallfireApiClient.Api.Contacts { public class DncApi { + //TODO vmalinovskiy: uncomment when dnc apis will be tested and available on docs site + /* private const string DNC_PATH = "/contacts/dncs"; + private const string DNC_SOURCES_PATH = "/contacts/dncs/sources/{}"; + private const string UNIVERSAL_DNC_PATH = "/contacts/dncs/universals/{}"; + private const string DNC_NUMBER_PATH = "/contacts/dncs/{}"; private readonly RestApiClient Client; @@ -28,15 +34,16 @@ internal DncApi(RestApiClient client) /// in case HTTP response code is 500 - Internal Server Error. /// in case HTTP response code is something different from codes listed above. /// in case error has occurred in client. - public Page Find(FindDncContactsRequest request) + public Page Find(FindDncNumbersRequest request) { return Client.Get>(DNC_PATH, request); } /// - /// Update a Do Not Contact (DNC) contact value. Can toggle whether the DNC is enabled for calls/texts. + /// Get do not contact(dnc). /// - /// DNC item to update + /// number to get dnc for + /// dnc object /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. /// in case HTTP response code is 403 - Forbidden, insufficient permissions. @@ -44,9 +51,101 @@ public Page Find(FindDncContactsRequest request) /// in case HTTP response code is 500 - Internal Server Error. /// in case HTTP response code is something different from codes listed above. /// in case error has occurred in client. - public void Update(DoNotContact dnc) + public DoNotContact Get(string number) { - Client.Put(DNC_PATH, dnc); + Validate.NotNull(number, "number"); + string path = DNC_NUMBER_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, number); + return Client.Get(path); } + + /// + /// Add Do Not Contact (DNC) entries. + /// + /// DNC items to create + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public void Create(CreateDncsRequest request) + { + Client.Post(DNC_PATH, request); + } + + /// + /// Update a Do Not Contact (DNC) value. Can toggle whether the DNC is enabled for calls/texts. + /// + /// DNC update request + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public void Update(UpdateDncRequest request) + { + Validate.NotNull(request.Number, "number"); + string path = DNC_NUMBER_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, request.Number); + Client.Put(path, request); + } + + /// + /// Delete a Do Not Contact(DNC) value. + /// + /// number to remove dnc for + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public void Delete(string number) + { + Validate.NotNull(number, "number"); + string path = DNC_NUMBER_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, number); + Client.Delete(path); + } + + /// + /// Find universal do not contacts(udnc) associated with toNumber + /// + /// find request with different properties to filter + /// list with universal dnc objects + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public IList FindUniversalDncs(FindUniversalDncsRequest request) + { + Validate.NotNull(request.ToNumber, "toNumber"); + string path = UNIVERSAL_DNC_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, request.ToNumber); + return Client.Get>(path, request).Items; + } + + /// + /// Delete do not contact (dnc) numbers contained in source. + /// + /// Source associated with Do Not Contact (DNC) entry. + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public void DeleteDncsFromSource(string source) + { + Validate.NotNull(source, "source"); + string path = DNC_SOURCES_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, source); + Client.Delete(path); + } + */ } -} \ No newline at end of file +} diff --git a/src/CallfireApiClient/Api/Contacts/Model/DoNotContact.cs b/src/CallfireApiClient/Api/Contacts/Model/DoNotContact.cs index c7071bd..ca99c87 100644 --- a/src/CallfireApiClient/Api/Contacts/Model/DoNotContact.cs +++ b/src/CallfireApiClient/Api/Contacts/Model/DoNotContact.cs @@ -8,12 +8,14 @@ public class DoNotContact : CallfireModel public string Number { get; set; } public bool? Call { get; set; } public bool? Text { get; set; } - public long? ListId { get; set; } - + //public long? CampaignId { get; private set; } + //public string Source { get; set; } + //public DateTime? Created { get; private set; } + public override string ToString() { - return string.Format("[DoNotContact: number={0}, call={1}, text={2}, listId={3}", - Number, Call, Text, ListId); + return string.Format("[DoNotContact: number={0}, call={1}, text={2}", + Number, Call, Text); } } } \ No newline at end of file diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/CallsTextsRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/CallsTextsRequest.cs new file mode 100644 index 0000000..c7e1ca8 --- /dev/null +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/CallsTextsRequest.cs @@ -0,0 +1,25 @@ +using CallfireApiClient.Api.Common.Model; + +namespace CallfireApiClient.Api.Contacts.Model.Request +{ + /// + /// Abstract request object for controlling calls/texts flags availability + /// + public abstract class CallsTextsRequest : CallfireModel + { + /// + /// Set Call flag + /// + /// Set Text flag + /// + public bool? Text { get; set; } + + public override string ToString() + { + return string.Format("[FindRequest: Call={0}, Text={1}]", Call, Text); + } + } +} \ No newline at end of file diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/CreateDncsRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/CreateDncsRequest.cs new file mode 100644 index 0000000..e91a089 --- /dev/null +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/CreateDncsRequest.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace CallfireApiClient.Api.Contacts.Model.Request +{ + public class CreateDncsRequest : CallsTextsRequest + { + public string Source { get; set; } + + public List Numbers { get; set; } + + public CreateDncsRequest() + { + Numbers = new List(); + } + + public override string ToString() + { + return string.Format("[CreateDncsRequest: {0}, Source={1}, Numbers={2}]", base.ToString(), + Source, Numbers.ToPrettyString()); + } + } +} + diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncContactsRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncContactsRequest.cs deleted file mode 100644 index adf3680..0000000 --- a/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncContactsRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using CallfireApiClient.Api.Common.Model.Request; - -namespace CallfireApiClient.Api.Contacts.Model.Request -{ - public class FindDncContactsRequest : FindRequest - { - public string Prefix { get; set; } - public long? DncListId { get; set; } - public string DncListName { get; set; } - public bool? CallDnc { get; set; } - public bool? TextDnc { get; set; } - - public override string ToString() - { - return string.Format("[FindDncContactsRequest: {0}, Prefix={1}, DncListId={2}, DncListName={3}, CallDnc={4}, TextDnc={5}]", base.ToString(), - Prefix, DncListId, DncListName, CallDnc, TextDnc); - } - } -} - diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncNumbersRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncNumbersRequest.cs new file mode 100644 index 0000000..1de8148 --- /dev/null +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/FindDncNumbersRequest.cs @@ -0,0 +1,22 @@ +using CallfireApiClient.Api.Common.Model.Request; +using System.Collections.Generic; + +namespace CallfireApiClient.Api.Contacts.Model.Request +{ + public class FindDncNumbersRequest : FindRequest + { + public string Prefix { get; set; } + public long? CampaignId { get; set; } + public string Source { get; set; } + public bool? Call { get; set; } + public bool? Text { get; set; } + public List Numbers { get; set; } + + public override string ToString() + { + return string.Format("[FindDncContactsRequest: {0}, Prefix={1}, CampaignId={2}, Source={3}, Call={4}, Text={5}, Numbers={6}]", base.ToString(), + Prefix, CampaignId, Source, Call, Text, Numbers.ToPrettyString()); + } + } +} + diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/FindUniversalDncsRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/FindUniversalDncsRequest.cs new file mode 100644 index 0000000..bbb573c --- /dev/null +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/FindUniversalDncsRequest.cs @@ -0,0 +1,20 @@ +using CallfireApiClient.Api.Common.Model; +using Newtonsoft.Json; + +namespace CallfireApiClient.Api.Contacts.Model.Request +{ + public class FindUniversalDncsRequest : CallfireModel + { + [JsonIgnore] + public string ToNumber { get; set; } + + public string FromNumber { get; set; } + + public string Fields { get; set; } + + public override string ToString() + { + return string.Format("[FindUniversalDncsRequest: ToNumber={0}, FromNumber={1}, Fields={1}]", ToNumber, FromNumber, Fields); + } + } +} \ No newline at end of file diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/UpdateDncRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/UpdateDncRequest.cs new file mode 100644 index 0000000..15a5c62 --- /dev/null +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/UpdateDncRequest.cs @@ -0,0 +1,17 @@ + +using Newtonsoft.Json; + +namespace CallfireApiClient.Api.Contacts.Model.Request +{ + public class UpdateDncRequest : CallsTextsRequest + { + [JsonIgnore] + public string Number { get; set; } + + public override string ToString() + { + return string.Format("[UpdateDncRequest: {0}, Number={1}]", base.ToString(), Number); + } + } +} + diff --git a/src/CallfireApiClient/Api/Contacts/Model/UniversalDnc.cs b/src/CallfireApiClient/Api/Contacts/Model/UniversalDnc.cs index 0171f56..ab7a9cd 100644 --- a/src/CallfireApiClient/Api/Contacts/Model/UniversalDnc.cs +++ b/src/CallfireApiClient/Api/Contacts/Model/UniversalDnc.cs @@ -1,4 +1,3 @@ -using System; using CallfireApiClient.Api.Common.Model; namespace CallfireApiClient.Api.Contacts.Model diff --git a/src/CallfireApiClient/Api/Numbers/NumbersApi.cs b/src/CallfireApiClient/Api/Numbers/NumbersApi.cs index 46e8683..d617b6c 100644 --- a/src/CallfireApiClient/Api/Numbers/NumbersApi.cs +++ b/src/CallfireApiClient/Api/Numbers/NumbersApi.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using CallfireApiClient.Api.Numbers.Model; using CallfireApiClient.Api.Numbers.Model.Request; using CallfireApiClient.Api.Common.Model; @@ -71,6 +70,7 @@ public IList FindNumbersTollfree(CommonFindRequest request) { return Client.Get>(NUMBERS_TOLLFREE_PATH, request).Items; } + } } diff --git a/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs b/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs index 5c90155..9c7bd01 100644 --- a/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs +++ b/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs @@ -28,6 +28,8 @@ public class Webhook : CallfireModel public ISet Events { get; set; } + public bool? SingleUse { get; set; } + private static Dictionary> supportedEvents = new Dictionary> { { ResourceType.MONTHLY_RENEWAL, new HashSet { ResourceEvent.FINISHED, ResourceEvent.FAILED } }, @@ -40,7 +42,7 @@ public class Webhook : CallfireModel { ResourceType.INBOUND_TEXT, new HashSet { ResourceEvent.FINISHED } }, { ResourceType.OUTBOUND_TEXT, new HashSet { ResourceEvent.FINISHED } }, { ResourceType.UNKNOWN, new HashSet { } } - }; + }; public override string ToString() { diff --git a/src/CallfireApiClient/CallfireApiClient.csproj b/src/CallfireApiClient/CallfireApiClient.csproj index 18c49de..7c3c6e6 100644 --- a/src/CallfireApiClient/CallfireApiClient.csproj +++ b/src/CallfireApiClient/CallfireApiClient.csproj @@ -123,9 +123,13 @@ + + - + + + diff --git a/src/CallfireApiClient/CallfireClient.cs b/src/CallfireApiClient/CallfireClient.cs index 6d32f4f..f461f25 100644 --- a/src/CallfireApiClient/CallfireClient.cs +++ b/src/CallfireApiClient/CallfireClient.cs @@ -62,7 +62,8 @@ public class CallfireClient public KeywordLeasesApi KeywordLeasesApi { get { return _KeywordLeasesApi.Value; } } - public DncApi DncApi { get { return _DncApi.Value; } } + //TODO vmalinovskiy: uncomment when dnc apis will be tested and available on docs site + //public DncApi DncApi { get { return _DncApi.Value; } } public CallsApi CallsApi { get { return _CallsApi.Value; } } @@ -92,7 +93,10 @@ public CallfireClient(string username, string password) _WebhooksApi = new Lazy(() => new WebhooksApi(RestApiClient)); _KeywordsApi = new Lazy(() => new KeywordsApi(RestApiClient)); _KeywordLeasesApi = new Lazy(() => new KeywordLeasesApi(RestApiClient)); - _DncApi = new Lazy(() => new DncApi(RestApiClient)); + + //TODO vmalinovskiy: uncomment when dnc apis will be tested and available on docs site + //_DncApi = new Lazy(() => new DncApi(RestApiClient)); + _CallsApi = new Lazy(() => new CallsApi(RestApiClient)); _TextsApi = new Lazy(() => new TextsApi(RestApiClient)); _TextAutoRepliesApi = new Lazy(() => new TextAutoRepliesApi(RestApiClient)); diff --git a/src/CallfireApiClient/Properties/AssemblyInfo.cs b/src/CallfireApiClient/Properties/AssemblyInfo.cs index d85b3f6..936f9f8 100644 --- a/src/CallfireApiClient/Properties/AssemblyInfo.cs +++ b/src/CallfireApiClient/Properties/AssemblyInfo.cs @@ -13,7 +13,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("1.1.11.*")] +[assembly: AssemblyVersion("1.1.12.*")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. diff --git a/src/CallfireApiClient/RestApiClient.cs b/src/CallfireApiClient/RestApiClient.cs index e98a224..4e52e22 100644 --- a/src/CallfireApiClient/RestApiClient.cs +++ b/src/CallfireApiClient/RestApiClient.cs @@ -271,6 +271,34 @@ public Stream GetFileData(string path, IEnumerable> return DoRequest(restRequest); } + /// + /// Performs POST request with binary body to specified path + /// + /// The type of object to create and populate with the returned data. + /// relative API request path + /// name of file + /// path to file + /// query parameters + /// mapped object + /// in case HTTP response code is 400 - Bad request, the request was formatted improperly. + /// in case HTTP response code is 401 - Unauthorized, API Key missing or invalid. + /// in case HTTP response code is 403 - Forbidden, insufficient permissions. + /// in case HTTP response code is 404 - NOT FOUND, the resource requested does not exist. + /// in case HTTP response code is 500 - Internal Server Error. + /// in case HTTP response code is something different from codes listed above. + /// in case error has occurred in client. + public T PostFile(String path, string fileName, string filePath, IList> additionalQueryParams) where T : new() + { + var queryParams = new List>(ClientUtils.BuildQueryParams("name", fileName)); + queryParams.AddRange(additionalQueryParams); + + var restRequest = CreateRestRequest(path, Method.POST, queryParams); + restRequest.AddHeader("Content-Type", "multipart/form-data"); + restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), DEFAULT_FILE_CONTENT_TYPE); + restRequest.AddParameter("name", fileName); + return DoRequest(restRequest); + } + /// /// Performs PUT request with body to specified path ///