How to send sms using Textlocal API? - c#

I am trying to implement the send message functionality using third party api. API-https://api.txtlocal.com/send/
But when we are testing the implementation, we are facing an issue with error code 3 and giving a message as "invalid user details."
C# code:
string UserId = "1234";
String message = HttpUtility.UrlEncode("OTP");
using (var wb = new WebClient())
{
byte[] response = wb.UploadValues("https://api.txtlocal.com/send/", new NameValueCollection()
{
{"username" , "<TextLocal UserName>"},
{"hash" , "<API has key>"},
{"sender" , "<Unique sender ID>"},
{"numbers" , "<receiver number>"},
{"message" , "Text message"}
});
string result = System.Text.Encoding.UTF8.GetString(response);
//return result;
Error Details:
{
"errors": [{
"code": 3,
"message": "Invalid login details"
}],
"status": "failure"
}
Even though I am passing valid credentials.
Please assist me and let me know in case you require any more details.
Thanks and appreciate your help in advance.

The documentation for the API states that you should pass your parameter values either in the header for POST requests or in the url for GET requests. WebClient.UploadValue does a POST per default, but you don't set the header accordingly. So no credentials are found.
You could try to use the WebClient.UploadValues(name, method, values) overload and specify GET as method.
NameValueCollection values = ...;
byte[] response = wb.UploadValues("https://api.txtlocal.com/send/", "GET", values);

I believe you should either send the API Key OR the username and password.
Remove the username from your request and just leave the API key, sender, numbers and message. All should work OK then.

This is what worked for me:
[HttpGet]
public async Task<JObject> SendOtp(string number)
{
using (var client = _httpClientFactory.CreateClient())
{
client.BaseAddress = new Uri("https://api.textlocal.in/");
client.DefaultRequestHeaders.Add("accept","application/json");
var query = HttpUtility.ParseQueryString(string.Empty);
query["apikey"] = ".....";
query["numbers"] = ".....";
query["message"] = ".....";
var response = await client.GetAsync("send?"+query);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JObject.Parse(content);
}
}

its bit late ...... Try replacing {"hash" , ""} with {"apikey" , ""}

Related

How to filter QnAMaker Question based on Source

I am using QnAMaker REST API in my Bot Framework to query a knowledge base.
It works fine but I would like to filter the 'questions' based on the 'source' as specified on the requestData. Referring to the documentation- https://learn.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/metadata-generateanswer-usage I did not see any option to do that. The documentation states that 'source' is only part of the response answer and not the request.
I tried passing 'source' as metadata to strictFilters.
Dictionary<string, object> requestData = new Dictionary<string, object>
{
["question"] = question,
["top"] = top,
["strictFilters"] = new Dictionary<string, object>
{
["source"] = "test.tsv"
}
};
string requestBody = JsonConvert.SerializeObject(requestData);
kbId = _configuration[qnaKbName];
method = "/knowledgebases/" + kbId + "/generateAnswer/";
var uri = host + method;
var response = await Post(uri, requestBody);
return response;
Request JSON format-
{"question":"flexible working","top":5,"strictFilters":{"source":"test.tsv"}}
It does not work and I get below response-
{
"error": {
"code": "BadArgument",
"message": "Parameter is null"
}
}
Tried creating the Request JSON like this-
{"question":"sabbatical","top":5,"strictFilters":[{"name":"source","value":"test.tsv"}]}
Got below response-
{
"error": {
"code": "Unspecified",
"message": "Something happened. Please retry after some time."
}
}
Is there any option to do that? Please let me know if I can provide more details..
the error BadArgument, Parameter is null comes when input json being passed does not match with QnA API request body. For example if API is expecting {"question":"this is my question"} and we pass {"questionAB":"this is my question"}, this will throw error.

How to get the full url of the current api NOT of the original requestor

Background
I have a local backend API at this address:
http://localhost:54641/orders
And a clientside UI at:
http://localhost:3000/
What I need
The UI does a call to the backend, to list all available orders. This includes information on an attachment for each order. It may or not be there. If there is an attachment, you should get this response from the API, for each order:
{
"orderReference": "123456",
"actions": { "download": "http://localhost:54641/orders/123456/download" }
}
Actions will be {} if there's no attachment available.
However
What I do get, is this:
{
"orderReference": "123456",
"actions": { "download": "http://localhost:3000/orders/123456/download" }
}
Which doesn't exist, ofcourse.
What I have right now
Is this code to build the full url, which is going wrong:
var baseUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority);
var uri = Url.Route("DownloadLabel", new {orderReference });
var fullUrl = $"{baseUrl}{uri}";
As in, it returns the requestor's full url path, not that of the current API.
Question
What can I do to get the API url in the response?
So, it should return like this:
http://localhost:54641/orders/123456/download
I guess you want this,
string fullUrl=HttpContext.Current.Request.Url.ToString();
var wantedUrl= fullUrl.SubString(0,fullUrl.IndexOf("/orders"))+"/orders/"+orderReference+"/download";
Found it, I used httpcontext instead:
var baseUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
var uri = Url.Route("DownloadLabel", new {orderReference });
var fullUrl = $"{baseUrl}{uri}";

