diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb0e0fb..efd64c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Channel implementations (SMS, WhatsApp, ...) are extensions to the `ILinkMobilityClient` interface.
+- Reorganized namespaces to reflect parts of the API
+
+### Removed
+
+- `IQueryParameter` as no usage on API docs found (for now)
## [v0.1.1] - 2026-03-13
diff --git a/README.md b/README.md
index 777d9e4..d3012e6 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@ So I decided to implement the current available API myself with a more modern (a
---
-Published under [MIT License] (see [**tl;dr**Legal])
+Published under [MIT License] (see [choose a license])
[LINK Mobility REST API]: https://developer.linkmobility.eu/
[outdated repository]: https://github.com/websms-com/websmscom-csharp
[.NET Standard 2.0]: https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-2-0
[MIT License]: LICENSE.txt
-[**tl;dr**Legal]: https://www.tldrlegal.com/license/mit-license
+[choose a license]: https://choosealicense.com/licenses/mit/
diff --git a/src/LinkMobility/Enums/StatusCodes.cs b/src/LinkMobility/Enums/StatusCodes.cs
index c912d70..cf941a2 100644
--- a/src/LinkMobility/Enums/StatusCodes.cs
+++ b/src/LinkMobility/Enums/StatusCodes.cs
@@ -1,7 +1,8 @@
namespace AMWD.Net.Api.LinkMobility
{
///
- /// Custom status codes as defined by Link Mobility.
+ /// Custom status codes as defined by
+ /// LINK Mobility.
///
public enum StatusCodes : int
{
diff --git a/src/LinkMobility/ILinkMobilityClient.cs b/src/LinkMobility/ILinkMobilityClient.cs
index 22bc798..e152d13 100644
--- a/src/LinkMobility/ILinkMobilityClient.cs
+++ b/src/LinkMobility/ILinkMobilityClient.cs
@@ -15,8 +15,7 @@ namespace AMWD.Net.Api.LinkMobility
/// The type of the request.
/// The path of the API endpoint.
/// The request data.
- /// Optional query parameters.
/// A cancellation token to propagate notification that operations should be canceled.
- Task PostAsync(string requestPath, TRequest? request, IQueryParameter? queryParams = null, CancellationToken cancellationToken = default);
+ Task PostAsync(string requestPath, TRequest? request, CancellationToken cancellationToken = default);
}
}
diff --git a/src/LinkMobility/LinkMobilityClient.cs b/src/LinkMobility/LinkMobilityClient.cs
index 8a5f673..6dcaef4 100644
--- a/src/LinkMobility/LinkMobilityClient.cs
+++ b/src/LinkMobility/LinkMobilityClient.cs
@@ -7,6 +7,7 @@ using System.Security.Authentication;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using AMWD.Net.Api.LinkMobility.Utils;
namespace AMWD.Net.Api.LinkMobility
{
@@ -79,12 +80,12 @@ namespace AMWD.Net.Api.LinkMobility
}
///
- public async Task PostAsync(string requestPath, TRequest? request, IQueryParameter? queryParams = null, CancellationToken cancellationToken = default)
+ public async Task PostAsync(string requestPath, TRequest? request, CancellationToken cancellationToken = default)
{
ThrowIfDisposed();
ValidateRequestPath(requestPath);
- string requestUrl = BuildRequestUrl(requestPath, queryParams);
+ string requestUrl = BuildRequestUrl(requestPath);
var httpContent = ConvertRequest(request);
var httpRequest = new HttpRequestMessage
@@ -99,7 +100,7 @@ namespace AMWD.Net.Api.LinkMobility
return response;
}
- private string BuildRequestUrl(string requestPath, IQueryParameter? queryParams = null)
+ private string BuildRequestUrl(string requestPath)
{
string path = requestPath.Trim().TrimStart('/');
var param = new Dictionary();
@@ -110,13 +111,6 @@ namespace AMWD.Net.Api.LinkMobility
param[kvp.Key] = kvp.Value;
}
- var customQueryParams = queryParams?.GetQueryParameters();
- if (customQueryParams?.Count > 0)
- {
- foreach (var kvp in customQueryParams)
- param[kvp.Key] = kvp.Value;
- }
-
if (param.Count == 0)
return path;
diff --git a/src/LinkMobility/QueryParameters/IQueryParameter.cs b/src/LinkMobility/QueryParameters/IQueryParameter.cs
deleted file mode 100644
index d687432..0000000
--- a/src/LinkMobility/QueryParameters/IQueryParameter.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Represents options defined via query parameters.
- ///
- public interface IQueryParameter
- {
- ///
- /// Retrieves the query parameters.
- ///
- IReadOnlyDictionary GetQueryParameters();
- }
-}
diff --git a/src/LinkMobility/Enums/AddressType.cs b/src/LinkMobility/Text/AddressType.cs
similarity index 90%
rename from src/LinkMobility/Enums/AddressType.cs
rename to src/LinkMobility/Text/AddressType.cs
index 465eda5..a07b285 100644
--- a/src/LinkMobility/Enums/AddressType.cs
+++ b/src/LinkMobility/Text/AddressType.cs
@@ -1,36 +1,36 @@
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Converters;
-
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Specifies the type of sender address.
- ///
- [JsonConverter(typeof(StringEnumConverter))]
- public enum AddressType
- {
- ///
- /// National number.
- ///
- [EnumMember(Value = "national")]
- National = 1,
-
- ///
- /// International number.
- ///
- [EnumMember(Value = "international")]
- International = 2,
-
- ///
- /// Alphanumeric sender ID.
- ///
- [EnumMember(Value = "alphanumeric")]
- Alphanumeric = 3,
-
- ///
- /// Shortcode.
- ///
- [EnumMember(Value = "shortcode")]
- Shortcode = 4,
- }
-}
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Converters;
+
+namespace AMWD.Net.Api.LinkMobility.Text
+{
+ ///
+ /// Specifies the type of sender address.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum AddressType
+ {
+ ///
+ /// National number.
+ ///
+ [EnumMember(Value = "national")]
+ National = 1,
+
+ ///
+ /// International number.
+ ///
+ [EnumMember(Value = "international")]
+ International = 2,
+
+ ///
+ /// Alphanumeric sender ID.
+ ///
+ [EnumMember(Value = "alphanumeric")]
+ Alphanumeric = 3,
+
+ ///
+ /// Shortcode.
+ ///
+ [EnumMember(Value = "shortcode")]
+ Shortcode = 4,
+ }
+}
diff --git a/src/LinkMobility/Enums/DeliveryType.cs b/src/LinkMobility/Text/DeliveryType.cs
similarity index 90%
rename from src/LinkMobility/Enums/DeliveryType.cs
rename to src/LinkMobility/Text/DeliveryType.cs
index 84a4b10..e80bb40 100644
--- a/src/LinkMobility/Enums/DeliveryType.cs
+++ b/src/LinkMobility/Text/DeliveryType.cs
@@ -1,36 +1,36 @@
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Converters;
-
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Defines the types of delivery methods on a report.
- ///
- [JsonConverter(typeof(StringEnumConverter))]
- public enum DeliveryType
- {
- ///
- /// Message sent via SMS.
- ///
- [EnumMember(Value = "sms")]
- Sms = 1,
-
- ///
- /// Message sent as Push message.
- ///
- [EnumMember(Value = "push")]
- Push = 2,
-
- ///
- /// Message sent as failover SMS.
- ///
- [EnumMember(Value = "failover-sms")]
- FailoverSms = 3,
-
- ///
- /// Message sent as voice message.
- ///
- [EnumMember(Value = "voice")]
- Voice = 4
- }
-}
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Converters;
+
+namespace AMWD.Net.Api.LinkMobility.Text
+{
+ ///
+ /// Defines the types of delivery methods on a report.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum DeliveryType
+ {
+ ///
+ /// Message sent via SMS.
+ ///
+ [EnumMember(Value = "sms")]
+ Sms = 1,
+
+ ///
+ /// Message sent as Push message.
+ ///
+ [EnumMember(Value = "push")]
+ Push = 2,
+
+ ///
+ /// Message sent as failover SMS.
+ ///
+ [EnumMember(Value = "failover-sms")]
+ FailoverSms = 3,
+
+ ///
+ /// Message sent as voice message.
+ ///
+ [EnumMember(Value = "voice")]
+ Voice = 4
+ }
+}
diff --git a/src/LinkMobility/Enums/MessageType.cs b/src/LinkMobility/Text/MessageType.cs
similarity index 88%
rename from src/LinkMobility/Enums/MessageType.cs
rename to src/LinkMobility/Text/MessageType.cs
index 474c002..8fb2e50 100644
--- a/src/LinkMobility/Enums/MessageType.cs
+++ b/src/LinkMobility/Text/MessageType.cs
@@ -1,24 +1,24 @@
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Converters;
-
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Specifies the message type.
- ///
- [JsonConverter(typeof(StringEnumConverter))]
- public enum MessageType
- {
- ///
- /// The message is sent as defined in the account settings.
- ///
- [EnumMember(Value = "default")]
- Default = 1,
-
- ///
- /// The message is sent as voice call.
- ///
- [EnumMember(Value = "voice")]
- Voice = 2,
- }
-}
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Converters;
+
+namespace AMWD.Net.Api.LinkMobility.Text
+{
+ ///
+ /// Specifies the message type.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum MessageType
+ {
+ ///
+ /// The message is sent as defined in the account settings.
+ ///
+ [EnumMember(Value = "default")]
+ Default = 1,
+
+ ///
+ /// The message is sent as voice call.
+ ///
+ [EnumMember(Value = "voice")]
+ Voice = 2,
+ }
+}
diff --git a/src/LinkMobility/Requests/SendBinaryMessageRequest.cs b/src/LinkMobility/Text/SendBinaryMessageRequest.cs
similarity index 96%
rename from src/LinkMobility/Requests/SendBinaryMessageRequest.cs
rename to src/LinkMobility/Text/SendBinaryMessageRequest.cs
index f1939dd..8063625 100644
--- a/src/LinkMobility/Requests/SendBinaryMessageRequest.cs
+++ b/src/LinkMobility/Text/SendBinaryMessageRequest.cs
@@ -1,130 +1,130 @@
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Request to send a text message to a list of recipients.
- ///
- public class SendBinaryMessageRequest
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// A binary message as base64 encoded lines.
- /// A list of recipient numbers.
- public SendBinaryMessageRequest(IReadOnlyCollection messageContent, IReadOnlyCollection recipientAddressList)
- {
- MessageContent = messageContent;
- RecipientAddressList = recipientAddressList;
- }
-
- ///
- /// Optional.
- /// May contain a freely definable message id.
- ///
- [JsonProperty("clientMessageId")]
- public string? ClientMessageId { get; set; }
-
- ///
- /// Optional.
- /// The content category that is used to categorize the message (used for blacklisting).
- ///
- ///
- /// The following content categories are supported: or .
- /// If no content category is provided, the default setting is used (may be changed inside the web interface).
- ///
- [JsonProperty("contentCategory")]
- public ContentCategory? ContentCategory { get; set; }
-
- ///
- /// Optional.
- /// Array of Base64 encoded binary data.
- ///
- ///
- /// Every element of the array corresponds to a message segment.
- /// The binary data is transmitted without being changed (using 8 bit alphabet).
- ///
- [JsonProperty("messageContent")]
- public IReadOnlyCollection MessageContent { get; set; }
-
- ///
- /// Optional.
- /// When setting a NotificationCallbackUrl all delivery reports are forwarded to this URL.
- ///
- [JsonProperty("notificationCallbackUrl")]
- public string? NotificationCallbackUrl { get; set; }
-
- ///
- /// Optional.
- /// Priority of the message.
- ///
- ///
- /// Must not exceed the value configured for the account used to send the message.
- /// For more information please contact our customer service.
- ///
- [JsonProperty("priority")]
- public int? Priority { get; set; }
-
- ///
- /// List of recipients (E.164 formatted MSISDNs)
- /// to whom the message should be sent.
- ///
- /// The list of recipients may contain a maximum of 1000 entries.
- ///
- [JsonProperty("recipientAddressList")]
- public IReadOnlyCollection RecipientAddressList { get; set; }
-
- ///
- /// Optional.
- ///
- /// : The message is sent as flash SMS (displayed directly on the screen of the mobile phone).
- ///
- /// : The message is sent as standard text SMS (default).
- ///
- [JsonProperty("sendAsFlashSms")]
- public bool? SendAsFlashSms { get; set; }
-
- ///
- /// Optional.
- /// Address of the sender (assigned to the account) from which the message is sent.
- ///
- [JsonProperty("senderAddress")]
- public string? SenderAddress { get; set; }
-
- ///
- /// Optional.
- /// The sender address type.
- ///
- [JsonProperty("senderAddressType")]
- public AddressType? SenderAddressType { get; set; }
-
- ///
- /// Optional.
- ///
- /// : The transmission is only simulated, no SMS is sent.
- /// Depending on the number of recipients the status code or is returned.
- ///
- /// : No simulation is done. The SMS is sent via the SMS Gateway. (default)
- ///
- [JsonProperty("test")]
- public bool? Test { get; set; }
-
- ///
- /// Optional.
- ///
- /// : Indicates the presence of a user data header in the property.
- ///
- /// : Indicates the absence of a user data header in the property. (default)
- ///
- [JsonProperty("userDataHeaderPresent")]
- public bool? UserDataHeaderPresent { get; set; }
-
- ///
- /// Optional.
- /// Specifies the validity periode (in seconds) in which the message is tried to be delivered to the recipient.
- ///
- ///
- /// A minimum of 1 minute (60 seconds) and a maximum of 3 days (259200 seconds) are allowed.
- ///
- [JsonProperty("validityPeriode")]
- public int? ValidityPeriode { get; set; }
- }
-}
+namespace AMWD.Net.Api.LinkMobility.Text
+{
+ ///
+ /// Request to send a text message to a list of recipients.
+ ///
+ public class SendBinaryMessageRequest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A binary message as base64 encoded lines.
+ /// A list of recipient numbers.
+ public SendBinaryMessageRequest(IReadOnlyCollection messageContent, IReadOnlyCollection recipientAddressList)
+ {
+ MessageContent = messageContent;
+ RecipientAddressList = recipientAddressList;
+ }
+
+ ///
+ /// Optional.
+ /// May contain a freely definable message id.
+ ///
+ [JsonProperty("clientMessageId")]
+ public string? ClientMessageId { get; set; }
+
+ ///
+ /// Optional.
+ /// The content category that is used to categorize the message (used for blacklisting).
+ ///
+ ///
+ /// The following content categories are supported: or .
+ /// If no content category is provided, the default setting is used (may be changed inside the web interface).
+ ///
+ [JsonProperty("contentCategory")]
+ public ContentCategory? ContentCategory { get; set; }
+
+ ///
+ /// Optional.
+ /// Array of Base64 encoded binary data.
+ ///
+ ///
+ /// Every element of the array corresponds to a message segment.
+ /// The binary data is transmitted without being changed (using 8 bit alphabet).
+ ///
+ [JsonProperty("messageContent")]
+ public IReadOnlyCollection MessageContent { get; set; }
+
+ ///
+ /// Optional.
+ /// When setting a NotificationCallbackUrl all delivery reports are forwarded to this URL.
+ ///
+ [JsonProperty("notificationCallbackUrl")]
+ public string? NotificationCallbackUrl { get; set; }
+
+ ///
+ /// Optional.
+ /// Priority of the message.
+ ///
+ ///
+ /// Must not exceed the value configured for the account used to send the message.
+ /// For more information please contact our customer service.
+ ///
+ [JsonProperty("priority")]
+ public int? Priority { get; set; }
+
+ ///
+ /// List of recipients (E.164 formatted MSISDNs)
+ /// to whom the message should be sent.
+ ///
+ /// The list of recipients may contain a maximum of 1000 entries.
+ ///
+ [JsonProperty("recipientAddressList")]
+ public IReadOnlyCollection RecipientAddressList { get; set; }
+
+ ///
+ /// Optional.
+ ///
+ /// : The message is sent as flash SMS (displayed directly on the screen of the mobile phone).
+ ///
+ /// : The message is sent as standard text SMS (default).
+ ///
+ [JsonProperty("sendAsFlashSms")]
+ public bool? SendAsFlashSms { get; set; }
+
+ ///
+ /// Optional.
+ /// Address of the sender (assigned to the account) from which the message is sent.
+ ///
+ [JsonProperty("senderAddress")]
+ public string? SenderAddress { get; set; }
+
+ ///
+ /// Optional.
+ /// The sender address type.
+ ///
+ [JsonProperty("senderAddressType")]
+ public AddressType? SenderAddressType { get; set; }
+
+ ///
+ /// Optional.
+ ///
+ /// : The transmission is only simulated, no SMS is sent.
+ /// Depending on the number of recipients the status code or is returned.
+ ///
+ /// : No simulation is done. The SMS is sent via the SMS Gateway. (default)
+ ///
+ [JsonProperty("test")]
+ public bool? Test { get; set; }
+
+ ///
+ /// Optional.
+ ///
+ /// : Indicates the presence of a user data header in the property.
+ ///
+ /// : Indicates the absence of a user data header in the property. (default)
+ ///
+ [JsonProperty("userDataHeaderPresent")]
+ public bool? UserDataHeaderPresent { get; set; }
+
+ ///
+ /// Optional.
+ /// Specifies the validity periode (in seconds) in which the message is tried to be delivered to the recipient.
+ ///
+ ///
+ /// A minimum of 1 minute (60 seconds) and a maximum of 3 days (259200 seconds) are allowed.
+ ///
+ [JsonProperty("validityPeriode")]
+ public int? ValidityPeriode { get; set; }
+ }
+}
diff --git a/src/LinkMobility/Requests/SendTextMessageRequest.cs b/src/LinkMobility/Text/SendTextMessageRequest.cs
similarity index 96%
rename from src/LinkMobility/Requests/SendTextMessageRequest.cs
rename to src/LinkMobility/Text/SendTextMessageRequest.cs
index c8d07e9..a919be0 100644
--- a/src/LinkMobility/Requests/SendTextMessageRequest.cs
+++ b/src/LinkMobility/Text/SendTextMessageRequest.cs
@@ -1,139 +1,139 @@
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Request to send a text message to a list of recipients.
- ///
- public class SendTextMessageRequest
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// A text message.
- /// A list of recipient numbers.
- public SendTextMessageRequest(string messageContent, IReadOnlyCollection recipientAddressList)
- {
- MessageContent = messageContent;
- RecipientAddressList = recipientAddressList;
- }
-
- ///
- /// Optional.
- /// May contain a freely definable message id.
- ///
- [JsonProperty("clientMessageId")]
- public string? ClientMessageId { get; set; }
-
- ///
- /// Optional.
- /// The content category that is used to categorize the message (used for blacklisting).
- ///
- ///
- /// The following content categories are supported: or .
- /// If no content category is provided, the default setting is used (may be changed inside the web interface).
- ///
- [JsonProperty("contentCategory")]
- public ContentCategory? ContentCategory { get; set; }
-
- ///
- /// Optional.
- /// Specifies the maximum number of SMS to be generated.
- ///
- ///
- /// If the system generates more than this number of SMS, the status code is returned.
- /// The default value of this parameter is 0.
- /// If set to 0, no limitation is applied.
- ///
- [JsonProperty("maxSmsPerMessage")]
- public int? MaxSmsPerMessage { get; set; }
-
- ///
- /// UTF-8 encoded message content.
- ///
- [JsonProperty("messageContent")]
- public string MessageContent { get; set; }
-
- ///
- /// Optional.
- /// Specifies the message type.
- ///
- ///
- /// Allowed values are and .
- /// When using the message type , the outgoing message type is determined based on account settings.
- /// Using the message type triggers a voice call.
- ///
- [JsonProperty("messageType")]
- public MessageType? MessageType { get; set; }
-
- ///
- /// Optional.
- /// When setting a NotificationCallbackUrl all delivery reports are forwarded to this URL.
- ///
- [JsonProperty("notificationCallbackUrl")]
- public string? NotificationCallbackUrl { get; set; }
-
- ///
- /// Optional.
- /// Priority of the message.
- ///
- ///
- /// Must not exceed the value configured for the account used to send the message.
- /// For more information please contact our customer service.
- ///
- [JsonProperty("priority")]
- public int? Priority { get; set; }
-
- ///
- /// List of recipients (E.164 formatted MSISDNs)
- /// to whom the message should be sent.
- ///
- /// The list of recipients may contain a maximum of 1000 entries.
- ///
- [JsonProperty("recipientAddressList")]
- public IReadOnlyCollection RecipientAddressList { get; set; }
-
- ///
- /// Optional.
- ///
- /// : The message is sent as flash SMS (displayed directly on the screen of the mobile phone).
- ///
- /// : The message is sent as standard text SMS (default).
- ///
- [JsonProperty("sendAsFlashSms")]
- public bool? SendAsFlashSms { get; set; }
-
- ///
- /// Optional.
- /// Address of the sender (assigned to the account) from which the message is sent.
- ///
- [JsonProperty("senderAddress")]
- public string? SenderAddress { get; set; }
-
- ///
- /// Optional.
- /// The sender address type.
- ///
- [JsonProperty("senderAddressType")]
- public AddressType? SenderAddressType { get; set; }
-
- ///
- /// Optional.
- ///
- /// : The transmission is only simulated, no SMS is sent.
- /// Depending on the number of recipients the status code or is returned.
- ///
- /// : No simulation is done. The SMS is sent via the SMS Gateway. (default)
- ///
- [JsonProperty("test")]
- public bool? Test { get; set; }
-
- ///
- /// Optional.
- /// Specifies the validity periode (in seconds) in which the message is tried to be delivered to the recipient.
- ///
- ///
- /// A minimum of 1 minute (60 seconds) and a maximum of 3 days (259200 seconds) are allowed.
- ///
- [JsonProperty("validityPeriode")]
- public int? ValidityPeriode { get; set; }
- }
-}
+namespace AMWD.Net.Api.LinkMobility.Text
+{
+ ///
+ /// Request to send a text message to a list of recipients.
+ ///
+ public class SendTextMessageRequest
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A text message.
+ /// A list of recipient numbers.
+ public SendTextMessageRequest(string messageContent, IReadOnlyCollection recipientAddressList)
+ {
+ MessageContent = messageContent;
+ RecipientAddressList = recipientAddressList;
+ }
+
+ ///
+ /// Optional.
+ /// May contain a freely definable message id.
+ ///
+ [JsonProperty("clientMessageId")]
+ public string? ClientMessageId { get; set; }
+
+ ///
+ /// Optional.
+ /// The content category that is used to categorize the message (used for blacklisting).
+ ///
+ ///
+ /// The following content categories are supported: or .
+ /// If no content category is provided, the default setting is used (may be changed inside the web interface).
+ ///
+ [JsonProperty("contentCategory")]
+ public ContentCategory? ContentCategory { get; set; }
+
+ ///
+ /// Optional.
+ /// Specifies the maximum number of SMS to be generated.
+ ///
+ ///
+ /// If the system generates more than this number of SMS, the status code is returned.
+ /// The default value of this parameter is 0.
+ /// If set to 0, no limitation is applied.
+ ///
+ [JsonProperty("maxSmsPerMessage")]
+ public int? MaxSmsPerMessage { get; set; }
+
+ ///
+ /// UTF-8 encoded message content.
+ ///
+ [JsonProperty("messageContent")]
+ public string MessageContent { get; set; }
+
+ ///
+ /// Optional.
+ /// Specifies the message type.
+ ///
+ ///
+ /// Allowed values are and .
+ /// When using the message type , the outgoing message type is determined based on account settings.
+ /// Using the message type triggers a voice call.
+ ///
+ [JsonProperty("messageType")]
+ public MessageType? MessageType { get; set; }
+
+ ///
+ /// Optional.
+ /// When setting a NotificationCallbackUrl all delivery reports are forwarded to this URL.
+ ///
+ [JsonProperty("notificationCallbackUrl")]
+ public string? NotificationCallbackUrl { get; set; }
+
+ ///
+ /// Optional.
+ /// Priority of the message.
+ ///
+ ///
+ /// Must not exceed the value configured for the account used to send the message.
+ /// For more information please contact our customer service.
+ ///
+ [JsonProperty("priority")]
+ public int? Priority { get; set; }
+
+ ///
+ /// List of recipients (E.164 formatted MSISDNs)
+ /// to whom the message should be sent.
+ ///
+ /// The list of recipients may contain a maximum of 1000 entries.
+ ///
+ [JsonProperty("recipientAddressList")]
+ public IReadOnlyCollection RecipientAddressList { get; set; }
+
+ ///
+ /// Optional.
+ ///
+ /// : The message is sent as flash SMS (displayed directly on the screen of the mobile phone).
+ ///
+ /// : The message is sent as standard text SMS (default).
+ ///
+ [JsonProperty("sendAsFlashSms")]
+ public bool? SendAsFlashSms { get; set; }
+
+ ///
+ /// Optional.
+ /// Address of the sender (assigned to the account) from which the message is sent.
+ ///
+ [JsonProperty("senderAddress")]
+ public string? SenderAddress { get; set; }
+
+ ///
+ /// Optional.
+ /// The sender address type.
+ ///
+ [JsonProperty("senderAddressType")]
+ public AddressType? SenderAddressType { get; set; }
+
+ ///
+ /// Optional.
+ ///
+ /// : The transmission is only simulated, no SMS is sent.
+ /// Depending on the number of recipients the status code or is returned.
+ ///
+ /// : No simulation is done. The SMS is sent via the SMS Gateway. (default)
+ ///
+ [JsonProperty("test")]
+ public bool? Test { get; set; }
+
+ ///
+ /// Optional.
+ /// Specifies the validity periode (in seconds) in which the message is tried to be delivered to the recipient.
+ ///
+ ///
+ /// A minimum of 1 minute (60 seconds) and a maximum of 3 days (259200 seconds) are allowed.
+ ///
+ [JsonProperty("validityPeriode")]
+ public int? ValidityPeriode { get; set; }
+ }
+}
diff --git a/src/LinkMobility/TextMessageExtensions.cs b/src/LinkMobility/Text/TextMessageExtensions.cs
similarity index 98%
rename from src/LinkMobility/TextMessageExtensions.cs
rename to src/LinkMobility/Text/TextMessageExtensions.cs
index 45dd4c9..43b400f 100644
--- a/src/LinkMobility/TextMessageExtensions.cs
+++ b/src/LinkMobility/Text/TextMessageExtensions.cs
@@ -2,7 +2,7 @@
using System.Threading.Tasks;
using AMWD.Net.Api.LinkMobility.Utils;
-namespace AMWD.Net.Api.LinkMobility
+namespace AMWD.Net.Api.LinkMobility.Text
{
///
/// Implementation of text messaging (SMS). API
diff --git a/src/LinkMobility/Utils/SerializerExtensions.cs b/src/LinkMobility/Utils/SerializerExtensions.cs
index 2fd0596..3299cc8 100644
--- a/src/LinkMobility/Utils/SerializerExtensions.cs
+++ b/src/LinkMobility/Utils/SerializerExtensions.cs
@@ -1,6 +1,6 @@
using System.Globalization;
-namespace AMWD.Net.Api.LinkMobility
+namespace AMWD.Net.Api.LinkMobility.Utils
{
internal static class SerializerExtensions
{
diff --git a/src/LinkMobility/Models/IncomingMessageNotificationResponse.cs b/src/LinkMobility/Webhook/NotificationResponse.cs
similarity index 68%
rename from src/LinkMobility/Models/IncomingMessageNotificationResponse.cs
rename to src/LinkMobility/Webhook/NotificationResponse.cs
index a1e04ca..c9da92d 100644
--- a/src/LinkMobility/Models/IncomingMessageNotificationResponse.cs
+++ b/src/LinkMobility/Webhook/NotificationResponse.cs
@@ -1,27 +1,33 @@
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Representes the response to an incoming message notification. (API)
- ///
- public class IncomingMessageNotificationResponse
- {
- ///
- /// Gets or sets the status code of the response.
- ///
- [JsonProperty("statusCode")]
- public StatusCodes StatusCode { get; set; } = StatusCodes.Ok;
-
- ///
- /// Gets or sets the status message of the response.
- ///
- [JsonProperty("statusMessage")]
- public string StatusMessage { get; set; } = "OK";
-
- ///
- /// Returns a string representation of the current object in serialized format.
- ///
- /// A string containing the serialized form of the object (json).
- public override string ToString()
- => this.SerializeObject();
- }
-}
+using AMWD.Net.Api.LinkMobility.Utils;
+
+namespace AMWD.Net.Api.LinkMobility.Webhook
+{
+ ///
+ /// Representes the response to an incoming message notification.
+ /// (See API)
+ ///
+ ///
+ /// This notification acknowlegement is the same for all webhooks of LINK Mobility.
+ ///
+ public class NotificationResponse
+ {
+ ///
+ /// Gets or sets the status code of the response.
+ ///
+ [JsonProperty("statusCode")]
+ public StatusCodes StatusCode { get; set; } = StatusCodes.Ok;
+
+ ///
+ /// Gets or sets the status message of the response.
+ ///
+ [JsonProperty("statusMessage")]
+ public string StatusMessage { get; set; } = "OK";
+
+ ///
+ /// Returns a string representation of the current object in serialized format.
+ ///
+ /// A string containing the serialized form of the object (json).
+ public override string ToString()
+ => this.SerializeObject();
+ }
+}
diff --git a/src/LinkMobility/Enums/DeliveryStatus.cs b/src/LinkMobility/Webhook/Text/DeliveryStatus.cs
similarity index 92%
rename from src/LinkMobility/Enums/DeliveryStatus.cs
rename to src/LinkMobility/Webhook/Text/DeliveryStatus.cs
index 36c4bbf..4ab2193 100644
--- a/src/LinkMobility/Enums/DeliveryStatus.cs
+++ b/src/LinkMobility/Webhook/Text/DeliveryStatus.cs
@@ -1,48 +1,48 @@
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Converters;
-
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Defines the delivery status of a message on a report.
- ///
- [JsonConverter(typeof(StringEnumConverter))]
- public enum DeliveryStatus
- {
- ///
- /// Message has been delivered to the recipient.
- ///
- [EnumMember(Value = "delivered")]
- Delivered = 1,
-
- ///
- /// Message not delivered and will be re-tried.
- ///
- [EnumMember(Value = "undelivered")]
- Undelivered = 2,
-
- ///
- /// Message has expired and will no longer re-tried.
- ///
- [EnumMember(Value = "expired")]
- Expired = 3,
-
- ///
- /// Message has been deleted.
- ///
- [EnumMember(Value = "deleted")]
- Deleted = 4,
-
- ///
- /// Message has been accepted by the carrier.
- ///
- [EnumMember(Value = "accepted")]
- Accepted = 5,
-
- ///
- /// Message has been rejected by the carrier.
- ///
- [EnumMember(Value = "rejected")]
- Rejected = 6
- }
-}
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Converters;
+
+namespace AMWD.Net.Api.LinkMobility.Webhook.Text
+{
+ ///
+ /// Defines the delivery status of a message on a report.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum DeliveryStatus
+ {
+ ///
+ /// Message has been delivered to the recipient.
+ ///
+ [EnumMember(Value = "delivered")]
+ Delivered = 1,
+
+ ///
+ /// Message not delivered and will be re-tried.
+ ///
+ [EnumMember(Value = "undelivered")]
+ Undelivered = 2,
+
+ ///
+ /// Message has expired and will no longer re-tried.
+ ///
+ [EnumMember(Value = "expired")]
+ Expired = 3,
+
+ ///
+ /// Message has been deleted.
+ ///
+ [EnumMember(Value = "deleted")]
+ Deleted = 4,
+
+ ///
+ /// Message has been accepted by the carrier.
+ ///
+ [EnumMember(Value = "accepted")]
+ Accepted = 5,
+
+ ///
+ /// Message has been rejected by the carrier.
+ ///
+ [EnumMember(Value = "rejected")]
+ Rejected = 6
+ }
+}
diff --git a/src/LinkMobility/Webhook/Text/TextMessageType.cs b/src/LinkMobility/Webhook/Text/TextMessageType.cs
new file mode 100644
index 0000000..7e7983e
--- /dev/null
+++ b/src/LinkMobility/Webhook/Text/TextMessageType.cs
@@ -0,0 +1,30 @@
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Converters;
+
+namespace AMWD.Net.Api.LinkMobility.Webhook.Text
+{
+ ///
+ /// Defines the type of notification.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum TextMessageType
+ {
+ ///
+ /// Notification of an incoming text message.
+ ///
+ [EnumMember(Value = "text")]
+ Text = 1,
+
+ ///
+ /// Notification of an incoming binary message.
+ ///
+ [EnumMember(Value = "binary")]
+ Binary = 2,
+
+ ///
+ /// Notification of a delivery report.
+ ///
+ [EnumMember(Value = "deliveryReport")]
+ DeliveryReport = 3
+ }
+}
diff --git a/src/LinkMobility/Models/IncomingMessageNotification.cs b/src/LinkMobility/Webhook/Text/TextNotification.cs
similarity index 67%
rename from src/LinkMobility/Models/IncomingMessageNotification.cs
rename to src/LinkMobility/Webhook/Text/TextNotification.cs
index 552b527..290df9b 100644
--- a/src/LinkMobility/Models/IncomingMessageNotification.cs
+++ b/src/LinkMobility/Webhook/Text/TextNotification.cs
@@ -1,194 +1,170 @@
-using System.Runtime.Serialization;
-using Newtonsoft.Json.Converters;
-
-namespace AMWD.Net.Api.LinkMobility
-{
- ///
- /// Represents a notification for an incoming message or delivery report. (API)
- ///
- public class IncomingMessageNotification
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The notification id.
- /// The transfer id.
- public IncomingMessageNotification(string notificationId, string transferId)
- {
- NotificationId = notificationId;
- TransferId = transferId;
- }
-
- ///
- /// Defines the content type of your notification.
- ///
- [JsonProperty("messageType")]
- public Type MessageType { get; set; }
-
- ///
- /// 20 digit long identification of your notification.
- ///
- [JsonProperty("notificationId")]
- public string NotificationId { get; set; }
-
- ///
- /// :
- ///
- /// Unique transfer-id to connect the deliveryReport to the initial message.
- ///
- [JsonProperty("transferId")]
- public string TransferId { get; set; }
-
- ///
- /// , :
- ///
- /// Indicates whether you received message is a SMS or a flash-SMS.
- ///
- [JsonProperty("messageFlashSms")]
- public bool? MessageFlashSms { get; set; }
-
- ///
- /// Originator of the sender.
- ///
- [JsonProperty("senderAddress")]
- public string? SenderAddress { get; set; }
-
- ///
- /// , :
- ///
- /// - defines the number format of the mobile originated .
- /// International numbers always includes the country prefix.
- ///
- [JsonProperty("senderAddressType")]
- public AddressType? SenderAddressType { get; set; }
-
- ///
- /// Senders address, can either be
- /// (4366012345678),
- /// (066012345678) or a
- /// (1234).
- ///
- [JsonProperty("recipientAddress")]
- public string? RecipientAddress { get; set; }
-
- ///
- /// , :
- ///
- /// Defines the number format of the mobile originated message.
- ///
- [JsonProperty("recipientAddressType")]
- public AddressType? RecipientAddressType { get; set; }
-
- ///
- /// :
- ///
- /// Text body of the message encoded in UTF-8.
- /// In the case of concatenated SMS it will contain the complete content of all segments.
- ///
- [JsonProperty("textMessageContent")]
- public string? TextMessageContent { get; set; }
-
- ///
- /// :
- ///
- /// Indicates whether a user-data-header is included within a Base64 encoded byte segment.
- ///
- [JsonProperty("userDataHeaderPresent")]
- public bool? UserDataHeaderPresent { get; set; }
-
- ///
- /// :
- ///
- /// Content of a binary SMS in an array of Base64 strings (URL safe).
- ///
- [JsonProperty("binaryMessageContent")]
- public IReadOnlyCollection? BinaryMessageContent { get; set; }
-
- ///
- /// :
- ///
- /// Status of the message.
- ///
- [JsonProperty("deliveryReportMessageStatus")]
- public DeliveryStatus? DeliveryReportMessageStatus { get; set; }
-
- ///
- /// :
- ///
- /// ISO 8601 timestamp. Point of time sending the message to recipients address.
- ///
- [JsonProperty("sentOn")]
- public DateTime? SentOn { get; set; }
-
- ///
- /// :
- ///
- /// ISO 8601 timestamp. Point of time of submitting the message to the mobile operators network.
- ///
- [JsonProperty("deliveredOn")]
- public DateTime? DeliveredOn { get; set; }
-
- ///
- /// :
- ///
- /// Type of delivery used to send the message.
- ///
- [JsonProperty("deliveredAs")]
- public DeliveryType? DeliveredAs { get; set; }
-
- ///
- /// :
- ///
- /// In the case of a delivery report, the contains the optional submitted message id.
- ///
- [JsonProperty("clientMessageId")]
- public string? ClientMessageId { get; set; }
-
- ///
- /// Defines the type of notification.
- ///
- [JsonConverter(typeof(StringEnumConverter))]
- public enum Type
- {
- ///
- /// Notification of an incoming text message.
- ///
- [EnumMember(Value = "text")]
- Text = 1,
-
- ///
- /// Notification of an incoming binary message.
- ///
- [EnumMember(Value = "binary")]
- Binary = 2,
-
- ///
- /// Notification of a delivery report.
- ///
- [EnumMember(Value = "deliveryReport")]
- DeliveryReport = 3
- }
-
- ///
- /// Tries to parse the given content as .
- ///
- /// The given content (should be the notification json).
- /// The deserialized notification.
- ///
- /// if the content could be parsed; otherwise, .
- ///
- public static bool TryParse(string json, out IncomingMessageNotification? notification)
- {
- try
- {
- notification = json.DeserializeObject();
- return notification != null;
- }
- catch
- {
- notification = null;
- return false;
- }
- }
- }
-}
+using AMWD.Net.Api.LinkMobility.Text;
+using AMWD.Net.Api.LinkMobility.Utils;
+
+namespace AMWD.Net.Api.LinkMobility.Webhook.Text
+{
+ ///
+ /// Represents a notification for an incoming text message or delivery report.
+ /// (API)
+ ///
+ public class TextNotification
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The notification id.
+ /// The transfer id.
+ public TextNotification(string notificationId, string transferId)
+ {
+ NotificationId = notificationId;
+ TransferId = transferId;
+ }
+
+ ///
+ /// Defines the content type of your notification.
+ ///
+ [JsonProperty("messageType")]
+ public TextMessageType MessageType { get; set; }
+
+ ///
+ /// 20 digit long identification of your notification.
+ ///
+ [JsonProperty("notificationId")]
+ public string NotificationId { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Unique transfer-id to connect the deliveryReport to the initial message.
+ ///
+ [JsonProperty("transferId")]
+ public string TransferId { get; set; }
+
+ ///
+ /// , :
+ ///
+ /// Indicates whether you received message is a SMS or a flash-SMS.
+ ///
+ [JsonProperty("messageFlashSms")]
+ public bool? MessageFlashSms { get; set; }
+
+ ///
+ /// Originator of the sender.
+ ///
+ [JsonProperty("senderAddress")]
+ public string? SenderAddress { get; set; }
+
+ ///
+ /// , :
+ ///
+ /// - defines the number format of the mobile originated .
+ /// International numbers always includes the country prefix.
+ ///
+ [JsonProperty("senderAddressType")]
+ public AddressType? SenderAddressType { get; set; }
+
+ ///
+ /// Senders address, can either be
+ /// (4366012345678),
+ /// (066012345678) or a
+ /// (1234).
+ ///
+ [JsonProperty("recipientAddress")]
+ public string? RecipientAddress { get; set; }
+
+ ///
+ /// , :
+ ///
+ /// Defines the number format of the mobile originated message.
+ ///
+ [JsonProperty("recipientAddressType")]
+ public AddressType? RecipientAddressType { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Text body of the message encoded in UTF-8.
+ /// In the case of concatenated SMS it will contain the complete content of all segments.
+ ///
+ [JsonProperty("textMessageContent")]
+ public string? TextMessageContent { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Indicates whether a user-data-header is included within a Base64 encoded byte segment.
+ ///
+ [JsonProperty("userDataHeaderPresent")]
+ public bool? UserDataHeaderPresent { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Content of a binary SMS in an array of Base64 strings (URL safe).
+ ///
+ [JsonProperty("binaryMessageContent")]
+ public IReadOnlyCollection? BinaryMessageContent { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Status of the message.
+ ///
+ [JsonProperty("deliveryReportMessageStatus")]
+ public DeliveryStatus? DeliveryReportMessageStatus { get; set; }
+
+ ///
+ /// :
+ ///
+ /// ISO 8601 timestamp. Point of time sending the message to recipients address.
+ ///
+ [JsonProperty("sentOn")]
+ public DateTime? SentOn { get; set; }
+
+ ///
+ /// :
+ ///
+ /// ISO 8601 timestamp. Point of time of submitting the message to the mobile operators network.
+ ///
+ [JsonProperty("deliveredOn")]
+ public DateTime? DeliveredOn { get; set; }
+
+ ///
+ /// :
+ ///
+ /// Type of delivery used to send the message.
+ ///
+ [JsonProperty("deliveredAs")]
+ public DeliveryType? DeliveredAs { get; set; }
+
+ ///
+ /// :
+ ///
+ /// In the case of a delivery report, the contains the optional submitted message id.
+ ///
+ [JsonProperty("clientMessageId")]
+ public string? ClientMessageId { get; set; }
+
+ ///
+ /// Tries to parse the given content as .
+ ///
+ /// The given content (should be the notification json).
+ /// The deserialized notification.
+ ///
+ /// if the content could be parsed; otherwise, .
+ ///
+ public static bool TryParse(string json, out TextNotification? notification)
+ {
+ try
+ {
+ notification = json.DeserializeObject();
+ return notification != null;
+ }
+ catch
+ {
+ notification = null;
+ return false;
+ }
+ }
+ }
+}
diff --git a/test/LinkMobility.Tests/LinkMobilityClientTest.cs b/test/LinkMobility.Tests/LinkMobilityClientTest.cs
index 8e10922..00e82ea 100644
--- a/test/LinkMobility.Tests/LinkMobilityClientTest.cs
+++ b/test/LinkMobility.Tests/LinkMobilityClientTest.cs
@@ -145,7 +145,7 @@ namespace LinkMobility.Tests
var client = GetClient();
// Act
- var response = await client.PostAsync("test", _request, null, TestContext.CancellationToken);
+ var response = await client.PostAsync("test", _request, TestContext.CancellationToken);
// Assert
Assert.IsNotNull(response);
@@ -166,57 +166,12 @@ namespace LinkMobility.Tests
Assert.AreEqual("Scheme Parameter", callback.Headers["Authorization"]);
Assert.AreEqual("LinkMobilityClient/1.0.0", callback.Headers["User-Agent"]);
- _httpMessageHandlerMock.Mock
- .Protected()
- .Verify("SendAsync", Times.Once(), ItExpr.IsAny(), ItExpr.IsAny());
+ _httpMessageHandlerMock.Protected.Verify("SendAsync", Times.Once(), ItExpr.IsAny(), ItExpr.IsAny());
_clientOptionsMock.VerifyGet(o => o.DefaultQueryParams, Times.Exactly(2));
VerifyNoOtherCalls();
}
- [TestMethod]
- public async Task ShouldAddCustomQueryParameters()
- {
- // Arrange
- var queryParams = new TestParams();
- _httpMessageHandlerMock.Responses.Enqueue(new HttpResponseMessage
- {
- StatusCode = HttpStatusCode.OK,
- Content = new StringContent(@"{ ""string"": ""some-string"", ""integer"": 123 }", Encoding.UTF8, "application/json"),
- });
-
- var client = GetClient();
-
- // Act
- var response = await client.PostAsync("params/path", _request, queryParams, TestContext.CancellationToken);
-
- // Assert
- Assert.IsNotNull(response);
-
- Assert.HasCount(1, _httpMessageHandlerMock.RequestCallbacks);
-
- var callback = _httpMessageHandlerMock.RequestCallbacks.First();
- Assert.AreEqual(HttpMethod.Post, callback.HttpMethod);
- Assert.AreEqual("https://localhost/rest/params/path?test=query+text", callback.Url);
- Assert.AreEqual(@"{""string"":""Happy Testing"",""integer"":54321}", callback.Content);
-
- Assert.HasCount(3, callback.Headers);
- Assert.IsTrue(callback.Headers.ContainsKey("Accept"));
- Assert.IsTrue(callback.Headers.ContainsKey("Authorization"));
- Assert.IsTrue(callback.Headers.ContainsKey("User-Agent"));
-
- Assert.AreEqual("application/json", callback.Headers["Accept"]);
- Assert.AreEqual("Scheme Parameter", callback.Headers["Authorization"]);
- Assert.AreEqual("LinkMobilityClient/1.0.0", callback.Headers["User-Agent"]);
-
- _httpMessageHandlerMock.Mock
- .Protected()
- .Verify("SendAsync", Times.Once(), ItExpr.IsAny(), ItExpr.IsAny());
-
- _clientOptionsMock.VerifyGet(o => o.DefaultQueryParams, Times.Once);
- VerifyNoOtherCalls();
- }
-
[TestMethod]
public void ShouldDisposeHttpClient()
{
@@ -227,9 +182,7 @@ namespace LinkMobility.Tests
client.Dispose();
// Assert
- _httpMessageHandlerMock.Mock
- .Protected()
- .Verify("Dispose", Times.Once(), exactParameterMatch: true, true);
+ _httpMessageHandlerMock.Protected.Verify("Dispose", Times.Once(), exactParameterMatch: true, true);
VerifyNoOtherCalls();
}
@@ -245,9 +198,7 @@ namespace LinkMobility.Tests
client.Dispose();
// Assert
- _httpMessageHandlerMock.Mock
- .Protected()
- .Verify("Dispose", Times.Once(), exactParameterMatch: true, true);
+ _httpMessageHandlerMock.Protected.Verify("Dispose", Times.Once(), exactParameterMatch: true, true);
VerifyNoOtherCalls();
}
@@ -320,7 +271,7 @@ namespace LinkMobility.Tests
// Act & Assert
await Assert.ThrowsExactlyAsync(async () =>
{
- await client.PostAsync