diff --git a/MessageMedia.SDK.Messages/Models/Message.cs b/MessageMedia.SDK.Messages/Models/Message.cs index 60db7a1..ea5fcd7 100644 --- a/MessageMedia.SDK.Messages/Models/Message.cs +++ b/MessageMedia.SDK.Messages/Models/Message.cs @@ -1,66 +1,78 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; namespace MessageMedia.Messages.Models { public struct Message { - [JsonProperty("message_id")] public string MessageId { get; set; } + [JsonProperty("message_id", NullValueHandling = NullValueHandling.Ignore)] public string MessageId { get; set; } /// /// Urls of the media files to send in the Message /// /// Only valid if the Format is MMS /// - [JsonProperty("media")] public string[] Media { get; set; } + [JsonProperty("media", NullValueHandling = NullValueHandling.Ignore)] public string[] Media { get; set; } - [JsonProperty("status")] public MessageStatus Status { get; set; } + /// + /// Subject of the Message + /// + /// Only valid if the Format is MMS + /// + [JsonProperty("subject", NullValueHandling = NullValueHandling.Ignore)] public string Subject { get; set; } + + [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] + public MessageStatus? Status { get; set; } /// /// Replies and delivery reports for this message will be pushed to the URL" /// - [JsonProperty("callback_url")] public string CallbackUrl { get; set; } + [JsonProperty("callback_url", NullValueHandling = NullValueHandling.Ignore)] public string CallbackUrl { get; set; } /// /// Content of the message /// Hello world! /// - [JsonProperty("content")] public string Content { get; set; } + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] public string Content { get; set; } /// /// Destination number of the message /// +61491570156 /// - [JsonProperty("destination_number")] public string DestinationNumber { get; set; } + [JsonProperty("destination_number", NullValueHandling = NullValueHandling.Ignore)] public string DestinationNumber { get; set; } /// /// Request a delivery report for this message /// - [JsonProperty("delivery_report")] public bool DeliveryReport { get; set; } + [JsonProperty("delivery_report", NullValueHandling = NullValueHandling.Ignore)] public bool DeliveryReport { get; set; } /// /// Format of message, SMS or TTS (Text To Speech). /// - [JsonProperty("format")] public MessageFormat Format { get; set; } + [JsonProperty("format", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] + public MessageFormat Format { get; set; } /// /// Date time after which the message expires and will not be sent /// - [JsonProperty("message_expiry_timestamp")] - public DateTime MessageExpiryTimestamp { get; set; } + [JsonProperty("message_expiry_timestamp", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? MessageExpiryTimestamp { get; set; } /// /// Metadata for the message specified as a set of key value pairs. /// /// Each key can be up to 100 characters long and each value can be up to 256 characters long. /// - [JsonProperty("metadata")] public Dictionary Metadata { get; set; } + [JsonProperty("metadata", NullValueHandling = NullValueHandling.Ignore)] public Dictionary Metadata { get; set; } /// /// Scheduled delivery date time of the message /// - [JsonProperty("scheduled")] public DateTime Scheduled { get; set; } + [JsonProperty("scheduled", NullValueHandling = NullValueHandling.Ignore)] public DateTime? Scheduled { get; set; } /// /// Source of the message @@ -70,11 +82,13 @@ public struct Message /// /// By default this feature is not available and will be ignored in the request. Please contact support@messagemedia.com for more information. Specifying a source number is optional and a by default a source number will be assigned to the message. /// - [JsonProperty("source_number")] public string SourceNumber { get; set; } + [JsonProperty("source_number", NullValueHandling = NullValueHandling.Ignore)] public string SourceNumber { get; set; } /// /// Type of source address specified /// - [JsonProperty("source_number_type")] public NumberType SourceNumberType { get; set; } + [JsonProperty("source_number_type", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(StringEnumConverter))] + public NumberType SourceNumberType { get; set; } } } \ No newline at end of file diff --git a/MessageMediaMessages.Tests/MessagesControllerTest.cs b/MessageMediaMessages.Tests/MessagesControllerTest.cs index ab6a965..f0b1e96 100644 --- a/MessageMediaMessages.Tests/MessagesControllerTest.cs +++ b/MessageMediaMessages.Tests/MessagesControllerTest.cs @@ -99,7 +99,38 @@ public static void SetUpClass() public async Task TestSendMessages1() { // Parameters for the API call - SendMessagesRequest body = APIHelper.JsonDeserialize("{ \"messages\": [ { \"callback_url\": \"https://my.callback.url.com\", \"content\": \"My first message\", \"destination_number\": \"+61491570156\", \"delivery_report\": true, \"format\": \"SMS\", \"message_expiry_timestamp\": \"2016-11-03T11:49:02.807Z\", \"metadata\": { \"key1\": \"value1\", \"key2\": \"value2\" }, \"scheduled\": \"2016-11-03T11:49:02.807Z\", \"source_number\": \"+61491570157\", \"source_number_type\": \"INTERNATIONAL\" }, { \"callback_url\": \"https://my.callback.url.com\", \"content\": \"My second message\", \"destination_number\": \"+61491570158\", \"delivery_report\": true, \"format\": \"SMS\", \"message_expiry_timestamp\": \"2016-11-03T11:49:02.807Z\", \"metadata\": { \"key1\": \"value1\", \"key2\": \"value2\" }, \"scheduled\": \"2016-11-03T11:49:02.807Z\", \"source_number\": \"+61491570159\", \"source_number_type\": \"INTERNATIONAL\" } ]}"); + SendMessagesRequest body = new SendMessagesRequest() + { + Messages = new List + { + new Message() + { + CallbackUrl = "https://my.callback.url.com", + Content = "My first message", + DestinationNumber = "+61491570156", + DeliveryReport = true, + Format = MessageFormat.SMS, + MessageExpiryTimestamp = new DateTime(2016, 11, 03, 11, 49, 02, DateTimeKind.Utc), + Metadata = new Dictionary() {{"key1", "value1"}, {"key2", "value2"}}, + Scheduled = new DateTime(2016, 11, 03, 11, 49, 02, DateTimeKind.Utc), + SourceNumber = "+61491570157", + SourceNumberType = NumberType.INTERNATIONAL + }, + new Message() + { + CallbackUrl = "https://my.callback.url.com", + Content = "My second message", + DestinationNumber = "+61491570158", + DeliveryReport = true, + Format = MessageFormat.SMS, + MessageExpiryTimestamp = new DateTime(2016, 11, 03, 11, 49, 02, DateTimeKind.Utc), + Metadata = new Dictionary() {{"key1", "value1"}, {"key2", "value2"}}, + Scheduled = new DateTime(2016, 11, 03, 11, 49, 02, DateTimeKind.Utc), + SourceNumber = "+61491570159", + SourceNumberType = NumberType.INTERNATIONAL + } + } + }; // Perform API call SendMessagesResponse result = null; @@ -122,7 +153,7 @@ public async Task TestSendMessages1() // Test whether the captured response is as we expected Assert.IsNotNull(result, "Result should exist"); - dynamic messages = result.Messages;//JObject.Parse(TestHelper.ConvertStreamToString(httpCallBackHandler.Response.RawBody)); + dynamic messages = result.Messages; int count = (int)messages.Count; Assert.AreEqual(count, 2); @@ -134,19 +165,19 @@ public async Task TestSendMessages1() AssertSendMessageResponseValid(secondMessage, "SMS", "My second message", "https://my.callback.url.com", true, "+61491570158", "+61491570159", "queued"); } - private void AssertSendMessageResponseValid(dynamic message, string expectedFormat, string expectedContent, string expectedCallbackUrl, + private void AssertSendMessageResponseValid(Message message, string expectedFormat, string expectedContent, string expectedCallbackUrl, bool expectedDeliveryReport, string expectedDestinationNumber, string expectedSourceNumber, string expectedStatus) { - var format = (string)message.format; - var content = (string)message.content; - var callbackUrl = (string)message.callback_url; - var deliveryReport = (bool)message.delivery_report; - var destinationNumber = (string)message.destination_number; - var sourceNumber = (string)message.source_number; - var status = (string)message.status; - var messageId = (string)message.message_id; - var messageExpiry = (string)message.message_expiry_timestamp; - var scheduled = (string)message.scheduled; + var format = message.Format.ToString(); + var content = (string)message.Content; + var callbackUrl = (string)message.CallbackUrl; + var deliveryReport = (bool)message.DeliveryReport; + var destinationNumber = (string)message.DestinationNumber; + var sourceNumber = (string) message.SourceNumber; + var status = (string)message.Status.ToString(); + var messageId = (string)message.MessageId; + var messageExpiry = message.MessageExpiryTimestamp; + var scheduled = message.Scheduled; Assert.AreEqual(format, expectedFormat, "Format should match exactly (string literal match)"); Assert.AreEqual(content, expectedContent, "Content should match exactly (string literal match)"); @@ -158,18 +189,10 @@ private void AssertSendMessageResponseValid(dynamic message, string expectedForm // note, these are non-deterministic, so we only check for their existence. Assert.IsNotEmpty(messageId, "Message ID should not be empty."); - Assert.IsNotEmpty(messageExpiry, "Message Expiry should not be empty."); - Assert.IsNotEmpty(scheduled, "Scheduled time should not be empty."); - - DateTime date; - bool canParse = DateTime.TryParse(messageExpiry, out date); - - Assert.IsTrue(canParse, "Message Expiry must be a valid DateTime"); + Assert.IsNotNull(messageExpiry, "Message Expiry should not be empty."); + Assert.IsNotNull(scheduled, "Scheduled time should not be empty."); - canParse = DateTime.TryParse(scheduled, out date); - Assert.IsTrue(canParse, "Scheduled time must be a valid DateTime"); - - JObject metadata = message.metadata as JObject; + var metadata = message.Metadata; Assert.IsNotNull(metadata, "Metadata must not be null."); @@ -177,16 +200,13 @@ private void AssertSendMessageResponseValid(dynamic message, string expectedForm Assert.AreEqual(metadataCount, 2, "Metadata must have two children."); - var firstKey = ((dynamic)metadata).key1; - var secondKey = ((dynamic)metadata).key2; - - Assert.IsNotNull(firstKey, "Metadata must contain key1."); - Assert.IsNotNull(secondKey, "Metadata must contain key2."); + Assert.IsTrue(metadata.ContainsKey("key1"), "Metadata must contain key1."); + Assert.IsTrue(metadata.ContainsKey("key2"), "Metadata must contain key2."); - var firstKeyValue = (string)firstKey; - var secondKeyValue = (string)secondKey; + var firstKeyValue = metadata["key1"]; + var secondKeyValue = metadata["key2"]; - Assert.AreEqual(firstKeyValue, "value1", "key1 must equal value1."); + Assert.AreEqual(firstKeyValue, "value1", "key1 must equal value1."); Assert.AreEqual(secondKeyValue, "value2", "key2 must equal value1."); } } diff --git a/README.md b/README.md index f9b1036..6d05cba 100644 --- a/README.md +++ b/README.md @@ -75,10 +75,12 @@ It's easy to get started. Simply enter the API Key and secret you obtained from Destination numbers (`destination_number`) should be in the [E.164](http://en.wikipedia.org/wiki/E.164) format. For example, `+61491570156`. ```csharp using System; +using System.Linq; using MessageMedia.Messages; using MessageMedia.Messages.Controllers; using MessageMedia.Messages.Models; + namespace TestCSharpSDK { class Program @@ -89,25 +91,24 @@ namespace TestCSharpSDK String basicAuthUserName = "YOUR_API_KEY"; String basicAuthPassword = "YOUR_API_SECRET"; bool useHmacAuthentication = false; //Change this to true if you are using HMAC keys - + // Instantiate the client MessageMediaMessagesClient client = new MessageMediaMessagesClient(basicAuthUserName, basicAuthPassword, useHmacAuthentication); IMessagesController messages = client.Messages; - // Perform API call - string bodyValue = @"{ - ""messages"":[ - { - ""content"":""Greetings from MessageMedia!"", - ""destination_number"":""YOUR_MOBILE_NUMBER"" - } - ] - }"; - - var body = Newtonsoft.Json.JsonConvert.DeserializeObject(bodyValue); - - MessageMedia.Messages.Models.SendMessagesResponse result = messages.CreateSendMessages(body); - Console.WriteLine(result.Messages); + var request = new SendMessagesRequest() { + Messages = new []{ + new Message() { + Content = "Greetings from MessageMedia!", + DestinationNumber = "YOUR_MOBILE_NUMBER" + } + } + }; + + SendMessagesResponse result = messages.CreateSendMessages(request); + Message message = result.Messages.First(); + + Console.WriteLine("Status: {0}, Message Id: {1}", message.Status, message.MessageId); Console.ReadKey(); } } @@ -118,6 +119,7 @@ namespace TestCSharpSDK Destination numbers (`destination_number`) should be in the [E.164](http://en.wikipedia.org/wiki/E.164) format. For example, `+61491570156`. ```csharp using System; +using System.Linq; using MessageMedia.Messages; using MessageMedia.Messages.Controllers; using MessageMedia.Messages.Models; @@ -153,8 +155,8 @@ namespace TestCSharpSDK } } }; - - Message message = result.Messages.First(); + SendMessagesResponse result = messages.CreateSendMessages(request); + Message message = result.Messages.First(); Console.WriteLine("Status: {0}, Message Id: {1}", message.Status, message.MessageId); Console.ReadKey(); @@ -181,7 +183,7 @@ namespace TestCSharpSDK String basicAuthUserName = "YOUR_API_KEY"; String basicAuthPassword = "YOUR_API_SECRET"; bool useHmacAuthentication = false; //Change this to true if you are using HMAC keys - + // Instantiate the client MessageMediaMessagesClient client = new MessageMediaMessagesClient(basicAuthUserName, basicAuthPassword, useHmacAuthentication); IMessagesController messages = client.Messages; @@ -214,7 +216,7 @@ namespace TestCSharpSDK String basicAuthUserName = "YOUR_API_KEY"; String basicAuthPassword = "YOUR_API_SECRET"; bool useHmacAuthentication = false; //Change this to true if you are using HMAC keys - + // Instantiate the client MessageMediaMessagesClient client = new MessageMediaMessagesClient(basicAuthUserName, basicAuthPassword, useHmacAuthentication); IRepliesController replies = client.Replies; @@ -246,7 +248,7 @@ namespace TestCSharpSDK String basicAuthUserName = "YOUR_API_KEY"; String basicAuthPassword = "YOUR_API_SECRET"; bool useHmacAuthentication = false; //Change this to true if you are using HMAC keys - + // Instantiate the client MessageMediaMessagesClient client = new MessageMediaMessagesClient(basicAuthUserName, basicAuthPassword, useHmacAuthentication); IDeliveryReportsController deliveryReports = client.DeliveryReports; @@ -267,4 +269,4 @@ Check out the [full API documentation](https://developers.messagemedia.com/code/ Please contact developer support at developers@messagemedia.com or check out the developer portal at [developers.messagemedia.com](https://developers.messagemedia.com/) ## :page_with_curl: License -Apache License. See the [LICENSE](LICENSE) file. +Apache License. See the [LICENSE](LICENSE) file. \ No newline at end of file