9

I am new to Google APIs. I want to know how to call Google Dialogflow API in C# to get intent form the input text. But I can't find any example to call Dialogflow using C#.

Please provide some example to call Dialogflow from C#.

kahveci
  • 1,429
  • 9
  • 23
Gowdham
  • 153
  • 2
  • 3
  • 11

2 Answers2

7

If I understand your question correctly you want to call the DialogFlow API from within a C# application (rather than writing fulfillment endpoint(s) that are called from DialogFlow. If that's the case here's a sample for making that call:

using Google.Cloud.Dialogflow.V2;

...
...

var query = new QueryInput
{
    Text = new TextInput
    {
        Text = "Something you want to ask a DF agent",
        LanguageCode = "en-us"
    }
};

var sessionId = "SomeUniqueId";
var agent = "MyAgentName";
var creds = GoogleCredential.FromJson("{ json google credentials file)");
var channel = new Grpc.Core.Channel(SessionsClient.DefaultEndpoint.Host, 
              creds.ToChannelCredentials());

var client = SessionsClient.Create(channel);

var dialogFlow = client.DetectIntent(
    new SessionName(agent, sessionId),
    query
);
channel.ShutdownAsync();

In an earlier version of the DialogFlowAPI I was running into file locking issues when trying to re-deploy a web api project which the channel.ShutDownAsync() seemed to solve. I think this has been fixed in a recent release.

This is the simplest version of a DF request I've used. There is a more complicated version that passes in an input context in this post: Making DialogFlow v2 DetectIntent Calls w/ C# (including input context)

5

(Nitpicking: I assume you know DialogFlow will call your code as specified/registered in the action at DialogFlow? So your code can only respond to DialogFlow, and not call it.)

Short answer/redirect:
Don't use Google.Apis.Dialogflow.v2 (with GoogleCloudDialogflowV2WebhookRequest and GoogleCloudDialogflowV2WebhookResponse) but use Google.Cloud.Dialogflow.v2 (with WebhookRequest and WebhookResponse) - see this eTag-error. I will also mention some other alternatives underneath.

Google.Cloud.Dialogflow.v2

Using Google.Cloud.Dialogflow.v2 NuGet (Edit: FWIW: this code was written for the beta-preview):

    [HttpPost]
    public dynamic PostWithCloudResponse([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 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,
                                   //Ssml = $"<speak>{testAnswer}</speak>"
                                }
                            }
                        }
                    }
            }
        };
        var jsonResponse = dialogflowResponse.ToString();
        return new ContentResult { Content = jsonResponse, ContentType = "application/json" }; ;
    }

Edit: It turns out that the model binding may not bind all properties from the 'ProtoBuf-json' correctly (e.g. WebhookRequest.outputContexts[N].parameters), so one should probably use the Google.Protobuf.JsonParser (e.g. see this documentation).

This parser may trip over unknown fields, so one probably also wants to ignore that. So now I use this code (I may one day make the generic method more generic and thus useful, by making HttpContext.Request.InputStream a parameter):

    public ActionResult PostWithCloudResponse()
    {
       var dialogflowRequest = ParseProtobufRequest<WebhookRequest>();
       ...
        var jsonResponse = dialogflowResponse.ToString();
        return new ContentResult { Content = jsonResponse, ContentType = "application/json" }; ;
    }

    private T ParseProtobufRequest<T>() where T : Google.Protobuf.IMessage, new()
    {
        // parse ProtoBuf (not 'normal' json) with unknown fields, else it may not bind ProtoBuf correctly
        // https://github.com/googleapis/google-cloud-dotnet/issues/2425 "ask the Protobuf code to parse the result"
        string requestBody;
        using (var reader = new StreamReader(HttpContext.Request.InputStream))
        {
            requestBody = reader.ReadToEnd();
        }
        var parser = new Google.Protobuf.JsonParser(JsonParser.Settings.Default.WithIgnoreUnknownFields(true));
        var typedRequest = parser.Parse<T>(requestBody);
        return typedRequest;
    }

BTW: This 'ProtoBuf-json' is also the reason to use WebhookResponse.ToString() which in turn uses Google.Protobuf.JsonFormatter.ToDiagnosticString.

Microsoft's BotBuilder

Microsoft's BotBuilder packages and Visual Studio template. I havent't used it yet, but expect approximately the same code?

Hand written proprietary code

A simple example of incoming request code (called an NLU-Response by Google) is provided by Madoka Chiyoda (Chomado) at Github. The incoming call is simply parsed to her DialogFlowResponseModel:

    public static async Task<HttpResponseMessage> Run([...]HttpRequestMessage req, [...]CloudBlockBlob mp3Out, TraceWriter log)
        ...
        var data = await req.Content.ReadAsAsync<Models.DialogFlowResponseModel>();

Gactions

If you plan to work without DialogFlow later on, please note that the interface for Gactions differs significantly from the interface with DialogFlow. The json-parameters and return-values have some overlap, but nothing gaining you any programming time (probably loosing some time by starting 'over').

However, starting with DialogFlow may gain you some quick dialog-experience (e.g. question & answer design/prototyping). And the DialogFlow-API does have a NuGet package, where the Gactions-interface does not have a NuGet-package just yet.

Yahoo Serious
  • 3,728
  • 1
  • 33
  • 37
  • No such package available anymore – Sana Ahmed Feb 11 '19 at 07:18
  • 1
    @Sana, Google.Cloud.Dialogflow.v2 1.0.0-beta02 is still available, and the link is also still valid. As implied by "Beta" and "presently in preview", you can see it if you also check the NuGet-prereleases. So I will consider your comment and downvote a question, and the answer is: you can see prereleases in the NuGet-GUI (VS2017) if you check the checkbox to "Include prereleases". In the NuGet Command-Line Interface you can add a `-prerelease` switch for the same purpose. – Yahoo Serious Feb 11 '19 at 11:27
  • 1
    @Sana, FWIW, I just happened to notice [Google.Cloud.Dialogflow.v2](https://www.nuget.org/packages/Google.Cloud.Dialogflow.v2/) is out of beta, and 1.1.0 is available. (I haven't used it in a while though.) – Yahoo Serious Oct 11 '19 at 07:37