Getting "BadRequest" when posting data to SharePoint Online list with HttpClient

I am trying to post data to a list on SharePoint Online with the C# HttpClient. this is my code:
using (var client = new SPHttpClient(webUri, userName, password))
{
var listTitle = "HttpClientList";
var itemPayload = new
{
__metadata = new
{
type = "SP.Data.HttpClientListListItem"
},
Title = "test3",<--column name "Title"
_x0071_cr5 = "value3"<--column name "Value"
};
var endpointUrl = string.Format("{0}/_api/web/lists/getbytitle('{1}')/items", webUri, listTitle);
var data = client.ExecuteJson(endpointUrl, HttpMethod.Post, itemPayload);
Console.WriteLine("Task item '{0}' has been created", data["d"]["Title"]);
Console.ReadLine();
As of right now, I am getting status "400, BadRequest". My guess is that I am missing something or feeding the post request the wrong data.
I have been following this blogpost Blogpost
I can only execute the verb GET. All other verbs gives me "400, BadRequest"
Solved it with varoius solutions.
Added the right ListItem HttpClientListListItem.
created all columns thru the ListSettings panel.
Replaced the client.ExecuteJson() with client.ExecuteJson(endpointUrl, HttpMethod.Post, headers, default(string));.
Thanks for all the help!

C# Web Api Post method with simple type parameters

I'm hoping someone can help. I have been asked to write a test application to consume a Web API.
The method I'm trying to consume, has the following signature:
[Transaction]
[HttpPost]
[Route("api2/Token/")]
public ApiToken Token(Guid companyId, DateTime dateTime, string passCode)
I've written a simple C# console application. However whatever I send to the API returns with a 404 error message and I can't see what my issue is.
My code to consume the API is as follows:
_client.BaseAddress = new Uri("http://localhost:1390");
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var companyId = Guid.Parse("4A55A43A-5D58-4245-AD7C-A72300A69865");
var apiKey = Guid.Parse("FD9AEE25-2ABC-4664-9333-B07D25ECE046");
var dateTime = DateTime.Now;
var sha256 = SHA256.Create();
var bytes = Encoding.UTF8.GetBytes(string.Format("{0}:{1:yyyyMMddHHmmss}:{2}", companyId, dateTime, apiKey));
var hash = sha256.ComputeHash(bytes);
var sb = new StringBuilder();
foreach (var b in hash)
{
sb.Append(b.ToString());
}
try
{
Console.WriteLine("Obtain an authorisation token");
var response = await _client.PostAsJsonAsync("api2/Token/", new { companyId = companyId, dateTime = dateTime, passCode = sb.ToString() });
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
All examples I've googled seem to post an object to a Web API method that accepts an object. Is it possible to post multiple simple types?
I don't think it's possible, from the documentation (https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api)
They've stated that
If the parameter is a "simple" type, Web API tries to get the value
from the URI.
For complex types, Web API tries to read the value from the message body
You can try to use uri parameters instead
var response = await _client.PostAsJsonAsync("api2/Token/{companyId}/{dateTime}/{sb.ToString()}");

Returning data/body along with an HttpReponseCode?

I'm looking at creating a REST WebAPI and want to return "error" messages along with my status codes - as desciption to the end client as to what went wrong.
One of the responses will be a 422 status code - but I can't see how to get the data element into my reponse?
public HttpResponseMessage GetValidate(string number)
{
var response = Request.CreateResponse((HttpStatusCode)422);
response.Content new { error = "something wrong here", item = "number" }; // This is wrong!
return response;
}
There is no definition in the HttpStatusCode for 422 code. Take a look at documentation.
You could use the 500 http status code which is Interval Error:
return Request.CreateResponse(HttpStatusCode.InternalServerError, new {error = "something wrong here", item = "number"});
or 400 Bad Request:
return Request.CreateResponse(HttpStatusCode.BadRequest, new { error = "something wrong here", item = "number" });
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "message"); or other overloads.
There is a draft proposal to the IETF for a standard way of returning error information from an API. The details are here https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem-04
I have a library that supports creating this format on Nuget and a GitHub project.
It works like this..
var problem = new ProblemDocument
{
ProblemType = new Uri("http://example.org"),
Title = "Houston we have a problem",
StatusCode = HttpStatusCode.BadGateway,
ProblemInstance = new Uri("http://foo")
};
problem.Extensions.Add("bar", new JValue("100"));
var response = new HttpResponseMessage(HttpStatusCode.BadGateway)
{
Content = new ProblemContent(problem)
};

Categories

Resources