Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions MessageMedia.SDK.Messages/Models/Message.cs
Original file line number Diff line number Diff line change
@@ -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; }

/// <summary>
/// Urls of the media files to send in the Message
///
/// <remarks>Only valid if the Format is MMS</remarks>
/// </summary>
[JsonProperty("media")] public string[] Media { get; set; }
[JsonProperty("media", NullValueHandling = NullValueHandling.Ignore)] public string[] Media { get; set; }

[JsonProperty("status")] public MessageStatus Status { get; set; }
/// <summary>
/// Subject of the Message
///
/// <remarks>Only valid if the Format is MMS</remarks>
/// </summary>
[JsonProperty("subject", NullValueHandling = NullValueHandling.Ignore)] public string Subject { get; set; }

[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public MessageStatus? Status { get; set; }

/// <summary>
/// Replies and delivery reports for this message will be pushed to the URL"
/// </summary>
[JsonProperty("callback_url")] public string CallbackUrl { get; set; }
[JsonProperty("callback_url", NullValueHandling = NullValueHandling.Ignore)] public string CallbackUrl { get; set; }

/// <summary>
/// Content of the message
/// <example>Hello world!</example>
/// </summary>
[JsonProperty("content")] public string Content { get; set; }
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] public string Content { get; set; }

/// <summary>
/// Destination number of the message
/// <example>+61491570156</example>
/// </summary>
[JsonProperty("destination_number")] public string DestinationNumber { get; set; }
[JsonProperty("destination_number", NullValueHandling = NullValueHandling.Ignore)] public string DestinationNumber { get; set; }

/// <summary>
/// Request a delivery report for this message
/// </summary>
[JsonProperty("delivery_report")] public bool DeliveryReport { get; set; }
[JsonProperty("delivery_report", NullValueHandling = NullValueHandling.Ignore)] public bool DeliveryReport { get; set; }

/// <summary>
/// Format of message, SMS or TTS (Text To Speech).
/// </summary>
[JsonProperty("format")] public MessageFormat Format { get; set; }
[JsonProperty("format", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public MessageFormat Format { get; set; }

/// <summary>
/// Date time after which the message expires and will not be sent
/// </summary>
[JsonProperty("message_expiry_timestamp")]
public DateTime MessageExpiryTimestamp { get; set; }
[JsonProperty("message_expiry_timestamp", NullValueHandling = NullValueHandling.Ignore)]
public DateTime? MessageExpiryTimestamp { get; set; }

/// <summary>
/// Metadata for the message specified as a set of key value pairs.
///
/// <remarks>Each key can be up to 100 characters long and each value can be up to 256 characters long.</remarks>
/// </summary>
[JsonProperty("metadata")] public Dictionary<string, string> Metadata { get; set; }
[JsonProperty("metadata", NullValueHandling = NullValueHandling.Ignore)] public Dictionary<string, string> Metadata { get; set; }

/// <summary>
/// Scheduled delivery date time of the message
/// </summary>
[JsonProperty("scheduled")] public DateTime Scheduled { get; set; }
[JsonProperty("scheduled", NullValueHandling = NullValueHandling.Ignore)] public DateTime? Scheduled { get; set; }

/// <summary>
/// Source of the message
Expand All @@ -70,11 +82,13 @@ public struct Message
///
/// <remarks>By default this feature is not available and will be ignored in the request. Please contact [email protected] for more information. Specifying a source number is optional and a by default a source number will be assigned to the message.</remarks>
/// </summary>
[JsonProperty("source_number")] public string SourceNumber { get; set; }
[JsonProperty("source_number", NullValueHandling = NullValueHandling.Ignore)] public string SourceNumber { get; set; }

/// <summary>
/// Type of source address specified
/// </summary>
[JsonProperty("source_number_type")] public NumberType SourceNumberType { get; set; }
[JsonProperty("source_number_type", NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(StringEnumConverter))]
public NumberType SourceNumberType { get; set; }
}
}
84 changes: 52 additions & 32 deletions MessageMediaMessages.Tests/MessagesControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,38 @@ public static void SetUpClass()
public async Task TestSendMessages1()
{
// Parameters for the API call
SendMessagesRequest body = APIHelper.JsonDeserialize<Models.SendMessagesRequest>("{ \"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<Message>
{
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<string, string>() {{"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<string, string>() {{"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;
Expand All @@ -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);
Expand All @@ -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)");
Expand All @@ -158,35 +189,24 @@ 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.");

var metadataCount = metadata.Count;

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.");
}
}
Expand Down
44 changes: 23 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<MessageMedia.Messages.Models.SendMessagesRequest>(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();
}
}
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -267,4 +269,4 @@ Check out the [full API documentation](https://developers.messagemedia.com/code/
Please contact developer support at [email protected] 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.