We have started experimenting with the Microsoft.CognitiveServices.Speech nuget package (https://learn.microsoft.com/en-gb/azure/cognitive-services/speech-service/how-to-recognize-intents-from-speech-csharp). This is great as it allows a language model to be built up and you can specifically include the intents you want to be matched:
// Creates a Language Understanding model using the app id, and adds specific intents from your model
var model = LanguageUnderstandingModel.FromAppId("YourLanguageUnderstandingAppId");
recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName1", "id1");
recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName2", "id2");
recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName3", "any-IntentId-here");
However, we are building an API and will be passing text over and this will call Luis using the API endpoint, this is very basic like so:
using (var client = new HttpClient())
{
var queryString = HttpUtility.ParseQueryString(String.Empty);
// The request header contains your subscription key
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", _cognitiveSettings.SubscriptionKey);
// The "q" parameter contains the utterance to send to LUIS
queryString["q"] = query;
// These optional request parameters are set to their default values
queryString["staging"] = _cognitiveSettings.IsProduction ? bool.FalseString : bool.TrueString;
queryString["timezoneOffset"] = "0";
queryString["verbose"] = "true";
queryString["spellCheck"] = "false";
var endpointUri = $"https://westeurope.api.cognitive.microsoft.com/luis/v2.0/apps/{_luisAppId}?{queryString}";
var response = await client.GetAsync(endpointUri);
var responseJson = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<IntentResponseModel>(responseJson);
}
Is there a way to control the intents we would want to be returned for a particular text string? We can set verbose to true so it returns all intents with a match rating but we would prefer to be able to specify a subset of intents depending on the state and just try to match those. It seems you can do this with the SDK using audio, can this be done using text (is there a text SDK?).
Also, is there a way for the entitites that are returned in the JSON to be matched to the intent which populated them, it looks like there is no link between the intents and the entities.
Unfortunately, no, there is no way to control the intents that are returned. In the app, you will need to filter on the intents returned to limit what is matched for a particular text string.
Related
I figured I'd upgrade my LuisRecognizer to use LuisRecognizerOptionsV3. However I can't seem to set prediction options the way I like - how do I set the timezone? The v3 prediction options lack this field.
In my bot I am currently doing:
var predictionOptions = new LuisPredictionOptions();
predictionOptions.TimezoneOffset = turnContext.Activity.LocalTimestamp.Value.Offset.TotalMinutes;
and I can't figure out the equivalent in v3's version of the data structure.
The timezoneOffset parameter was mostly provided as a way to determine what day it is for the user in case they say something like "today" or "tomorrow." It also helps when the user enters a relative time like "in three hours." When using the timezoneOffset parameter, the returned entity is in the provided timezone rather than universal time.
In LUIS v3, instead of providing an offset you provide a DateTime reference and LUIS uses that to process relative time. You can see that documented here. Note that the datetimeReference property is only available in POST requests and not GET requests because you provide it in the request body and not as a query parameter.
Also note that the datetimeReference property is not currently available in the Bot Builder SDK. You can write your own code to access the LUIS API directly with an HttpClient, but if you'd still like a prebuilt SDK to handle things then you can use this NuGet package: Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime 3.0.0
Here's an example of how to use it:
var appId = new Guid("<LUIS APP ID>");
var client = new LUISRuntimeClient(new ApiKeyServiceClientCredentials("<SERVICE KEY>"));
client.Endpoint = "https://westus2.api.cognitive.microsoft.com";
var options = new PredictionRequestOptions(activity.LocalTimestamp.Value.DateTime);
var request = new PredictionRequest("Book a flight in three hours", options);
var response = await client.Prediction.GetSlotPredictionAsync(appId, "PRODUCTION", request);
Console.WriteLine(JsonConvert.SerializeObject(response.Prediction.Entities, Formatting.Indented));
I am using simple.odata.client in my application. The problem is the client is retrieving the whole structure at the first call which is too large (more than 30MB) and so I am getting a timeout? Is there any parameter/setting to prevent the client to retrieve the whole structure.
Is there any other package which can help me with my application instead of simple.odata.client
The Simple.OData client will retrieve the metadata from the service once for the lifecycle of the object.
You can also initialize the client with a metadata xml string which will prevent the client from making the call.
Below is an except of my code where MetaDataDocumentAsString is the XML metadata as a string. This code also sets the OAuth2 bearer token in the httpclient instance used to create the client.
HttpClient.BaseAddress = new Uri(AppSettings.Dynamics365.WebAPI_ServiceRootURL);
//Use the httpClient we setup with the Bearer token header
ODataClientSettings odataSettings = new ODataClientSettings(HttpClient, new Uri(WebAPI_VersionRelativeURL, UriKind.Relative))
{
//Setting the MetadataDocument property prevent Simple.OData from making the expensive call to get the metadata
MetadataDocument = MetaDataDocumentAsString
};
_ODataClient = new ODataClient(odataSettings);
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GetToken().Access_token);}
See the github issue for more details
https://github.com/simple-odata-client/Simple.OData.Client/issues/314
I use OData Top and Skip in my client request call. For example;
var accessToken = await _psUtils.GetUspsReferenceApiAccessToken(token);
var client = new ODataClient(SetODataToken(_psUtils.GetBaseUspsReferenceApiUrl(), accessToken));
var annotations = new ODataFeedAnnotations();
addressComplianceCodes = await client.For<AddressComplianceCode>()
.Filter(x => x.Description.Contains(searchValue) || x.Code.Contains(searchValue))
.Top(pageSize).Skip(skip)
.OrderByDescending(sortColumn)
.FindEntriesAsync(annotations, token);
and in my client code, I have a pager that tracks the values I pass to top and skip so I can step through the pages. The Top is the total number of records per page. The annotations object returns a Count property you can use to show the total number of records. I.e.
annotations.Count
Here is a link to the OData.org tutorial that talks about top and skip.
https://github.com/simple-odata-client/Simple.OData.Client/wiki/Results-projection,-paging-and-ordering that talks about paging.
I am using Google API to get information about an authenticated user. I can get the basic profile information, such as the ID and the full name. From the profile information, I can get the URL to the picture:
var plusMeUri = new Uri($"https://www.googleapis.com/plus/v1/people/me?key=<APP-ID>&access_token=<ACCESS-TOKEN>");
string userResponse = await HttpClient.GetStringAsync(plusMeUri);
JObject userObject = JObject.Parse(userResponse);
...
var imageObject = userObject.GetValue("image") as JObject;
var pictureUrl = imageObject.GetValue("url").Value<string>();
var pictureUri = new Uri(pictureUrl);
string uri = $"{pictureUri.Scheme}://{pictureUri.Host}{pictureUri.AbsolutePath}";
var pictureRequest = new HttpRequestMessage(HttpMethod.Get, uri);
pictureRequest.Headers.IfModifiedSince = <previous-timestamp>;
HttpResponseMessage pictureResponse = await HttpClient.SendAsync(pictureRequest);
if (pictureResponse.StatusCode == HttpStatusCode.NotModified)
// No need to handle anything else
return;
Question
I do not want to download the user's picture if it has not changed. This is why I am using the IfModifiedSince property. It does work with Facebook's API but it does not seem to work with Google's. How can I make it work?
From the information given, it seems like what you're trying to do is determine whether the image you're downloading/about to download is the same image as you've downloaded before. After looking at the Google+ API docs, it looks like the header you've been using isn't officially (at least not obviously) supported by their APIs.
But this is not the only way we can determine whether the image has changed or not (in fact, date last modified isn't necessarily the best way to do this anyway). Alternative methods include:
1) diffing the two images
2) checking the url (if we can assume different resources have different urls)
1 is likely the most accurate but also likely the least efficient, so I'll leave that to you to solve if you decide to go that route. I think the most promising is #2. I went ahead and played around with the API a little bit and it looks like the image.url field changes when you update your profile picture.
For example, here are my last two Google+ profile picture URLs:
https://lh4.googleusercontent.com/-oaUVPGFNkV8/AAAAAAAAAAI/AAAAAAAAAqs/KM7H8ZIFuxk/photo.jpg?sz=50
https://lh4.googleusercontent.com/-oaUVPGFNkV8/AAAAAAAAAAI/AAAAAAAAl24/yHU99opjgN4/photo.jpg?sz=50
As such, instead of waiting for the response from the server and checking its header to decide whether the image has been updated or not, you may be able to short-circuit the entire HTTP request by simply checking whether the last image you pulled down was from the same url or not. If it was from the same URL, it's likely you've already acquired that image otherwise you may not have it so should incur the cost of downloading anyway.
In this case, your code would read something like:
var imageObject = userObject.GetValue("image") as JObject;
var pictureUrl = imageObject.GetValue("url").Value<string>();
if(pictureUrl != <previous-picture-url>)
{
// insert get new picture logic here...
}
I'm trying to post a comment to a status on Facebook. Basically what I'm doing is something like this:
var parameters = new Dictionary<string, object>(); parameters["message"] = "hello";
fb.Post("/"+id+"/comments", parameters);
Where fb is a FacebookClient object and id is the id of the status.
Unfortunately this doesn't post the comment on recent status. For instance, if I type https://graph.facebook.com/"id"/comments in a web-browser it returns no data if the status is recent, but if the status is old (more than 1 month) it returns the information about the comments on that status.
Is there a way to comment on a status, picture, etc. using this API with C#?
the fb.Post command seems to be correct. I use the same (in vb.net) and it works like expected...
string AccessToken = "...." // User's access token
FacebookClient fb = new FacebookClient(AccessToken);
dynamic parameters = new ExpandoObject();
parameters.message = txtNewComment.Text.Trim();
dynamic result=fb.Post(HiddenMyPostID.Value+"/comments", parameters);
Above is code that i use for posting new comment on any post of facebook. And It's working.
I was having the same issue so I tried few things & this worked for me
var token = "[your access token]";
var fb = new Facebook.FacebookClient(token);
var postId = "173213306032925_74xxxxxxxxxxxxx"; //replace this with your big id which comprises of [userid]_[postid]
var parameters = new Dictionary<string, object>();
parameters.Add("message", "test message");
Console.WriteLine(fb.Post(id+"/comments", parameters).ToString()); // should give new comment's id
Console.WriteLine(fb.Get(postId +"/comments").ToString()); //should give you details
//for deleting
fb.Delete(newly_created_comment_id); //should return true or false
For this, you need to learn about how can you use Graph API and you also need to learn about some parameters like
height should be in integers which indicated the height of the pixels.
redirection should be in boolean and its default value should be true.
width is in integers which indicates the width of pictures in pixels.
There are many more but it can be understood by the standard programmatic interfaces.
When you use the programming language which you prefer should be based on HTTPS requests.
The version of APIs describes that all the requests are firstly in encrypted form and then they are sent via HTTPs requests.
To do so, you need to send make a registration for your application even users are not allowed to log in.
I hope it would work for you. But apart from it, you need to do more researches.
http://wholestatus.com/
I have a requirement that we need to make a telephone call using ASP.NET application.
Our ASP.NET application is used in call center. Currently, they make a call to customer manually. Now, the call should go from our application by clicking the phone number link and starts recording the conversation between the agent (application user) and customer.
What all would be the hardware requirements for the above scenario?
How can we implement telephone calling in asp.net application and what are the required components to implement the same?
Nexmo offers a range of cloud communication APIs including Voice API that allows you to fulfil this requirement.
All you need is to install the Nuget package:
Install-Package Nexmo.Csharp.Client
Then use the Call class:
Call.Do(new Call.CallCommand
{
to = new[]
{
new Call.Endpoint
{
type = "phone",
number = NEXMO_TO_NUMBER
}
from = new Call.Endpoint
{
type = "phone",
number = NEXMO_FROM_NUMBER
},
answer_url = new[]
{
NEXMO_CALL_ANSWER_URL
}
});
Here's a detailed post on how to make a phone call with Nexmo Voice API and ASP.Net
If you want to use phone line you should use Computer-telephony boards, for example Dialogic: http://www.dialogic.com/products/ip_enabled/ip_boards.htm They should have API, so you will be able to use it from your application.
In addition to Asterisk, you might also consider Twilio, a web based telephony service that provides you a rest based api for making and receiving phone calls. See http://www.twilio.com/docs/howto/ for info.
You Can Use Third party API To Make a Call Using Asp.net Code.First You Need To Register. Here's a detailed post on
How To Make a Call Using Asp.net Code
protected void btnCall_click(object sender, EventArgs e)
{
// Call porcessing happens here.
// Use your account SID and authentication token instead of
// the placeholders shown here.
var accountSID = "C0d09f4042d1ff4acb55329cf8e5efb";
var authToken = "05b278c6f3538d3a35f13b25c73dff";
// Instantiate an instance of the Twilio client.
TwilioClient.Init(accountSID, authToken);
// Retrieve the account, used later to retrieve the
var account = AccountResource.Fetch(accountSID);
// this.varDisplay.Items.Clear();
// Retrieve the values entered by the user.
var To =new PhoneNumber(txtMobileNumber.Text);
//twlio=14155992671
var from = new PhoneNumber("+918098641075");
var myMessage = this.txtMessage.Text;
// Create a URL using the Twilio message and the user-entered
// text. You must replace spaces in the user's text with '%20'
// to make the text suitable for a URL.
var url = #"http://twimlets.com/message?Message%5B0%5D={myMessage.Replace()}";
var twimlUri = new Uri(url);
// Display the endpoint, API version, and the URL for the message.
this.varDisplay.Items.Add(#"Using Twilio endpoint { }");
this.varDisplay.Items.Add(#"Twilioclient API Version is {apiVersion}");
this.varDisplay.Items.Add(#"The URL is {url}");
// Place the call.
var Call=CallResource.Create(To,from,url:twimlUri);
// var call = CallResource.create(to, from, url: twimlUri);
this.varDisplay.Items.Add("Call status: " + Call.Status);
}