Dialogflow Webhook Response c# gives error on invoke - azure

I'm trying to create a webhook for Dialogflow in C# (on Azure). Everytime I see the same example but my DialogFlows keeps geting an error with this response"
Here's what I did:
Created a new ASP.Net Web Project (WebAPI)
installed NuGet Google.Cloud.DialogFlow V2 (v1.0.0.beta02)
updated System.Net.Http to 4.3.3
Created a new controller
[System.Web.Http.HttpPost]
public dynamic DialogAction([FromBody] WebhookRequest dialogflowRequest)
{
var intentName = dialogflowRequest.QueryResult.Intent.DisplayName;
var actualQuestion = dialogflowRequest.QueryResult.QueryText;
var testAnswer = $"Dialogflow Request for intent {intentName} and question {actualQuestion}";
var parameters = dialogflowRequest.QueryResult.Parameters;
var dialogflowResponse = new WebhookResponse
{
FulfillmentText = testAnswer,
FulfillmentMessages =
{ new Intent.Types.Message
{ SimpleResponses = new Intent.Types.Message.Types.SimpleResponses
{ SimpleResponses_ =
{ new Intent.Types.Message.Types.SimpleResponse
{
DisplayText = testAnswer,
TextToSpeech = testAnswer,
}
}
}
}
}
};
var jsonResponse = dialogflowResponse.ToString();
return new ContentResult
{
Content = jsonResponse,
ContentType = "application/json"
};
Published the app to Azure so there's a webhook URl.
Now, when I test it in dialogflow, the response is:
"Webhook call failed. Error: Failed to parse webhook JSON response: Cannot find field: Content in message google.cloud.dialogflow.v2.WebhookResponse."
Which I do not understand.....what am I missing here?
(here's the screenshot of the response:)

The solution to this problem is to return JsonResult instead of the ContentResult.
[System.Web.Http.HttpPost]
public JsonResult DialogAction([FromBody] WebhookRequest dialogflowRequest)
{
var intentName = dialogflowRequest.QueryResult.Intent.DisplayName;
var actualQuestion = dialogflowRequest.QueryResult.QueryText;
var testAnswer = $"Dialogflow Request for intent {intentName} and question {actualQuestion}";
var parameters = dialogflowRequest.QueryResult.Parameters;
var dialogflowResponse = new WebhookResponse
{
FulfillmentText = testAnswer,
FulfillmentMessages =
{ new Intent.Types.Message
{ SimpleResponses = new Intent.Types.Message.Types.SimpleResponses
{ SimpleResponses_ =
{ new Intent.Types.Message.Types.SimpleResponse
{
DisplayText = testAnswer,
TextToSpeech = testAnswer,
}
}
}
}
}
};
var jsonResponse = dialogflowResponse.ToString();
return Json(jsonResponse);

Related

How can I capture audio in Blazor Server?

My app:
https://vcat.azurewebsites.net/voice
uses azure voice to text service on a blazor server side. It works fine locally, but when published at azure it does not work.
What is wrong?
As I have understood it is not only me who has this problem. This is another one:
CognitiveServices.Speech Blazor Server not working when Published to Azure
here is the code:
private async Task record()
{
try
{
_isRecording = true;
_question = string.Empty;
_answer = string.Empty;
using var audioConfig = AudioConfig.FromDefaultMicrophoneInput();
using var speechRecognizer = new SpeechRecognizer(_speechConfig, audioConfig);
var speechRecognitionResult = await speechRecognizer.RecognizeOnceAsync();
_question = speechRecognitionResult.Text;
_isRecording = false;
if (string.IsNullOrEmpty(_question))
{
_question = "Please try again!";
}
else
{
//_isThinking = true;
await answer();
//_isThinking = false;
await speak();
}
}
catch (Exception ex)
{
Error?.ProcessError(ex);
}
}

Receiving BrokeredMessage from ServiceBus from a nodejs server

I am reading messages from an existing Azure ServiceBus from a new nodejs Server.
This is the way the messages are being sent to the ServiceBus from a .NET server:
var topicClient = TopicClient.CreateFromConnectionString(serviceBusConnectionString, routingKey);
var brokeredMessage = new BrokeredMessage(message.ToJson());
topicClient.Send(brokeredMessage);
Where topicClient is Microsoft.ServiceBus.Messaging.TopicClient
I am using the following method to read the messages on a nodejs server using azure-sb package:
sbClient = ServiceBusClient.createFromConnectionString(connectionString)
subscriptionClient = this.sbClient.createSubscriptionClient(topicName, subscriptionName);
receiver = this.subscriptionClient.createReceiver(ReceiveMode.receiveAndDelete);
messages = await this.receiver.receiveMessages(10,10);
console.log(messages.map(message => { message.body }));
message.body is a buffer and when I do message.body.toString('utf-8') I get something like:
#string3http://schemas.microsoft.com/2003/10/Serialization/��{VALID JSON}
I am interested of course in the valid JSON in between.
In the .net servers we simply do brokeredMessage.GetBody() and we get the object, so is there an easy way on nodejs to do the same?
According to my test, if we use the standard library Microsoft.Azure.ServiceBus to send messages in .Net application, it will directly JSON parse the message in node application
For example
This is my C# code to send a message:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = new TopicClient(connectionString, "");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello!!! {DateTime.Now}" });
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.SendAsync(serviceBusMessage).Wait();
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
This is my Node.js code to receive a message:
const { ServiceBusClient, ReceiveMode } = require("#azure/service-bus");
// Define connection string and related Service Bus entity names here
const connectionString =
"Endpoint=sb://";
const topicName = "***";
const subscriptionName = "***";
async function main() {
const sbClient = ServiceBusClient.createFromConnectionString(
connectionString,
);
const subscriptionClient = sbClient.createSubscriptionClient(
topicName,
subscriptionName,
);
const receiver = subscriptionClient.createReceiver(ReceiveMode.receiveAndDelete);
try {
const messages = await receiver.receiveMessages(1);
console.log("Received messages:");
console.log(messages.map((message) => message.body));
await subscriptionClient.close();
} finally {
await sbClient.close();
}
}
main().catch((err) => {
console.log("Error occurred: ", err);
});
Besides, if you still use the library WindowsAzure.ServiceBus, we need to use BrokeredMessage(Stream messageBodyStream, bool ownsStream) to initialize an object.
Because we use BrokeredMessage(platload) to initialize, it will use DataContractSerializer with a binary XmlDictionaryWriter to initialize an object. So, the payload is being serialized using DataContractSerializer with a binary XmlDictionaryWriter and this is the cause that explains why the body of the message has in its start the type indication #string3http://schemas.microsoft.com/2003/10/Serialization/.
For example
This is my C# code to send a message:
var client =TopicClient.CreateFromConnectionString(connectionString, "test");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello BrokeredMessage!!! {DateTime.Now}" });
using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(payload))) {
var serviceBusMessage = new BrokeredMessage(stream,true);
await client.SendAsync(serviceBusMessage);
}
I use the same code to receive
For more details, please refer to here.

How do I use the rabbitmq in my .net core web

As the title suggests,Examples on the official website are console project but is it really impossible to apply to asp.net core web?
My web project as a consumer or producer but does not output received information,But the rabbitmq page console displays the queue messages sent,so What are consumers or producer in the actual production environment?windows server?console?
this is my api code:
[HttpGet]
public ActionResult sendMgs()
{
string message = string.Empty;
//var uri = new Uri("amqp://192.168.150.129:5672");
var factory = new ConnectionFactory()
{
UserName = "admin",
Password = "admin",
Port=5672,
HostName= "192.168.150.129",
RequestedHeartbeat = 0,
VirtualHost= "/vhost_mmr"
//Endpoint = new AmqpTcpEndpoint(uri)
};
using (var connection=factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue:"hello",
durable:false,
exclusive:false,
autoDelete:false,
arguments:null);
message = "Hello World";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "",
routingKey:"hello",
basicProperties:null,
body:body);
}
}
return Json(new {message = message });
}
and this my mvc web code:
public IActionResult MqTest()
{
System.Diagnostics.Debug.Write("test begin:");
GetQueueMsg();
return View();
}
public void GetQueueMsg()
{
var factory = new ConnectionFactory()
{
UserName = "admin",
Password = "admin",
Port = 5672,
HostName = "192.168.150.129",
RequestedHeartbeat = 0,
VirtualHost = "/vhost_mmr"
};
using (var connection = factory.CreateConnection())
{
using (var channel =connection.CreateModel())
{
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var msg = Encoding.UTF8.GetString(body);
ViewBag.msg = msg;
System.Diagnostics.Debug.Write("test:" + msg);
};
var ret = channel.BasicConsume(queue: "hello",
autoAck: true,
consumer: consumer);
}
}
}

