diff --git a/CallfireApiClient.nuspec b/CallfireApiClient.nuspec index 9db7db4..e15086d 100644 --- a/CallfireApiClient.nuspec +++ b/CallfireApiClient.nuspec @@ -1,7 +1,7 @@ CallfireApiClient - 1.1.18 + 1.1.19 CallFire API v2 client Vladimir Mikhailov @@ -15,6 +15,13 @@ C# client library for integration with Callfire REST API v2 services Callfire API client Changelog ============================= +Version 1.1.19 - Jun 13 2017 +- added fromNumber to Recipient object for sending calls/texts +- added strictValidation flag for adding contacts to broadcast +- added useCustomFields to createContactList/addContactListContacts apis +- added media array parameter for TextRecipient +- added a way to upload files from byte array for media and campaign sounds api + Version 1.1.18 - May 29 2017 - upgraded dependencies diff --git a/Changelog.txt b/Changelog.txt index 11ef9c1..c62c748 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,12 @@ Callfire API client Changelog ============================= +Version 1.1.19 - Jun 13 2017 +- added fromNumber to Recipient object for sending calls/texts +- added strictValidation flag for adding contacts to broadcast +- added useCustomFields to createContactList/addContactListContacts apis +- added media array parameter for TextRecipient +- added a way to upload files from byte array for media and campaign sounds api + Version 1.1.18 - May 29 2017 - upgraded dependencies diff --git a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs index 744d13b..ab9141d 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/CallsApiIntegrationTest.cs @@ -48,7 +48,7 @@ public void SendCall() var contacts = Client.ContactsApi.Find(new FindContactsRequest()); var recipient1 = new CallRecipient { ContactId = contacts.Items[0].Id, LiveMessage = "testMessage", TransferDigit = "1", TransferMessage = "transferTestMessage", TransferNumber = "14246525473" }; - var recipient2 = new CallRecipient { ContactId = contacts.Items[0].Id, LiveMessage = "testMessage", TransferDigit = "1", TransferMessageSoundId = 1, TransferNumber = "14246525473" }; + var recipient2 = new CallRecipient { ContactId = contacts.Items[0].Id, LiveMessage = "testMessage", TransferDigit = "1", TransferMessageSoundId = 1, TransferNumber = "14246525473", FromNumber = "12132041238" }; var recipients = new List { recipient1, recipient2 }; IList calls = Client.CallsApi.Send(recipients, null, "items(id,fromNumber,state)"); @@ -66,7 +66,8 @@ public void SendCall() Fields = "items(id, fromNumber, state, campaignId)", DefaultLiveMessage = "DefaultLiveMessage", DefaultMachineMessage = "DefaultMachineMessage", - DefaultVoice = CallfireApiClient.Api.Campaigns.Model.Voice.FRENCHCANADIAN1 + DefaultVoice = Voice.FRENCHCANADIAN1, + StrictValidation = true }; calls = Client.CallsApi.Send(request); Assert.AreEqual(2, calls.Count); @@ -79,7 +80,7 @@ public void SendCall() Fields = "items(id, fromNumber, state, campaignId)", DefaultLiveMessageSoundId = 1, DefaultMachineMessageSoundId = 1, - DefaultVoice = CallfireApiClient.Api.Campaigns.Model.Voice.FRENCHCANADIAN1 + DefaultVoice = Voice.FRENCHCANADIAN1 }; calls = Client.CallsApi.Send(request); Assert.AreEqual(2, calls.Count); diff --git a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/MediaApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/MediaApiIntegrationTest.cs index 54b8f1a..a3db7ab 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/MediaApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/MediaApiIntegrationTest.cs @@ -24,6 +24,15 @@ public void TestUpload() Assert.NotNull(wavResourceId.Id); } + [Test] + public void TestUploadWithFileData() + { + String soundName = "mp3_test_" + DateTime.Now.Millisecond.ToString(); + ResourceId wavResourceId = Client.MediaApi.Upload(File.ReadAllBytes(wavFilePath), MediaType.WAV); + ResourceId mp3ResourceId = Client.MediaApi.Upload(File.ReadAllBytes(mp3FilePath), MediaType.MP3, soundName); + Assert.NotNull(mp3ResourceId.Id); + } + [Test] public void TestGet() { diff --git a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/TextsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/TextsApiIntegrationTest.cs index a183773..23c9c3f 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/TextsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/CallsTexts/TextsApiIntegrationTest.cs @@ -37,7 +37,7 @@ public void FindAndGetParticularTexts() public void SendText() { var recipient1 = new TextRecipient { Message = "msg", PhoneNumber = "12132212384" }; - var recipient2 = new TextRecipient { Message = "msg", PhoneNumber = "12132212384" }; + var recipient2 = new TextRecipient { Message = "msg", PhoneNumber = "12132212384", FromNumber = "12132041238" }; var recipients = new List { recipient1, recipient2 }; IList texts = Client.TextsApi.Send(recipients, null, "items(id,fromNumber,state)"); @@ -54,7 +54,8 @@ public void SendText() Recipients = recipients, CampaignId = 7415135003, DefaultMessage = "DefaultLiveMessage", - Fields = "items(id,fromNumber,state)" + Fields = "items(id,fromNumber,state)", + StrictValidation = true }; texts = Client.TextsApi.Send(request); CallfireApiClient.Api.CallsTexts.Model.Text text = Client.TextsApi.Get((long)texts[0].Id); diff --git a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CallBroadcastsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CallBroadcastsApiIntegrationTest.cs index e5a5baf..e29fe6b 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CallBroadcastsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CallBroadcastsApiIntegrationTest.cs @@ -37,9 +37,9 @@ public void VoiceBroadcastCrudOperations() TimeZone = "America/New_York", DaysOfWeek = new HashSet { DayOfWeek.MONDAY, DayOfWeek.FRIDAY } } }, - ResumeNextDay = true + ResumeNextDay = true, }; - var id = Client.CallBroadcastsApi.Create(broadcast, true); + var id = Client.CallBroadcastsApi.Create(broadcast, true, true); System.Console.WriteLine("broadcast id: " + id); var savedBroadcast = Client.CallBroadcastsApi.Get(id.Id); Assert.AreEqual(broadcast.Name, savedBroadcast.Name); @@ -77,7 +77,7 @@ public void IvrsCrudOperations() savedBroadcast.Name = "updated_name"; savedBroadcast.DialplanXml = "\r\n\tCongratulations! You have successfully configured a CallFire I V R.\r\n"; - Client.CallBroadcastsApi.Update(savedBroadcast); + Client.CallBroadcastsApi.Update(savedBroadcast, true); var updatedBroadcast = Client.CallBroadcastsApi.Get(id.Id, "id,name"); Assert.Null(updatedBroadcast.Status); @@ -186,7 +186,7 @@ public void AddRecipientsAndAddRemoveBatches() { new Recipient { PhoneNumber = "12132212384" }, new Recipient { PhoneNumber = "12132212385" } - }); + }, null, true); System.Console.WriteLine(calls); Assert.AreEqual(2, calls.Count); @@ -204,7 +204,8 @@ public void AddRecipientsAndAddRemoveBatches() { new Recipient { PhoneNumber = "12132212386" }, new Recipient { PhoneNumber = "12132212387" } - } + }, + StrictValidation = true }; ResourceId addedBatchId = Client.CallBroadcastsApi.AddBatch(addBatchRequest); diff --git a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs index 42fa2dc..fdec17c 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/CampaignSoundsApiIntegrationTest.cs @@ -48,6 +48,22 @@ public void TestUploadSoundAndDeleteIt() } + [Test] + public void TestUploadSoundWithFileDataAndDeleteIt() + { + String soundName = "mp3_test_" + DateTime.Now.ToString(); + string mp3FilePath = "Resources/File-examples/train1.mp3"; + CampaignSound campaignSound = Client.CampaignSoundsApi.UploadAndGetSoundDetails(File.ReadAllBytes(mp3FilePath), soundName); + Assert.NotNull(campaignSound.Id); + + Client.CampaignSoundsApi.Delete((long)campaignSound.Id); + + FindSoundsRequest request = new FindSoundsRequest { Filter = soundName }; + Page campaignSounds = Client.CampaignSoundsApi.Find(request); + Assert.True(campaignSounds.Items.Count == 0); + + } + [Test, Ignore("performs real call to specified number")] public void TestCallInToRecord() { diff --git a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs index 89480de..5648851 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Campaigns/TextBroadcastsApiIntegrationTest.cs @@ -35,13 +35,13 @@ public void CrudOperations() }, ResumeNextDay = true }; - var id = Client.TextBroadcastsApi.Create(broadcast, true); + var id = Client.TextBroadcastsApi.Create(broadcast, true, true); var savedBroadcast = Client.TextBroadcastsApi.Get(id.Id); Assert.AreEqual(broadcast.Name, savedBroadcast.Name); Assert.AreEqual(savedBroadcast.ResumeNextDay, true); savedBroadcast.Name = "updated_name"; savedBroadcast.ResumeNextDay = false; - Client.TextBroadcastsApi.Update(savedBroadcast); + Client.TextBroadcastsApi.Update(savedBroadcast, true); var updatedBroadcast = Client.TextBroadcastsApi.Get(id.Id, "id,name"); Assert.Null(updatedBroadcast.Status); @@ -148,7 +148,7 @@ public void AddRecipientsAndAddRemoveBatches() new TextRecipient { PhoneNumber = "14246525473" }, new TextRecipient { PhoneNumber = "12132041238" } }; - var texts = Client.TextBroadcastsApi.AddRecipients((long)id, recipients); + var texts = Client.TextBroadcastsApi.AddRecipients((long)id, recipients, null, true); Console.WriteLine(texts); Assert.AreEqual(2, texts.Count); Assert.That(texts[0].Message, Is.StringStarting("test_msg")); @@ -167,7 +167,8 @@ public void AddRecipientsAndAddRemoveBatches() { new TextRecipient { PhoneNumber = "14246525473" }, new TextRecipient { PhoneNumber = "12132041238" } - } + }, + StrictValidation = true }; ResourceId addedBatchId = Client.TextBroadcastsApi.AddBatch(addBatchRequest); diff --git a/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactListsApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactListsApiIntegrationTest.cs index ae793fc..247e45d 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactListsApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Contacts/ContactListsApiIntegrationTest.cs @@ -25,7 +25,7 @@ public void TestFindContactLists() public void TestCreateContactListFromFile() { string path = "Resources/File-examples/contacts1.csv"; - ResourceId listId = Client.ContactListsApi.CreateFromCsv("fileList", Path.GetFullPath(path)); + ResourceId listId = Client.ContactListsApi.CreateFromCsv("fileList", Path.GetFullPath(path), true); ContactList contactList = Client.ContactListsApi.Get(listId.Id); Assert.AreEqual(2, contactList.Size); @@ -39,7 +39,8 @@ public void TestContactListCRUD() CreateContactListRequest request = new CreateContactListRequest { Contacts = new List { "12135543211", "12135678882" }, - Name = "listFromNumbers" + Name = "listFromNumbers", + UseCustomFields = true }; ResourceId numbersListId = Client.ContactListsApi.Create(request); @@ -93,14 +94,16 @@ public void TestContactListItemsCRUD() CreateContactListRequest request = new CreateContactListRequest { Contacts = new List { c1, c2 }, - Name = "listFromContacts" + Name = "listFromContacts", + UseCustomFields = true }; ResourceId id = Client.ContactListsApi.Create(request); AddContactListContactsRequest addItemsRequest = new AddContactListContactsRequest { ContactListId = id.Id, - Contacts = new List { "12345543211" } + Contacts = new List { "12345543211" }, + UseCustomFields = true }; Client.ContactListsApi.AddListItems(addItemsRequest); diff --git a/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs b/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs index 575117f..8832acf 100644 --- a/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs +++ b/src/CallfireApiClient.IntegrationTests/Api/Webhooks/WebhooksApiIntegrationTest.cs @@ -24,6 +24,9 @@ public void CrudOperations() Assert.NotNull(resourceId1.Id); webhook.Name = "test_name2"; var resourceId2 = api.Create(webhook); + webhook.Resource = ResourceType.CONTACT_LIST; + webhook.Events = new HashSet { ResourceEvent.VALIDATION_FINISHED }; + var resourceId3 = api.Create(webhook); var findRequest = new FindWebhooksRequest { @@ -50,6 +53,7 @@ public void CrudOperations() api.Delete((long)resourceId1.Id); api.Delete((long)resourceId2.Id); + api.Delete((long)resourceId3.Id); Assert.Throws(() => api.Get((long)resourceId1.Id)); Assert.Throws(() => api.Get((long)resourceId2.Id)); diff --git a/src/CallfireApiClient.Tests/Api/CallsTexts/CallsApiTest.cs b/src/CallfireApiClient.Tests/Api/CallsTexts/CallsApiTest.cs index a25a540..fd18ec2 100644 --- a/src/CallfireApiClient.Tests/Api/CallsTexts/CallsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/CallsTexts/CallsApiTest.cs @@ -24,7 +24,7 @@ public void SendCalls() var restRequest = MockRestResponse(responseJson); CallRecipient r1 = new CallRecipient { PhoneNumber = "12135551100", LiveMessage = "Why hello there!", TransferDigit = "1", TransferMessage = "testMessage", TransferNumber = "12135551101" }; - CallRecipient r2 = new CallRecipient { PhoneNumber = "12135551101", LiveMessage = "And hello to you too." }; + CallRecipient r2 = new CallRecipient { PhoneNumber = "12135551101", LiveMessage = "And hello to you too.", FromNumber = "12135551102" }; IList calls = Client.CallsApi.Send(new List { r1, r2 }); Assert.That(Serializer.Serialize(new ListHolder(calls)), Is.EqualTo(responseJson)); @@ -45,7 +45,7 @@ public void SendCallsUsingRequest() var restRequest = MockRestResponse(responseJson); CallRecipient r1 = new CallRecipient { PhoneNumber = "12135551100", LiveMessage = "Why hello there!", TransferDigit = "1", TransferMessage = "testMessage", TransferNumber = "12135551101" }; - CallRecipient r2 = new CallRecipient { PhoneNumber = "12135551101", LiveMessage = "And hello to you too." }; + CallRecipient r2 = new CallRecipient { PhoneNumber = "12135551101", LiveMessage = "And hello to you too.", FromNumber = "12135551102" }; var request = new SendCallsRequest { @@ -56,7 +56,8 @@ public void SendCallsUsingRequest() DefaultMachineMessage = "DefaultMachineMessage", DefaultLiveMessageSoundId = 1, DefaultMachineMessageSoundId = 1, - DefaultVoice = CallfireApiClient.Api.Campaigns.Model.Voice.FRENCHCANADIAN1 + DefaultVoice = Voice.FRENCHCANADIAN1, + StrictValidation = true }; IList calls = Client.CallsApi.Send(request); @@ -75,6 +76,7 @@ public void SendCallsUsingRequest() Assert.That(restRequest.Value.Resource, !Is.StringContaining("defaultMachineMessageSoundId=1")); Assert.That(restRequest.Value.Resource, !Is.StringContaining("defaultMachineMessageSoundId=1")); Assert.That(restRequest.Value.Resource, !Is.StringContaining("defaultVoice=FRENCHCANADIAN1")); + Assert.That(restRequest.Value.Resource, !Is.StringContaining("strictValidation=TRUE")); } [Test] diff --git a/src/CallfireApiClient.Tests/Api/CallsTexts/MediaApiTest.cs b/src/CallfireApiClient.Tests/Api/CallsTexts/MediaApiTest.cs index 67b6d85..4faba65 100644 --- a/src/CallfireApiClient.Tests/Api/CallsTexts/MediaApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/CallsTexts/MediaApiTest.cs @@ -3,6 +3,7 @@ using CallfireApiClient.Api.CallsTexts.Model; using RestSharp; using System; +using System.IO; namespace CallfireApiClient.Tests.Api.CallsTexts { @@ -24,6 +25,19 @@ public void Upload() Assert.AreEqual(Method.POST, restRequest.Value.Method); } + [Test] + public void UploadWithFileData() + { + string expectedJson = GetJsonPayload("/callstexts/mediaApi/response/uploadSound.json"); + var restRequest = MockRestResponse(expectedJson); + + string mp3FilePath = "Resources/File-examples/train.mp3"; + ResourceId id = Client.MediaApi.Upload(File.ReadAllBytes(mp3FilePath), MediaType.MP3, "fname"); + + Assert.That(Serializer.Serialize(id), Is.EqualTo(expectedJson)); + Assert.AreEqual(Method.POST, restRequest.Value.Method); + } + [Test] public void GetMedia() { diff --git a/src/CallfireApiClient.Tests/Api/CallsTexts/TextsApiTest.cs b/src/CallfireApiClient.Tests/Api/CallsTexts/TextsApiTest.cs index 7e7c813..0b328d1 100644 --- a/src/CallfireApiClient.Tests/Api/CallsTexts/TextsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/CallsTexts/TextsApiTest.cs @@ -20,7 +20,7 @@ public void SendTexts() var restRequest = MockRestResponse(responseJson); TextRecipient r1 = new TextRecipient { PhoneNumber = "12135551100", Message = "Hello World!" }; - TextRecipient r2 = new TextRecipient { PhoneNumber = "12135551101", Message = "Testing 1 2 3" }; + TextRecipient r2 = new TextRecipient { PhoneNumber = "12135551101", Message = "Testing 1 2 3", FromNumber = "12135551102" }; IList texts = Client.TextsApi.Send(new List { r1, r2 }); @@ -42,14 +42,15 @@ public void SendTextsUsingRequest() var restRequest = MockRestResponse(responseJson); TextRecipient r1 = new TextRecipient { PhoneNumber = "12135551100", Message = "Hello World!" }; - TextRecipient r2 = new TextRecipient { PhoneNumber = "12135551101", Message = "Testing 1 2 3" }; + TextRecipient r2 = new TextRecipient { PhoneNumber = "12135551101", Message = "Testing 1 2 3", FromNumber = "12135551102" }; var request = new SendTextsRequest { Recipients = new List { r1, r2 }, CampaignId = 100, Fields = FIELDS, - DefaultMessage = "defaultMessage" + DefaultMessage = "defaultMessage", + StrictValidation = true }; IList texts = Client.TextsApi.Send(request); @@ -61,6 +62,7 @@ public void SendTextsUsingRequest() 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("campaignId") && p.Value.Equals("100"))); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("defaultMessage") && p.Value.Equals("defaultMessage"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] diff --git a/src/CallfireApiClient.Tests/Api/Campaigns/CallBroadcastsApiTest.cs b/src/CallfireApiClient.Tests/Api/Campaigns/CallBroadcastsApiTest.cs index f98d186..f73a5cf 100644 --- a/src/CallfireApiClient.Tests/Api/Campaigns/CallBroadcastsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Campaigns/CallBroadcastsApiTest.cs @@ -40,13 +40,14 @@ public void CreateVoiceBroadcast() }, ResumeNextDay = true }; - var id = Client.CallBroadcastsApi.Create(callBroadcast, true); + var id = Client.CallBroadcastsApi.Create(callBroadcast, true, true); Assert.That(Serializer.Serialize(id), Is.EqualTo(responseJson)); Assert.AreEqual(Method.POST, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("start") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -120,12 +121,13 @@ public void UpdateVoiceBroadcast() }, ResumeNextDay = true }; - Client.CallBroadcastsApi.Update(callBroadcast); + Client.CallBroadcastsApi.Update(callBroadcast, true); Assert.AreEqual(Method.PUT, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.AreEqual(requestBodyParam.Value, expectedJson); Assert.That(restRequest.Value.Resource, Is.StringEnding("/11")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -310,7 +312,8 @@ public void AddBatch() { new Recipient { PhoneNumber = "12135551100" }, new Recipient { PhoneNumber = "12135551101" }, - } + }, + StrictValidation = true }; var id = Client.CallBroadcastsApi.AddBatch(request); Assert.That(Serializer.Serialize(id), Is.EqualTo(responseJson)); @@ -320,6 +323,7 @@ public void AddBatch() Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Parameters, Has.No.Some.Matches(p => p.Name.Equals("campaignId"))); Assert.That(restRequest.Value.Resource, Is.StringEnding("/15/batches")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -334,13 +338,14 @@ public void AddRecipients() new Recipient { PhoneNumber = "12135551100" }, new Recipient { PhoneNumber = "12135551101" }, }; - var calls = Client.CallBroadcastsApi.AddRecipients(15, recipients); + var calls = Client.CallBroadcastsApi.AddRecipients(15, recipients, null, true); Assert.That(Serializer.Serialize(new ListHolder(calls)), Is.EqualTo(responseJson)); Assert.AreEqual(Method.POST, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Resource, Is.StringEnding("/15/recipients")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); Client.CallBroadcastsApi.AddRecipients(15, recipients, FIELDS); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("fields") && p.Value.Equals(FIELDS))); diff --git a/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs b/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs index ed529a8..5379ad4 100644 --- a/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Campaigns/CampaignSoundsApiTest.cs @@ -5,6 +5,7 @@ using System.Linq; using CallfireApiClient.Api.CallsTexts.Model.Request; using CallfireApiClient.Api.Common.Model; +using System.IO; namespace CallfireApiClient.Tests.Api.Campaigns { @@ -127,6 +128,19 @@ public void TestUploadAndGetSoundDetailsWithFileNameAndFields() Assert.AreEqual(Method.POST, restRequest.Value.Method); } + [Test] + public void TestUploadWithFileData() + { + string expectedJson = GetJsonPayload("/campaigns/campaignSoundsApi/response/uploadSoundWithDetails.json"); + var restRequest = MockRestResponse(expectedJson); + + string mp3FilePath = "Resources/File-examples/train.mp3"; + CampaignSound sound = Client.CampaignSoundsApi.UploadAndGetSoundDetails(File.ReadAllBytes(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/Campaigns/TextBroadcastsApiTest.cs b/src/CallfireApiClient.Tests/Api/Campaigns/TextBroadcastsApiTest.cs index f398a78..8ff0a0a 100644 --- a/src/CallfireApiClient.Tests/Api/Campaigns/TextBroadcastsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Campaigns/TextBroadcastsApiTest.cs @@ -33,13 +33,14 @@ public void Create() }, ResumeNextDay = true }; - var id = Client.TextBroadcastsApi.Create(textBroadcast, true); + var id = Client.TextBroadcastsApi.Create(textBroadcast, true, true); Assert.That(Serializer.Serialize(id), Is.EqualTo(responseJson)); Assert.AreEqual(Method.POST, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("start") && p.Value.Equals("True"))); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -78,14 +79,15 @@ public void Update() Id = 11, Name = "Example API SMS updated", Message = "a new test message", - ResumeNextDay = true + ResumeNextDay = true, }; - Client.TextBroadcastsApi.Update(textBroadcast); + Client.TextBroadcastsApi.Update(textBroadcast, true); Assert.AreEqual(Method.PUT, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.AreEqual(requestBodyParam.Value, expectedJson); Assert.That(restRequest.Value.Resource, Is.StringEnding("/11")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -250,7 +252,8 @@ public void AddBatch() { new TextRecipient { PhoneNumber = "12135551122" }, new TextRecipient { PhoneNumber = "12135551123" }, - } + }, + StrictValidation = true }; var id = Client.TextBroadcastsApi.AddBatch(request); Assert.That(Serializer.Serialize(id), Is.EqualTo(responseJson)); @@ -260,6 +263,7 @@ public void AddBatch() Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Parameters, Has.No.Some.Matches(p => p.Name.Equals("campaignId"))); Assert.That(restRequest.Value.Resource, Is.StringEnding("/15/batches")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); } [Test] @@ -274,13 +278,14 @@ public void AddRecipients() new TextRecipient { PhoneNumber = "12135551100" }, new TextRecipient { PhoneNumber = "12135551101" }, }; - var texts = Client.TextBroadcastsApi.AddRecipients(15, recipients); + var texts = Client.TextBroadcastsApi.AddRecipients(15, recipients, null, true); Assert.That(Serializer.Serialize(new ListHolder(texts)), Is.EqualTo(responseJson)); Assert.AreEqual(Method.POST, restRequest.Value.Method); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); Assert.That(requestBodyParam.Value, Is.EqualTo(requestJson)); Assert.That(restRequest.Value.Resource, Is.StringEnding("/15/recipients")); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("strictValidation") && p.Value.Equals("True"))); Client.TextBroadcastsApi.AddRecipients(15, recipients, FIELDS); Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("fields") && p.Value.Equals(FIELDS))); diff --git a/src/CallfireApiClient.Tests/Api/Contacts/ContactListsApiTest.cs b/src/CallfireApiClient.Tests/Api/Contacts/ContactListsApiTest.cs index ac7d192..c3c5568 100644 --- a/src/CallfireApiClient.Tests/Api/Contacts/ContactListsApiTest.cs +++ b/src/CallfireApiClient.Tests/Api/Contacts/ContactListsApiTest.cs @@ -114,7 +114,8 @@ public void Create() CreateContactListRequest requestContact = new CreateContactListRequest { Name = "listFromContacts", - Contacts = new List { c1, c2 } + Contacts = new List { c1, c2 }, + UseCustomFields = true }; ResourceId res = Client.ContactListsApi.Create(requestContact); @@ -129,10 +130,11 @@ public void TestCreateFromCsv() string responseJson = GetJsonPayload("/contacts/contactsApi/response/createContactList.json"); var restRequest = MockRestResponse(responseJson); - ResourceId resourceId = Client.ContactListsApi.CreateFromCsv("fileList", "Resources/File-examples/contacts1.csv"); + ResourceId resourceId = Client.ContactListsApi.CreateFromCsv("fileList", "Resources/File-examples/contacts1.csv", true); Assert.That(Serializer.Serialize(resourceId), Is.EqualTo(responseJson)); Assert.AreEqual(Method.POST, restRequest.Value.Method); + Assert.That(restRequest.Value.Parameters, Has.Some.Matches(p => p.Name.Equals("useCustomFields") && p.Value.Equals("True"))); } [Test] @@ -225,8 +227,8 @@ public void TestAddContactsToContactListByNullId() [Test] public void TestAddContactsToContactListById() { - string expectedJson = GetJsonPayload("/contacts/contactsApi/response/addContactsToContactList.json"); - var restRequest = MockRestResponse(expectedJson); + string requestJson = GetJsonPayload("/contacts/contactsApi/response/addContactsToContactList.json"); + var restRequest = MockRestResponse(requestJson); Contact c1 = new Contact { HomePhone = "123456" }; Contact c2 = new Contact { HomePhone = "123457" }; @@ -235,13 +237,14 @@ public void TestAddContactsToContactListById() { ContactNumbersField = "homePhone", ContactListId = TEST_LONG, - Contacts = new List { c1, c2 } + Contacts = new List { c1, c2 }, + UseCustomFields = true }; Client.ContactListsApi.AddListItems(request); var requestBodyParam = restRequest.Value.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody); - Assert.AreEqual(requestBodyParam.Value, expectedJson); + Assert.AreEqual(requestBodyParam.Value, requestJson); Assert.AreEqual(Method.POST, restRequest.Value.Method); Assert.That(restRequest.Value.Resource, Is.StringContaining("/" + TEST_LONG)); } diff --git a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/request/sendCalls.json b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/request/sendCalls.json index 773bd71..933b11f 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/request/sendCalls.json +++ b/src/CallfireApiClient.Tests/JsonMocks/callstexts/callsApi/request/sendCalls.json @@ -8,6 +8,7 @@ }, { "phoneNumber": "12135551101", + "fromNumber": "12135551102", "liveMessage": "And hello to you too." } ] \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/JsonMocks/callstexts/textsApi/request/sendTexts.json b/src/CallfireApiClient.Tests/JsonMocks/callstexts/textsApi/request/sendTexts.json index ff93487..e71b7c4 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/callstexts/textsApi/request/sendTexts.json +++ b/src/CallfireApiClient.Tests/JsonMocks/callstexts/textsApi/request/sendTexts.json @@ -5,6 +5,7 @@ }, { "phoneNumber": "12135551101", + "fromNumber": "12135551102", "message": "Testing 1 2 3" } ] \ No newline at end of file diff --git a/src/CallfireApiClient.Tests/JsonMocks/contacts/contactsApi/response/addContactsToContactList.json b/src/CallfireApiClient.Tests/JsonMocks/contacts/contactsApi/response/addContactsToContactList.json index 8b9f6a1..e25d3e1 100644 --- a/src/CallfireApiClient.Tests/JsonMocks/contacts/contactsApi/response/addContactsToContactList.json +++ b/src/CallfireApiClient.Tests/JsonMocks/contacts/contactsApi/response/addContactsToContactList.json @@ -1,5 +1,6 @@ { "contactNumbersField": "homePhone", + "useCustomFields": true, "contacts": [ {"homePhone": "123456"}, {"homePhone": "123457"} diff --git a/src/CallfireApiClient/Api/CallsTexts/MediaApi.cs b/src/CallfireApiClient/Api/CallsTexts/MediaApi.cs index 0d4498c..7761ca0 100644 --- a/src/CallfireApiClient/Api/CallsTexts/MediaApi.cs +++ b/src/CallfireApiClient/Api/CallsTexts/MediaApi.cs @@ -38,6 +38,25 @@ public ResourceId Upload(string pathToFile, string name = null) return Client.PostFile(MEDIA_PATH, name, pathToFile, ClientUtils.EnumMemberAttr(type)); } + /// + /// Upload media file to account + /// + /// binary file data to upload + /// media type for file uploaded + /// name for file uploaded + /// ResourceId object with sound id + /// 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 ResourceId Upload(byte[] fileData, MediaType type, string name = null) + { + return Client.PostFile(MEDIA_PATH, fileData, name, ClientUtils.EnumMemberAttr(type)); + } + /// /// Returns a single Media instance for a given media file id. This is the metadata /// for the media only.No content data is returned from this API. diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/Request/FindCallsRequest.cs b/src/CallfireApiClient/Api/CallsTexts/Model/Request/FindCallsRequest.cs index f38f6dc..c645753 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/Request/FindCallsRequest.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/Request/FindCallsRequest.cs @@ -1,6 +1,4 @@ using System.Collections.Generic; -using CallfireApiClient.Api.CallsTexts.Model; -using CallfireApiClient.Api.Common.Model.Request; namespace CallfireApiClient.Api.CallsTexts.Model.Request { diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsRequest.cs b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsRequest.cs index 30ed384..12e4ec2 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsRequest.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsRequest.cs @@ -1,22 +1,17 @@ - - -using CallfireApiClient.Api.CallsTexts.Model; using CallfireApiClient.Api.Campaigns.Model; using Newtonsoft.Json; using System.Collections.Generic; -namespace CallfireApiClient.Api.Common.Model.Request +namespace CallfireApiClient.Api.CallsTexts.Model.Request { /// - /// Contains fields to send calls (recipients, campaignId etc) + /// Contains fields to send calls (Recipients, DefaultVoice etc) /// - public class SendCallsRequest : CallfireModel + public class SendCallsRequest : SendCallsTextsRequest { [JsonIgnore] public List Recipients; - public long? CampaignId { get; set; } - public string DefaultLiveMessage { get; set; } public string DefaultMachineMessage { get; set; } @@ -27,8 +22,6 @@ public class SendCallsRequest : CallfireModel public Voice DefaultVoice { get; set; } - public string Fields { get; set; } - public SendCallsRequest() { Recipients = new List(); @@ -36,8 +29,8 @@ public SendCallsRequest() public override string ToString() { - return string.Format("[SendCallsRequest: Recipients={0}, CampaignId={1}, DefaultLiveMessage={2}, DefaultMachineMessage={3}, DefaultLiveMessageSoundId={4}, DefaultMachineMessageSoundId ={5}, DefaultVoice ={6}, Fields ={7}]", - Recipients, CampaignId, DefaultLiveMessage, DefaultMachineMessage, DefaultLiveMessageSoundId, DefaultMachineMessageSoundId, DefaultVoice, Fields); + return string.Format("[SendCallsRequest: {0}, Recipients={1}, DefaultLiveMessage={2}, DefaultMachineMessage={3}, DefaultLiveMessageSoundId={4}, DefaultMachineMessageSoundId ={5}, DefaultVoice ={6}]", + base.ToString(), Recipients.ToPrettyString(), DefaultLiveMessage, DefaultMachineMessage, DefaultLiveMessageSoundId, DefaultMachineMessageSoundId, DefaultVoice); } } } diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsTextsRequest.cs b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsTextsRequest.cs new file mode 100644 index 0000000..4a180f8 --- /dev/null +++ b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendCallsTextsRequest.cs @@ -0,0 +1,20 @@ +using CallfireApiClient.Api.Common.Model; + +namespace CallfireApiClient.Api.CallsTexts.Model.Request +{ + public abstract class SendCallsTextsRequest : CallfireModel + { + public long? CampaignId { get; set; } + + public string Fields { get; set; } + + public bool? StrictValidation { get; set; } + + public override string ToString() + { + return string.Format("[SendCallsTextsRequest: campaignId={0}, fields={1}, strictValidation={2}]]", + CampaignId, Fields, StrictValidation); + } + } +} + diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendTextsRequest.cs b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendTextsRequest.cs index e2b7345..5d6ebf1 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendTextsRequest.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/Request/SendTextsRequest.cs @@ -1,26 +1,18 @@ - - -using CallfireApiClient.Api.CallsTexts.Model; -using CallfireApiClient.Api.Campaigns.Model; using Newtonsoft.Json; using System.Collections.Generic; -namespace CallfireApiClient.Api.Common.Model.Request +namespace CallfireApiClient.Api.CallsTexts.Model.Request { /// - /// Contains fields to send texts (recipients, campaignId etc) + /// Contains fields to send texts (Recipients, DefaultMessage etc) /// - public class SendTextsRequest : CallfireModel + public class SendTextsRequest : SendCallsTextsRequest { [JsonIgnore] public List Recipients; - public long? CampaignId { get; set; } - public string DefaultMessage { get; set; } - public string Fields { get; set; } - public SendTextsRequest() { Recipients = new List(); @@ -28,8 +20,8 @@ public SendTextsRequest() public override string ToString() { - return string.Format("[SendCallsRequest: Recipients={0}, CampaignId={1}, DefaultMessage={2}, Fields ={3}]", - Recipients, CampaignId, DefaultMessage, Fields); + return string.Format("[SendCallsRequest: {0}, Recipients={1}, DefaultMessage={2}]", + base.ToString(), Recipients.ToPrettyString(), DefaultMessage); } } } diff --git a/src/CallfireApiClient/Api/CallsTexts/Model/TextRecipient.cs b/src/CallfireApiClient/Api/CallsTexts/Model/TextRecipient.cs index 97e8b59..01639c4 100644 --- a/src/CallfireApiClient/Api/CallsTexts/Model/TextRecipient.cs +++ b/src/CallfireApiClient/Api/CallsTexts/Model/TextRecipient.cs @@ -1,4 +1,5 @@ using CallfireApiClient.Api.Campaigns.Model; +using System.Collections.Generic; namespace CallfireApiClient.Api.CallsTexts.Model { @@ -6,10 +7,11 @@ public class TextRecipient : Recipient { public string Message { get; set; } + public IList Media { get; set; } + public override string ToString() { - return string.Format("[TextRecipient: {0}, Message={1}]", base.ToString(), Message); + return string.Format("[TextRecipient: {0}, Message={1}, Media={2}]", base.ToString(), Message, Media.ToPrettyString()); } } -} - +} \ No newline at end of file diff --git a/src/CallfireApiClient/Api/CallsTexts/TextsApi.cs b/src/CallfireApiClient/Api/CallsTexts/TextsApi.cs index 20a37f8..004ae99 100644 --- a/src/CallfireApiClient/Api/CallsTexts/TextsApi.cs +++ b/src/CallfireApiClient/Api/CallsTexts/TextsApi.cs @@ -2,7 +2,6 @@ using CallfireApiClient.Api.CallsTexts.Model; using System.Collections.Generic; using CallfireApiClient.Api.CallsTexts.Model.Request; -using CallfireApiClient.Api.Common.Model.Request; namespace CallfireApiClient.Api.CallsTexts { @@ -80,7 +79,7 @@ public IList Send(List recipients, long? campaignId = null, Validate.NotBlank(recipients.ToString(), "recipients cannot be blank"); var queryParams = new List>(2); ClientUtils.AddQueryParamIfSet("campaignId", campaignId, queryParams); - ClientUtils.AddQueryParamIfSet("fields", fields, queryParams); + ClientUtils.AddQueryParamIfSet("fields", fields, queryParams); return Client.Post>(TEXTS_PATH, recipients, queryParams).Items; } diff --git a/src/CallfireApiClient/Api/Campaigns/CallBroadcastsApi.cs b/src/CallfireApiClient/Api/Campaigns/CallBroadcastsApi.cs index 714fd7a..7ffece9 100644 --- a/src/CallfireApiClient/Api/Campaigns/CallBroadcastsApi.cs +++ b/src/CallfireApiClient/Api/Campaigns/CallBroadcastsApi.cs @@ -53,6 +53,7 @@ public Page Find(FindBroadcastsRequest request) /// /// call broadcast to create /// if set to true then broadcast will start immediately, by default it set to false + /// apply strict validation for contacts /// ResourceId object with id of created broadcast /// 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. @@ -61,9 +62,11 @@ public Page Find(FindBroadcastsRequest 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 ResourceId Create(CallBroadcast broadcast, bool start = false) + public ResourceId Create(CallBroadcast broadcast, bool start = false, bool? strictValidation = null) { - var queryParams = ClientUtils.BuildQueryParams("start", start.ToString()); + var queryParams = new List>(2); + ClientUtils.AddQueryParamIfSet("start", start.ToString(), queryParams); + ClientUtils.AddQueryParamIfSet("strictValidation", strictValidation.ToString(), queryParams); return Client.Post(CB_PATH, broadcast, queryParams); } @@ -91,6 +94,7 @@ public CallBroadcast Get(long id, string fields = null) /// Update broadcast /// /// broadcast to update + /// apply strict validation for contacts /// 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. @@ -98,10 +102,11 @@ public CallBroadcast Get(long id, string fields = null) /// 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(CallBroadcast broadcast) + public void Update(CallBroadcast broadcast, bool? strictValidation = null) { Validate.NotNull(broadcast.Id, "broadcast.id cannot be null"); - Client.Put(CB_ITEM_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, broadcast.Id.ToString()), broadcast); + var queryParams = ClientUtils.BuildQueryParams("strictValidation", strictValidation.ToString()); + Client.Put(CB_ITEM_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, broadcast.Id.ToString()), broadcast, queryParams); } /// @@ -189,7 +194,8 @@ public Page GetBatches(GetByIdRequest request) public ResourceId AddBatch(AddBatchRequest request) { String path = CB_ITEM_BATCHES_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, request.CampaignId.ToString()); - return Client.Post(path, request); + var queryParams = ClientUtils.BuildQueryParams("strictValidation", request.StrictValidation.ToString()); + return Client.Post(path, request, queryParams); } /// @@ -263,6 +269,7 @@ public CallBroadcastStats GetStats(long id, string fields = null, DateTime? begi /// id of call broadcast /// recipients to add /// limit fields returned. E.g. fields=id,name or fields=items(id,name) + /// apply strict validation for contacts /// Call 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. @@ -271,9 +278,11 @@ public CallBroadcastStats GetStats(long id, string fields = null, DateTime? begi /// 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 AddRecipients(long id, IList recipients, String fields = null) + public IList AddRecipients(long id, IList recipients, String fields = null, bool? strictValidation = null) { - var queryParams = ClientUtils.BuildQueryParams("fields", fields); + var queryParams = new List>(2); + ClientUtils.AddQueryParamIfSet("fields", fields, queryParams); + ClientUtils.AddQueryParamIfSet("strictValidation", strictValidation, queryParams); string path = CB_ITEM_RECIPIENTS_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, id.ToString()); return Client.Post>(path, recipients, queryParams).Items; } diff --git a/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs b/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs index fdd262d..c122714 100644 --- a/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs +++ b/src/CallfireApiClient/Api/Campaigns/CampaignSoundsApi.cs @@ -139,7 +139,7 @@ public ResourceId RecordViaPhone(CallCreateSound callCreateSound) /// the CallCreateSound object inside of the request, and the user will receive a call /// shortly after with instructions on how to record a sound over the phone. /// - /// request object to create campaign sound + /// request object to create campaign sound /// 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. @@ -195,7 +195,7 @@ public CampaignSound UploadAndGetSoundDetails(string pathToFile, string name = n /// /// Upload a MP3 or WAV file to account /// - /// contact list name + /// file name /// path to MP3 or WAV file /// Limit text fields returned. Example fields=limit,offset,items(id,message) /// CampaignSound object with sound details @@ -212,6 +212,26 @@ public CampaignSound UploadAndGetSoundDetails(string pathToFile, string name, st return Client.PostFile(SOUNDS_FILES_PATH, name, pathToFile, queryParams); } + /// + /// Upload a MP3 or WAV file to account + /// + /// binary file data to upload + /// file name + /// 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(byte[] fileData, string name = null, string fields = null) + { + var queryParams = ClientUtils.BuildQueryParams("fields", fields); + return Client.PostFile(SOUNDS_FILES_PATH, fileData, name, null, queryParams); + } + /// /// Use this API to create a sound file via a supplied string of text. /// diff --git a/src/CallfireApiClient/Api/Campaigns/Model/Recipient.cs b/src/CallfireApiClient/Api/Campaigns/Model/Recipient.cs index 2e9f1ac..518e689 100644 --- a/src/CallfireApiClient/Api/Campaigns/Model/Recipient.cs +++ b/src/CallfireApiClient/Api/Campaigns/Model/Recipient.cs @@ -7,14 +7,16 @@ public class Recipient : CallfireModel { public string PhoneNumber { get; set; } + public string FromNumber { get; set; } + public long? ContactId { get; set; } public IDictionary Attributes = new Dictionary(); public override string ToString() { - return string.Format("[Recipient: phoneNumber={0}, contactId={1}, attributes={2}]", - PhoneNumber, ContactId, Attributes.ToPrettyString()); + return string.Format("[Recipient: phoneNumber={0}, fromNumber={1}, contactId={2}, attributes={3}]", + PhoneNumber, FromNumber, ContactId, Attributes.ToPrettyString()); } } } diff --git a/src/CallfireApiClient/Api/Campaigns/Model/Request/AddBatchRequest.cs b/src/CallfireApiClient/Api/Campaigns/Model/Request/AddBatchRequest.cs index 2f1de54..2a01bcb 100644 --- a/src/CallfireApiClient/Api/Campaigns/Model/Request/AddBatchRequest.cs +++ b/src/CallfireApiClient/Api/Campaigns/Model/Request/AddBatchRequest.cs @@ -1,5 +1,4 @@ -using System; -using CallfireApiClient.Api.Common.Model; +using CallfireApiClient.Api.Common.Model; using System.Collections.Generic; using Newtonsoft.Json; @@ -10,6 +9,9 @@ public class AddBatchRequest : CallfireModel [JsonIgnore] public long CampaignId { get; set; } + [JsonIgnore] + public bool? StrictValidation { get; set; } + public string Name { get; set; } public long? ContactListId { get; set; } @@ -20,8 +22,8 @@ public class AddBatchRequest : CallfireModel public override string ToString() { - return string.Format("[AddBatchRequest: CampaignId={0}, Name={1}, ContactListId={2}, ScrubDuplicates={3}, Recipients={4}]", - CampaignId, Name, ContactListId, ScrubDuplicates, Recipients); + return string.Format("[AddBatchRequest: CampaignId={0}, Name={1}, ContactListId={2}, ScrubDuplicates={3}, Recipients={4}, StrictValidation={5}]", + CampaignId, Name, ContactListId, ScrubDuplicates, Recipients, StrictValidation); } } } diff --git a/src/CallfireApiClient/Api/Campaigns/TextBroadcastsApi.cs b/src/CallfireApiClient/Api/Campaigns/TextBroadcastsApi.cs index 2ed96c8..47ddcea 100644 --- a/src/CallfireApiClient/Api/Campaigns/TextBroadcastsApi.cs +++ b/src/CallfireApiClient/Api/Campaigns/TextBroadcastsApi.cs @@ -54,6 +54,7 @@ public Page Find(FindBroadcastsRequest request) /// /// text broadcast to create /// if set to true then broadcast will start immediately, by default it set to false + /// apply strict validation for contacts /// ResourceId object with id of created broadcast /// 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. @@ -62,9 +63,11 @@ public Page Find(FindBroadcastsRequest 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 ResourceId Create(TextBroadcast broadcast, bool start = false) + public ResourceId Create(TextBroadcast broadcast, bool start = false, bool? strictValidation = null) { - var queryParams = ClientUtils.BuildQueryParams("start", start.ToString()); + var queryParams = new List>(2); + ClientUtils.AddQueryParamIfSet("start", start.ToString(), queryParams); + ClientUtils.AddQueryParamIfSet("strictValidation", strictValidation.ToString(), queryParams); return Client.Post(TB_PATH, broadcast, queryParams); } @@ -92,6 +95,7 @@ public TextBroadcast Get(long id, string fields = null) /// Update broadcast /// /// broadcast to update + /// apply strict validation for contacts /// 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. @@ -99,10 +103,11 @@ public TextBroadcast Get(long id, string fields = null) /// 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(TextBroadcast broadcast) + public void Update(TextBroadcast broadcast, bool? strictValidation = null) { Validate.NotNull(broadcast.Id, "broadcast.id cannot be null"); - Client.Put(TB_ITEM_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, broadcast.Id.ToString()), broadcast); + var queryParams = ClientUtils.BuildQueryParams("strictValidation", strictValidation.ToString()); + Client.Put(TB_ITEM_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, broadcast.Id.ToString()), broadcast, queryParams); } /// @@ -190,7 +195,8 @@ public Page GetBatches(GetByIdRequest request) public ResourceId AddBatch(AddBatchRequest request) { String path = TB_ITEM_BATCHES_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, request.CampaignId.ToString()); - return Client.Post(path, request); + var queryParams = ClientUtils.BuildQueryParams("strictValidation", request.StrictValidation.ToString()); + return Client.Post(path, request, queryParams); } /// @@ -264,6 +270,7 @@ public TextBroadcastStats GetStats(long id, string fields = null, DateTime? begi /// id of text broadcast /// recipients to add /// limit fields returned. E.g. fields=id,name or fields=items(id,name) + /// apply strict validation for contacts /// Text 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. @@ -272,9 +279,11 @@ public TextBroadcastStats GetStats(long id, string fields = null, DateTime? begi /// 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 AddRecipients(long id, IList recipients, String fields = null) + public IList AddRecipients(long id, IList recipients, String fields = null, bool? strictValidation = null) { - var queryParams = ClientUtils.BuildQueryParams("fields", fields); + var queryParams = new List>(2); + ClientUtils.AddQueryParamIfSet("fields", fields, queryParams); + ClientUtils.AddQueryParamIfSet("strictValidation", strictValidation, queryParams); string path = TB_ITEM_RECIPIENTS_PATH.ReplaceFirst(ClientConstants.PLACEHOLDER, id.ToString()); return Client.Post>(path, recipients, queryParams).Items; } diff --git a/src/CallfireApiClient/Api/Contacts/ContactListsApi.cs b/src/CallfireApiClient/Api/Contacts/ContactListsApi.cs index ed05b7b..c864c70 100644 --- a/src/CallfireApiClient/Api/Contacts/ContactListsApi.cs +++ b/src/CallfireApiClient/Api/Contacts/ContactListsApi.cs @@ -89,6 +89,7 @@ public ResourceId Create(CreateContactListRequest request) /// /// contact list name /// path to CSV file with contacts to upload + /// A flag to indicate how to define property names for contacts. If true, uses the field and property names exactly as defined. If false will assign custom properties and fields to A, B, C, etc /// newly created contact list id /// 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. @@ -97,9 +98,12 @@ public ResourceId Create(CreateContactListRequest 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 ResourceId CreateFromCsv(string name, string filePath) + public ResourceId CreateFromCsv(string name, string filePath, bool? useCustomFields = null) { - return Client.PostFile(LISTS_UPLOAD_PATH, name, filePath); + var formParams = new List>(2); + ClientUtils.AddQueryParamIfSet("name", name, formParams); + ClientUtils.AddQueryParamIfSet("useCustomFields", useCustomFields, formParams); + return Client.PostFile(LISTS_UPLOAD_PATH, filePath, formParams); } /// diff --git a/src/CallfireApiClient/Api/Contacts/Model/Request/AddContactsRequest.cs b/src/CallfireApiClient/Api/Contacts/Model/Request/AddContactsRequest.cs index ae3ac7a..386d1e6 100644 --- a/src/CallfireApiClient/Api/Contacts/Model/Request/AddContactsRequest.cs +++ b/src/CallfireApiClient/Api/Contacts/Model/Request/AddContactsRequest.cs @@ -19,6 +19,8 @@ public class AddContactsRequest : CallfireModel public string ContactNumbersField { get; set; } + public bool? UseCustomFields { get; set; } + [OnSerializing] private void OnSerializing(StreamingContext context) { @@ -48,7 +50,7 @@ private void OnSerializing(StreamingContext context) public override string ToString() { - return string.Format("[AddContactsRequest: Contacts={0}, ContactNumbersField={1}]", Contacts?.ToPrettyString(), ContactNumbersField); + return string.Format("[AddContactsRequest: Contacts={0}, ContactNumbersField={1}, UseCustomFields={2}]", Contacts?.ToPrettyString(), ContactNumbersField, UseCustomFields); } } diff --git a/src/CallfireApiClient/Api/Webhooks/Model/ResourceType.cs b/src/CallfireApiClient/Api/Webhooks/Model/ResourceType.cs index 5b76e32..520ed21 100644 --- a/src/CallfireApiClient/Api/Webhooks/Model/ResourceType.cs +++ b/src/CallfireApiClient/Api/Webhooks/Model/ResourceType.cs @@ -12,6 +12,10 @@ public enum ResourceEvent FINISHED, [EnumMember(Value = "Failed")] FAILED, + [EnumMember(Value = "ValidationFinished")] + VALIDATION_FINISHED, + [EnumMember(Value = "ValidationFailed")] + VALIDATION_FAILED, [EnumMember(Value = "unknown")] UNKNOWN } @@ -36,6 +40,8 @@ public enum ResourceType OUTBOUND_TEXT, [EnumMember(Value = "InboundText")] INBOUND_TEXT, + [EnumMember(Value = "ContactList")] + CONTACT_LIST, [EnumMember(Value = "unknown")] UNKNOWN } diff --git a/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs b/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs index 9c7bd01..1c42831 100644 --- a/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs +++ b/src/CallfireApiClient/Api/Webhooks/Model/Webhook.cs @@ -41,6 +41,7 @@ public class Webhook : CallfireModel { ResourceType.OUTBOUND_CALL, new HashSet { ResourceEvent.FINISHED } }, { ResourceType.INBOUND_TEXT, new HashSet { ResourceEvent.FINISHED } }, { ResourceType.OUTBOUND_TEXT, new HashSet { ResourceEvent.FINISHED } }, + { ResourceType.CONTACT_LIST, new HashSet { ResourceEvent.VALIDATION_FINISHED, ResourceEvent.VALIDATION_FAILED } }, { ResourceType.UNKNOWN, new HashSet { } } }; diff --git a/src/CallfireApiClient/CallfireApiClient.csproj b/src/CallfireApiClient/CallfireApiClient.csproj index 23b3f3a..49ff27d 100644 --- a/src/CallfireApiClient/CallfireApiClient.csproj +++ b/src/CallfireApiClient/CallfireApiClient.csproj @@ -59,6 +59,7 @@ + diff --git a/src/CallfireApiClient/Properties/AssemblyInfo.cs b/src/CallfireApiClient/Properties/AssemblyInfo.cs index 4631343..b60a352 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.18.*")] +[assembly: AssemblyVersion("1.1.19.*")] // 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 36972f4..e9819d9 100644 --- a/src/CallfireApiClient/RestApiClient.cs +++ b/src/CallfireApiClient/RestApiClient.cs @@ -310,14 +310,44 @@ public Stream GetFileData(string path, IEnumerable> /// in case error has occurred in client. public T PostFile(String path, string fileName, string filePath, string contentType = null) where T : new() { - var queryParams = ClientUtils.BuildQueryParams("name", fileName); - var restRequest = CreateRestRequest(path, Method.POST, queryParams); + var restRequest = CreateRestRequest(path, Method.POST); restRequest.AddHeader("Content-Type", "multipart/form-data"); restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), contentType != null ? contentType : ClientConstants.DEFAULT_FILE_CONTENT_TYPE); restRequest.AddParameter("name", fileName); 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 + /// path to file + /// form parameters to include in request + /// 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 filePath, IList> formParams) where T : new() + { + var restRequest = CreateRestRequest(path, Method.POST); + restRequest.AddHeader("Content-Type", "multipart/form-data"); + restRequest.AddFileBytes("file", File.ReadAllBytes(filePath), Path.GetFileName(filePath), ClientConstants.DEFAULT_FILE_CONTENT_TYPE); + + foreach (KeyValuePair pair in formParams) + { + restRequest.AddParameter(pair.Key, pair.Value.ToString()); + } + + return DoRequest(restRequest); + } + + + /// /// Performs POST request with binary body to specified path /// @@ -334,11 +364,8 @@ public Stream GetFileData(string path, IEnumerable> /// 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() + public T PostFile(String path, string fileName, string filePath, IList> queryParams) 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), ClientConstants.DEFAULT_FILE_CONTENT_TYPE); @@ -346,6 +373,32 @@ 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 + /// binary file data to upload + /// name of file + /// media type for file uploaded + /// 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, byte[] fileData, string fileName, string contentType = null, IList> queryParams = null) where T : new() + { + var restRequest = CreateRestRequest(path, Method.POST, queryParams); + restRequest.AddHeader("Content-Type", "multipart/form-data"); + restRequest.AddFileBytes("file", fileData, fileName, contentType != null ? contentType : ClientConstants.DEFAULT_FILE_CONTENT_TYPE); + restRequest.AddParameter("name", fileName); + return DoRequest(restRequest); + } + /// /// Performs PUT request with body to specified path ///