From 0c770a3e064096fd4d780f6f3dafe487eca5b87a Mon Sep 17 00:00:00 2001 From: BiBi Date: Fri, 10 Aug 2018 14:44:53 +0100 Subject: [PATCH 1/5] added redact transaction functionnality --- Nexmo.api/Redact.cs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Nexmo.api/Redact.cs diff --git a/Nexmo.api/Redact.cs b/Nexmo.api/Redact.cs new file mode 100644 index 000000000..c5c06cbe1 --- /dev/null +++ b/Nexmo.api/Redact.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using Nexmo.Api.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Nexmo.Api +{ + public static class Redact + { + public class RedactCommand + { + /// + /// The transaction ID to redact + /// + public string Id { get; set; } + /// + /// Product name that the ID provided relates to + /// Must be one of: sms, voice, number-insight, verify, verify-sdk, message or workflow + /// + public string Product { get; set; } + /// + /// Required if redacting SMS data + /// Must be one of: inbound or outbound + /// + public string Type { get; set; } + } + + /// + /// POST /v1/redact/transaction - redacts a specific transaction + /// + /// + /// (Optional) Overridden credentials for only this request + /// + public static void RedactTransaction(RedactCommand cmd, Credentials creds = null) + { + VersionedApiRequest.DoRequest("POST", ApiRequest.GetBaseUriFor(typeof(Redact), "/v1/redact/transaction"), cmd, creds); + } + } +} From 7a78cf8f59516c8e7b01bfd605c146a05eac9c3c Mon Sep 17 00:00:00 2001 From: BiBi Date: Wed, 15 Aug 2018 23:29:34 +0100 Subject: [PATCH 2/5] Added Redact --- Nexmo.Api/Client/Client.cs | 2 + Nexmo.Api/Client/Redact.cs | 25 ++ Nexmo.Api/Request/ApiRequest.cs | 454 ++++++++++++++++++-------------- 3 files changed, 285 insertions(+), 196 deletions(-) create mode 100644 Nexmo.Api/Client/Redact.cs diff --git a/Nexmo.Api/Client/Client.cs b/Nexmo.Api/Client/Client.cs index 6ddd7720f..091d52e47 100644 --- a/Nexmo.Api/Client/Client.cs +++ b/Nexmo.Api/Client/Client.cs @@ -36,6 +36,7 @@ private void PropagateCredentials() Search = new ClientMethods.Search(Credentials); ShortCode = new ClientMethods.ShortCode(Credentials); SMS = new ClientMethods.SMS(Credentials); + Redact = new ClientMethods.Redact(Credentials); } public ClientMethods.Account Account { get; private set; } @@ -47,5 +48,6 @@ private void PropagateCredentials() public ClientMethods.Search Search { get; private set; } public ClientMethods.ShortCode ShortCode { get; private set; } public ClientMethods.SMS SMS { get; private set; } + public ClientMethods.Redact Redact { get; private set; } } } diff --git a/Nexmo.Api/Client/Redact.cs b/Nexmo.Api/Client/Redact.cs new file mode 100644 index 000000000..c1f75d2c4 --- /dev/null +++ b/Nexmo.Api/Client/Redact.cs @@ -0,0 +1,25 @@ +using Nexmo.Api.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Nexmo.Api.Redact; + +namespace Nexmo.Api.ClientMethods +{ + public class Redact + { + public Credentials Credentials { get; set; } + + public Redact(Credentials creds) + { + Credentials = creds; + } + + public void RedactTransaction (RedactRequest redactRequest, Credentials creds = null) + { + Nexmo.Api.Redact.RedactTransaction(redactRequest, creds ?? Credentials); + } + } +} diff --git a/Nexmo.Api/Request/ApiRequest.cs b/Nexmo.Api/Request/ApiRequest.cs index 83a94febb..61b38363d 100644 --- a/Nexmo.Api/Request/ApiRequest.cs +++ b/Nexmo.Api/Request/ApiRequest.cs @@ -1,106 +1,107 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Text; -using Newtonsoft.Json; -using System.Net.Http; -using System.Security.Cryptography; -using Nexmo.Api.Logging; - -namespace Nexmo.Api.Request -{ - /// - /// Responsible for sending all Nexmo API requests that do not make use of Application authentication. - /// For application authentication, see VersionedApiRequest. - /// - public static class ApiRequest - { - private static readonly ILog Logger = LogProvider.GetLogger(typeof(ApiRequest), "Nexmo.Api.Request.ApiRequest"); - - private static StringBuilder BuildQueryString(IDictionary parameters, Credentials creds = null) - { - var apiKey = (creds?.ApiKey ?? Configuration.Instance.Settings["appSettings:Nexmo.api_key"]).ToUpper(); - var apiSecret = creds?.ApiSecret ?? Configuration.Instance.Settings["appSettings:Nexmo.api_secret"]; - var securitySecret = creds?.SecuritySecret ?? Configuration.Instance.Settings["appSettings:Nexmo.security_secret"]; - - var sb = new StringBuilder(); - Action, StringBuilder> buildStringFromParams = (param, strings) => - { - foreach (var kvp in param) - { - strings.AppendFormat("{0}={1}&", WebUtility.UrlEncode(kvp.Key), WebUtility.UrlEncode(kvp.Value)); - } - }; - parameters.Add("api_key", apiKey); - if (string.IsNullOrEmpty(securitySecret)) - { - // security secret not provided, do not sign - parameters.Add("api_secret", apiSecret); - buildStringFromParams(parameters, sb); - return sb; - } - // security secret provided, sort and sign request - parameters.Add("timestamp", ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString(CultureInfo.InvariantCulture)); +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Text; +using Newtonsoft.Json; +using System.Net.Http; +using System.Security.Cryptography; +using Nexmo.Api.Logging; + +namespace Nexmo.Api.Request +{ + /// + /// Responsible for sending all Nexmo API requests that do not make use of Application authentication. + /// For application authentication, see VersionedApiRequest. + /// + public static class ApiRequest + { + private static readonly ILog Logger = LogProvider.GetLogger(typeof(ApiRequest), "Nexmo.Api.Request.ApiRequest"); + + private static StringBuilder BuildQueryString(IDictionary parameters, Credentials creds = null) + { + var apiKey = (creds?.ApiKey ?? Configuration.Instance.Settings["appSettings:Nexmo.api_key"]).ToLower(); + var apiSecret = creds?.ApiSecret ?? Configuration.Instance.Settings["appSettings:Nexmo.api_secret"]; + var securitySecret = creds?.SecuritySecret ?? Configuration.Instance.Settings["appSettings:Nexmo.security_secret"]; + + var sb = new StringBuilder(); + Action, StringBuilder> buildStringFromParams = (param, strings) => + { + foreach (var kvp in param) + { + strings.AppendFormat("{0}={1}&", WebUtility.UrlEncode(kvp.Key), WebUtility.UrlEncode(kvp.Value)); + } + }; + parameters.Add("api_key", apiKey); + if (string.IsNullOrEmpty(securitySecret)) + { + // security secret not provided, do not sign + parameters.Add("api_secret", apiSecret); + buildStringFromParams(parameters, sb); + return sb; + } + // security secret provided, sort and sign request + parameters.Add("timestamp", ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds).ToString(CultureInfo.InvariantCulture)); var sortedParams = new SortedDictionary(parameters); - buildStringFromParams(sortedParams, sb); - var queryToSign = "&" + sb; - queryToSign = queryToSign.Remove(queryToSign.Length - 1) + securitySecret.ToUpper(); - var hashgen = MD5.Create(); - var hash = hashgen.ComputeHash(Encoding.UTF8.GetBytes(queryToSign)); - sb.AppendFormat("sig={0}", ByteArrayToHexHelper.ByteArrayToHex(hash).ToLower()); - return sb; - } - - internal static Dictionary GetParameters(object parameters) - { - var paramType = parameters.GetType().GetTypeInfo(); - var apiParams = new Dictionary(); - foreach (var property in paramType.GetProperties()) - { - string jsonPropertyName = null; - - if (property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).Any()) - { - jsonPropertyName = - ((JsonPropertyAttribute)property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).First()) - .PropertyName; - } - - if (null == paramType.GetProperty(property.Name).GetValue(parameters, null)) continue; - - apiParams.Add(string.IsNullOrEmpty(jsonPropertyName) ? property.Name : jsonPropertyName, - paramType.GetProperty(property.Name).GetValue(parameters, null).ToString()); - } - return apiParams; - } - - internal static Uri GetBaseUriFor(Type component, string url = null) - { - Uri baseUri; - if (typeof(NumberVerify) == component - || typeof(Application) == component - || typeof(Voice.Call) == component) - { - baseUri = new Uri(Configuration.Instance.Settings["appSettings:Nexmo.Url.Api"]); - } - else - { - baseUri = new Uri(Configuration.Instance.Settings["appSettings:Nexmo.Url.Rest"]); - } - return string.IsNullOrEmpty(url) ? baseUri : new Uri(baseUri, url); - } - - internal static StringBuilder GetQueryStringBuilderFor(object parameters, Credentials creds = null) - { - var apiParams = GetParameters(parameters); - var sb = BuildQueryString(apiParams, creds); - return sb; - } - + buildStringFromParams(sortedParams, sb); + var queryToSign = "&" + sb; + queryToSign = queryToSign.Remove(queryToSign.Length - 1) + securitySecret.ToUpper(); + var hashgen = MD5.Create(); + var hash = hashgen.ComputeHash(Encoding.UTF8.GetBytes(queryToSign)); + sb.AppendFormat("sig={0}", ByteArrayToHexHelper.ByteArrayToHex(hash).ToLower()); + return sb; + } + + internal static Dictionary GetParameters(object parameters) + { + var paramType = parameters.GetType().GetTypeInfo(); + var apiParams = new Dictionary(); + foreach (var property in paramType.GetProperties()) + { + string jsonPropertyName = null; + + if (property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).Any()) + { + jsonPropertyName = + ((JsonPropertyAttribute)property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).First()) + .PropertyName; + } + + if (null == paramType.GetProperty(property.Name).GetValue(parameters, null)) continue; + + apiParams.Add(string.IsNullOrEmpty(jsonPropertyName) ? property.Name : jsonPropertyName, + paramType.GetProperty(property.Name).GetValue(parameters, null).ToString()); + } + return apiParams; + } + + internal static Uri GetBaseUriFor(Type component, string url = null) + { + Uri baseUri; + if (typeof(NumberVerify) == component + || typeof(Application) == component + || typeof(Voice.Call) == component + || typeof(Redact) == component) + { + baseUri = new Uri(Configuration.Instance.Settings["appSettings:Nexmo.Url.Api"]); + } + else + { + baseUri = new Uri(Configuration.Instance.Settings["appSettings:Nexmo.Url.Rest"]); + } + return string.IsNullOrEmpty(url) ? baseUri : new Uri(baseUri, url); + } + + internal static StringBuilder GetQueryStringBuilderFor(object parameters, Credentials creds = null) + { + var apiParams = GetParameters(parameters); + var sb = BuildQueryString(apiParams, creds); + return sb; + } + /// /// Send a GET request to the Nexmo API. /// Do not include credentials in the parameters object. If you need to override credentials, use the optional Credentials parameter. @@ -108,57 +109,57 @@ internal static StringBuilder GetQueryStringBuilderFor(object parameters, Creden /// The URI to GET /// Parameters required by the endpoint (do not include credentials) /// (Optional) Overridden credentials for only this request - /// - public static string DoRequest(Uri uri, Dictionary parameters, Credentials creds = null) - { - var sb = BuildQueryString(parameters, creds); - return DoRequest(new Uri(uri, "?" + sb), creds); - } - - internal static string DoRequest(Uri uri, object parameters, Credentials creds = null) + /// + public static string DoRequest(Uri uri, Dictionary parameters, Credentials creds = null) + { + var sb = BuildQueryString(parameters, creds); + return DoRequest(new Uri(uri, "?" + sb), creds); + } + + internal static string DoRequest(Uri uri, object parameters, Credentials creds = null) + { + var sb = GetQueryStringBuilderFor(parameters, creds); + + return DoRequest(new Uri(uri, "?" + sb), creds); + } + + internal static string DoRequest(Uri uri, Credentials creds) { - var sb = GetQueryStringBuilderFor(parameters, creds); - - return DoRequest(new Uri(uri, "?" + sb), creds); - } - - internal static string DoRequest(Uri uri, Credentials creds) - { var req = new HttpRequestMessage { RequestUri = uri, Method = HttpMethod.Get - }; - VersionedApiRequest.SetUserAgent(ref req, creds); - - using (LogProvider.OpenMappedContext("ApiRequest.DoRequest",uri.GetHashCode())) - { - Logger.Debug($"GET {uri}"); + }; + VersionedApiRequest.SetUserAgent(ref req, creds); + + using (LogProvider.OpenMappedContext("ApiRequest.DoRequest",uri.GetHashCode())) + { + Logger.Debug($"GET {uri}"); var sendTask = Configuration.Instance.Client.SendAsync(req); - sendTask.Wait(); - - if (!sendTask.Result.IsSuccessStatusCode) - { - Logger.Error($"FAIL: {sendTask.Result.StatusCode}"); - - if (string.Compare(Configuration.Instance.Settings["appSettings:Nexmo.Api.EnsureSuccessStatusCode"], - "true", StringComparison.OrdinalIgnoreCase) == 0) - { - sendTask.Result.EnsureSuccessStatusCode(); - } - } - + sendTask.Wait(); + + if (!sendTask.Result.IsSuccessStatusCode) + { + Logger.Error($"FAIL: {sendTask.Result.StatusCode}"); + + if (string.Compare(Configuration.Instance.Settings["appSettings:Nexmo.Api.EnsureSuccessStatusCode"], + "true", StringComparison.OrdinalIgnoreCase) == 0) + { + sendTask.Result.EnsureSuccessStatusCode(); + } + } + var readTask = sendTask.Result.Content.ReadAsStreamAsync(); readTask.Wait(); string json; - using (var sr = new StreamReader(readTask.Result)) - { - json = sr.ReadToEnd(); - } - Logger.Debug(json); - return json; - } + using (var sr = new StreamReader(readTask.Result)) + { + json = sr.ReadToEnd(); + } + Logger.Debug(json); + return json; + } } /// @@ -170,72 +171,133 @@ internal static string DoRequest(Uri uri, Credentials creds) /// Parameters required by the endpoint (do not include credentials) /// (Optional) Overridden credentials for only this request /// - public static NexmoResponse DoRequest(string method, Uri uri, Dictionary parameters, Credentials creds = null) + public static NexmoResponse DoRequest(string method, Uri uri, Dictionary parameters, Credentials creds = null) { - var sb = new StringBuilder(); - // if parameters is null, assume that key and secret have been taken care of - if (null != parameters) - { - sb = BuildQueryString(parameters, creds); - } - + var sb = new StringBuilder(); + // if parameters is null, assume that key and secret have been taken care of + if (null != parameters) + { + sb = BuildQueryString(parameters, creds); + } + var req = new HttpRequestMessage { RequestUri = uri, Method = new HttpMethod(method) }; VersionedApiRequest.SetUserAgent(ref req, creds); - + var data = Encoding.ASCII.GetBytes(sb.ToString()); req.Content = new ByteArrayContent(data); - req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded"); - - using (LogProvider.OpenMappedContext("ApiRequest.DoRequest",uri.GetHashCode())) - { - Logger.Debug($"{method} {uri} {sb}"); - var sendTask = Configuration.Instance.Client.SendAsync(req); - sendTask.Wait(); - - if (!sendTask.Result.IsSuccessStatusCode) - { + req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded"); + + using (LogProvider.OpenMappedContext("ApiRequest.DoRequest",uri.GetHashCode())) + { + Logger.Debug($"{method} {uri} {sb}"); + var sendTask = Configuration.Instance.Client.SendAsync(req); + sendTask.Wait(); + + if (!sendTask.Result.IsSuccessStatusCode) + { Logger.Error($"FAIL: {sendTask.Result.StatusCode}"); if (string.Compare(Configuration.Instance.Settings["appSettings:Nexmo.Api.EnsureSuccessStatusCode"], "true", StringComparison.OrdinalIgnoreCase) == 0) { sendTask.Result.EnsureSuccessStatusCode(); - } - - return new NexmoResponse - { - Status = sendTask.Result.StatusCode - }; - } - - string json; - var readTask = sendTask.Result.Content.ReadAsStreamAsync(); - readTask.Wait(); - using (var sr = new StreamReader(readTask.Result)) - { - json = sr.ReadToEnd(); - } - Logger.Debug(json); - return new NexmoResponse - { - Status = sendTask.Result.StatusCode, - JsonResponse = json - }; - } - } - - internal static NexmoResponse DoPostRequest(Uri uri, object parameters, Credentials creds = null) - { - var apiParams = GetParameters(parameters); - return DoPostRequest(uri, apiParams, creds); - } - - internal static NexmoResponse DoPostRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); - internal static NexmoResponse DoPutRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("PUT", uri, parameters, creds); - internal static NexmoResponse DoDeleteRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("DELETE", uri, parameters, creds); - } + } + + return new NexmoResponse + { + Status = sendTask.Result.StatusCode + }; + } + + string json; + var readTask = sendTask.Result.Content.ReadAsStreamAsync(); + readTask.Wait(); + using (var sr = new StreamReader(readTask.Result)) + { + json = sr.ReadToEnd(); + } + Logger.Debug(json); + return new NexmoResponse + { + Status = sendTask.Result.StatusCode, + JsonResponse = json + }; + } + } + + public static NexmoResponse DoRequest(string method, Uri uri, object parameter, Credentials creds = null) + { + var sb = new StringBuilder(); + var parameters = new Dictionary(); + sb = BuildQueryString(parameters, creds); + + var requestContent = JsonConvert.SerializeObject(parameter); + + var req = new HttpRequestMessage + { + RequestUri = new Uri((uri.OriginalString + $"?{sb}").ToLower()), + Method = new HttpMethod(method), + Content = new StringContent(requestContent, Encoding.ASCII, "application/json"), + }; + VersionedApiRequest.SetUserAgent(ref req, creds); + + using (LogProvider.OpenMappedContext("ApiRequest.DoRequest", uri.GetHashCode())) + { + Logger.Debug($"{method} {uri} {sb}"); + var sendTask = Configuration.Instance.Client.SendAsync(req); + sendTask.Wait(); + + if (!sendTask.Result.IsSuccessStatusCode) + { + + Logger.Error($"FAIL: {sendTask.Result.StatusCode}"); + + if (string.Compare(Configuration.Instance.Settings["appSettings:Nexmo.Api.EnsureSuccessStatusCode"], + "true", StringComparison.OrdinalIgnoreCase) == 0) + { + sendTask.Result.EnsureSuccessStatusCode(); + } + + return new NexmoResponse + { + Status = sendTask.Result.StatusCode + }; + } + + string jsonResult; + var readTask = sendTask.Result.Content.ReadAsStreamAsync(); + readTask.Wait(); + using (var sr = new StreamReader(readTask.Result)) + { + jsonResult = sr.ReadToEnd(); + } + Logger.Debug(jsonResult); + return new NexmoResponse + { + Status = sendTask.Result.StatusCode, + JsonResponse = jsonResult + }; + } + } + + internal static NexmoResponse DoPostRequest(Uri uri, object parameters, Credentials creds = null) + { + var apiParams = GetParameters(parameters); + return DoPostRequest(uri, apiParams, creds); + } + + internal static NexmoResponse MakePostRequest(Uri uri, object parameters, Credentials creds = null) + { + return MakeRequest(uri, parameters, creds); + } + + internal static NexmoResponse DoPostRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); + internal static NexmoResponse MakeRequest(Uri uri, object parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); + internal static NexmoResponse DoPutRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("PUT", uri, parameters, creds); + internal static NexmoResponse DoDeleteRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("DELETE", uri, parameters, creds); + } } \ No newline at end of file From acff6e3f28aacebf5db89ac023e160f7d092334e Mon Sep 17 00:00:00 2001 From: BiBi Date: Thu, 16 Aug 2018 00:26:59 +0100 Subject: [PATCH 3/5] updated README --- Nexmo.api/Redact.cs | 24 +++++++-- README.md | 129 +++++++++++++++++++++++++++++++++----------- 2 files changed, 117 insertions(+), 36 deletions(-) diff --git a/Nexmo.api/Redact.cs b/Nexmo.api/Redact.cs index c5c06cbe1..1dc79b0f3 100644 --- a/Nexmo.api/Redact.cs +++ b/Nexmo.api/Redact.cs @@ -10,33 +10,49 @@ namespace Nexmo.Api { public static class Redact { - public class RedactCommand + public class RedactRequest { /// /// The transaction ID to redact /// + [JsonProperty("id")] public string Id { get; set; } /// /// Product name that the ID provided relates to /// Must be one of: sms, voice, number-insight, verify, verify-sdk, message or workflow /// + [JsonProperty("product")] public string Product { get; set; } /// /// Required if redacting SMS data /// Must be one of: inbound or outbound /// + [JsonProperty("type")] public string Type { get; set; } + + public RedactRequest (string id, string product) + { + Id = id; + Product = product; + } + public RedactRequest(string id, string product, string type) + { + Id = id; + Product = product; + Type = type; + } + } /// /// POST /v1/redact/transaction - redacts a specific transaction /// - /// + /// /// (Optional) Overridden credentials for only this request /// - public static void RedactTransaction(RedactCommand cmd, Credentials creds = null) + public static void RedactTransaction(RedactRequest redactRequest, Credentials creds = null) { - VersionedApiRequest.DoRequest("POST", ApiRequest.GetBaseUriFor(typeof(Redact), "/v1/redact/transaction"), cmd, creds); + ApiRequest.MakePostRequest(ApiRequest.GetBaseUriFor(typeof(Redact), "/v1/redact/transaction"), redactRequest, creds); } } } diff --git a/README.md b/README.md index 0d86d2c25..7813d82b6 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,29 @@ Targeted frameworks: Configuration: -------------- + +* Create a Nexmo Client instance and pass in credentials in the constructor + +```csharp +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO-API-KEY", + ApiSecret = "NEXMO-API-SECRET" + }); +``` + +```csharp +var results = client.SMS.Send(request: new SMS.SMSRequest + { + + from = NEXMO_NUMBER, + to = TO_NUMBER, + text = "Hello, I'm an SMS sent to you using Nexmo" + }); +``` + +Alternatively: + * Provide the nexmo URLs, API key, secret, and application credentials (for JWT) in ```appsettings.json```: ```json @@ -51,8 +74,8 @@ Configuration: "Nexmo.UserAgent": "myApp/1.0", "Nexmo.Url.Rest": "https://rest.nexmo.com", "Nexmo.Url.Api": "https://api.nexmo.com", - "Nexmo.api_key": "", - "Nexmo.api_secret": "", + "Nexmo.api_key": "NEXMO-API-KEY", + "Nexmo.api_secret": "NEXMO-API-SECRET", "Nexmo.Application.Id": "ffffffff-ffff-ffff-ffff-ffffffffffff", "Nexmo.Application.Key": "c:\\path\\to\\your\\application\\private.key" @@ -65,27 +88,6 @@ Configuration: * ```appsettings.json``` which overrides * ```settings.json``` -Alternatively: -* Provide the credentials as part of the API call. - -```csharp -var creds = new Nexmo.Api.Request.Credentials - { - ApiKey = NEXMO_API_KEY, - ApiSecret = NEXMO_API_SECRET, - ApplicationId = NEXMO_APPLICATION_ID, - ApplicationKey = NEXMO_APPLICATION_KEY - }; -``` - -```csharp -var results = SMS.Send(new SMS.SMSRequest -{ - from = "15555551212", - to = "17775551212", - text = "this is a test" -}, creds); -``` ### Configuration Reference @@ -153,9 +155,11 @@ Examples We are working on a separate repository for .NET examples. [Check it out here!](https://github.com/nexmo-community/nexmo-dotnet-quickstart) The following examples show how to: + * [Send a message](#sending-a-message) * [Receive a message](#receiving-a-message) * [Receive a message delivery receipt](#receiving-a-message-delivery-receipt) + * [Redact a message](#redacting a message) * [Initiate a call](#initiating-a-call) * [Receive a call](#receiving-a-call) * [Send 2FA code](#sending-2fa-code) @@ -166,10 +170,18 @@ The following examples show how to: Use [Nexmo's SMS API][doc_sms] to send a SMS message. ```C# -var results = SMS.Send(new SMS.SMSRequest +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET" + }); +``` + +```C# +var results = client.SMS.Send(new SMS.SMSRequest { - from = "15555551212", - to = "17775551212", + from = NEXMO_NUMBER, + to = TO_NUMBER, text = "this is a test" }); ``` @@ -206,28 +218,54 @@ public ActionResult DLR([FromUri]SMS.SMSDeliveryReceipt response) __NOTE:__ ```[FromUri]``` is deprecated in .NET Core; ```[FromQuery]``` works in this case. +### Redacting a message + +Use [Nexmo's Redact API][doc_redact] to redact a SMS message. + +```C# +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET" + }); +``` + +```C# +client.Redact.RedactTransaction(new Redact.RedactRequest(MESSAGE_ID, "sms", "outbound")); +``` + ### Initiating a Call Use [Nexmo's Voice API][doc_voice] to initiate a voice call. __NOTE:__ You must have a valid Application ID and private key in order to make voice calls. Use either ```Nexmo.Api.Application``` or Nexmo's Node.js-based [CLI tool](https://github.com/nexmo/nexmo-cli) to register. See the [Application API][doc_app] documentation for details. +```C# +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET", + ApplicationId = "NEXMO_APPLICATION_ID", + ApplicationKey = "NEXMO_APPLICATION_PRIVATE_KEY" + } +``` + ```C# using Nexmo.Api.Voice; -Call.Do(new Call.CallCommand +client.Call.Do(new Call.CallCommand { to = new[] { new Call.Endpoint { type = "phone", - number = "15555551212" + number = TO_NUMBER } }, from = new Call.Endpoint { type = "phone", - number = "15557772424" + number = NEXMO_NUMBER }, answer_url = new[] { @@ -239,12 +277,22 @@ Call.Do(new Call.CallCommand Use [Nexmo's Voice API][doc_voice] to receive a voice call. +```C# +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET", + ApplicationId = "NEXMO_APPLICATION_ID", + ApplicationKey = "NEXMO_APPLICATION_PRIVATE_KEY" + } +``` + ```C# using Nexmo.Api.Voice; public ActionResult GetCall(string id) { - var call = Call.Get(id); + var call = client.Call.Get(id); // Do something with call. } ``` @@ -252,11 +300,19 @@ public ActionResult GetCall(string id) Use [Nexmo's Verify API][doc_verify] to send 2FA pin code. +```C# +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET" + } +``` + ```C# public ActionResult Start(string to) { - var start = NumberVerify.Verify(new NumberVerify.VerifyRequest + var start = client.NumberVerify.Verify(new NumberVerify.VerifyRequest { number = to, brand = "NexmoQS" @@ -270,11 +326,19 @@ public ActionResult Start(string to) Use [Nexmo's Verify API][doc_verify] to check 2FA pin code. +```C# +var client = new Client(creds: new Nexmo.Api.Request.Credentials + { + ApiKey = "NEXMO_API_KEY", + ApiSecret = "NEXMO_API_SECRET" + } +``` + ```C# public ActionResult Check(string code) { - var result = NumberVerify.Check(new NumberVerify.CheckRequest + var result = client.NumberVerify.Check(new NumberVerify.CheckRequest { request_id = Session["requestID"].ToString(), code = code @@ -381,4 +445,5 @@ This library is released under the [MIT License][license] [doc_voice]: https://developer.nexmo.com/voice/voice-api/overview?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library [doc_verify]: https://developer.nexmo.com/verify/overview?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library [doc_app]: https://developer.nexmo.com/concepts/guides/applications?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library +[doc_redact]: https://developer.nexmo.com/api/redact?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library [license]: LICENSE.md From b2af336e786ff40ea5d1fb19742fb53d6f786e1c Mon Sep 17 00:00:00 2001 From: BiBi Date: Thu, 16 Aug 2018 00:33:02 +0100 Subject: [PATCH 4/5] Updated CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be291c9d7..c4c818f46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 3.1.0 (2018-08-16) +* Added Redact API implementation. + # 3.0.1 (2018-03-05) * Fixed missed NumberInsight instanciation (#90) From 07b5d0a2d38f2fa4faa3eca5ad15108b40d87d4a Mon Sep 17 00:00:00 2001 From: BiBi Date: Fri, 17 Aug 2018 12:30:18 +0100 Subject: [PATCH 5/5] Renaming some methods --- Nexmo.Api/Request/ApiRequest.cs | 12 ++++++------ Nexmo.api/Redact.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Nexmo.Api/Request/ApiRequest.cs b/Nexmo.Api/Request/ApiRequest.cs index 61b38363d..beebefbad 100644 --- a/Nexmo.Api/Request/ApiRequest.cs +++ b/Nexmo.Api/Request/ApiRequest.cs @@ -229,19 +229,19 @@ public static NexmoResponse DoRequest(string method, Uri uri, Dictionary(); sb = BuildQueryString(parameters, creds); - var requestContent = JsonConvert.SerializeObject(parameter); + var requestContent = JsonConvert.SerializeObject(requestBody); var req = new HttpRequestMessage { RequestUri = new Uri((uri.OriginalString + $"?{sb}").ToLower()), Method = new HttpMethod(method), - Content = new StringContent(requestContent, Encoding.ASCII, "application/json"), + Content = new StringContent(requestContent, Encoding.UTF8, "application/json"), }; VersionedApiRequest.SetUserAgent(ref req, creds); @@ -290,13 +290,13 @@ internal static NexmoResponse DoPostRequest(Uri uri, object parameters, Credenti return DoPostRequest(uri, apiParams, creds); } - internal static NexmoResponse MakePostRequest(Uri uri, object parameters, Credentials creds = null) + internal static NexmoResponse DoPostRequestWithContent(Uri uri, object parameters, Credentials creds = null) { - return MakeRequest(uri, parameters, creds); + return DoRequestWithContent(uri, parameters, creds); } internal static NexmoResponse DoPostRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); - internal static NexmoResponse MakeRequest(Uri uri, object parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); + internal static NexmoResponse DoRequestWithContent(Uri uri, object parameters, Credentials creds = null) => DoRequest("POST", uri, parameters, creds); internal static NexmoResponse DoPutRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("PUT", uri, parameters, creds); internal static NexmoResponse DoDeleteRequest(Uri uri, Dictionary parameters, Credentials creds = null) => DoRequest("DELETE", uri, parameters, creds); } diff --git a/Nexmo.api/Redact.cs b/Nexmo.api/Redact.cs index 1dc79b0f3..35b598834 100644 --- a/Nexmo.api/Redact.cs +++ b/Nexmo.api/Redact.cs @@ -52,7 +52,7 @@ public RedactRequest(string id, string product, string type) /// public static void RedactTransaction(RedactRequest redactRequest, Credentials creds = null) { - ApiRequest.MakePostRequest(ApiRequest.GetBaseUriFor(typeof(Redact), "/v1/redact/transaction"), redactRequest, creds); + ApiRequest.DoPostRequestWithContent(ApiRequest.GetBaseUriFor(typeof(Redact), "/v1/redact/transaction"), redactRequest, creds); } } }