Unauthorized Http Response

I am using an Azure Authentication in my Xamarin.Form project, the token received is used for making API calls for authentication purpose.
After some time after the keeping the app in background, again I try to make the API calls it returns "unauthorised".
The token expiration time is set to 30 min. But unauthorised error is not consistent some time it happens as soon as keep the app in background and some time it works fine.
Has anyone faced the same issue.
public async Task<Response> AuthenticatedGet(string uri, string accessToken, string content = null)
{
Uri restUri = new Uri(uri, UriKind.RelativeOrAbsolute);
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(60);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, restUri.ToString());
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization",
string.Format("Bearer {0}", accessToken));
var result = await client.SendAsync(request);
//HttpClient client = new HttpClient();
//client.Timeout = TimeSpan.FromSeconds(60);
//var result = await client.SendAsync(request);
Response sr = new Response();
if (result.IsSuccessStatusCode)
{
string responseString = await result.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(responseString))
{
sr.ResponseData = responseString;
sr.IsSuccess = true;
sr.StatusCode = (int)result.StatusCode;
}
}
else if (result.StatusCode == HttpStatusCode.NotFound)
{
sr.ResponseData = $"Service not found at the specifed uri {uri}";
sr.IsSuccess = false;
sr.StatusCode = (int)result.StatusCode;
}
else
{
//var responseString = await result.Content.ReadAsStringAsync();
//JObject jObject = JObject.Parse(responseString);
//var messageProperty = jObject.Property("Message");
//if (messageProperty != null && result.StatusCode == HttpStatusCode.Unauthorized)
//{
// var message = messageProperty.Value?.ToString();
// sr.Message = !string.IsNullOrEmpty(message) ? message : result.ReasonPhrase;
// LogoutUnauthorisedUser?.Invoke(message);
// throw new UnauthorizedAccessException(message);
//}
//sr.Message = result.ReasonPhrase;
//sr.IsSuccess = false;
//sr.StatusCode = (int)result.StatusCode;
//TODO: Handle Unauthorized user
}
return sr;
}
public async Task<ObservableCollection<NIODetails>> GetABCServiceAsync()
{
var uri = string.Format(_hostConfiguration.ABCHostName + _hostConfiguration.ABC, Configuration.ABC);
var resonse = await _httpService.AuthenticatedGet(uri, Constant.ADToken, null);
if (resonse.IsSuccess)
{
var list = JsonConvert.DeserializeObject<ObservableCollection<ABCDetails>>(resonse.ResponseData);
return list;
}
else
{
return null;
}
}

Win Phone 8 / Asp .Net Web API Image Upload

The following code responsible for uploading images:
[HttpPost]
public async Task<HttpResponseMessage> Upload()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var streamProvider = new MultipartMemoryStreamProvider();
Cloudinary cloudinary = new Cloudinary(ConfigurationManager.AppSettings.Get("CLOUDINARY_URL"));
return await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
throw new HttpResponseException(HttpStatusCode.InternalServerError);
var content = streamProvider.Contents.FirstOrDefault().ReadAsStreamAsync();
ImageUploadParams uploadParams = new ImageUploadParams()
{
File = new CloudinaryDotNet.Actions.FileDescription(Guid.NewGuid().ToString(), content.Result)
};
ImageUploadResult uploadResult = cloudinary.Upload(uploadParams);
string url = cloudinary.Api.UrlImgUp.BuildUrl(String.Format("{0}.{1}", uploadResult.PublicId, uploadResult.Format));
return Request.CreateResponse<MediaModel>(HttpStatusCode.Created, new MediaModel { URL = url });
});
}
It works via jquery post request. However, in win phone 8 application, the following code does not seem to make a request to the api:
public async Task<string> UploadImage(byte[] image)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
var imageContent = new ByteArrayContent(image);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
content.Add(imageContent, "image", string.Format("{0}.jpg", Guid.NewGuid().ToString()));
return await client.PostAsync(baseURL + "image/Upload", content).Result.Content.ReadAsStringAsync().ContinueWith(t =>
{
return t.Result;
});
}
What is the problem here? I hope someone could show me the proper use of httpclient.
It is a classic Turkish İ problem. Changing "image/Upload" to "Image/Upload" solved the problem.

Resources