如何在 C# 中调用 google.apis.dialogflow.v2

Posted

技术标签:

【中文标题】如何在 C# 中调用 google.apis.dialogflow.v2【英文标题】:How to call google.apis.dialogflow.v2 in C# 【发布时间】:2018-11-11 03:59:28 【问题描述】:

我是 Google API 的新手。我想知道如何在 C# 中调用 Google Dialogflow API 来获取输入文本的意图。但我找不到任何使用 C# 调用 Dialogflow 的示例。

请提供一些从 C# 调用 Dialogflow 的示例。

【问题讨论】:

你可以通过这些链接github.com/GoogleCloudPlatform/google-cloud-dotnet和github.com/dialogflow/dialogflow-dotnet-client 如果你得到这个工作,你介意分享一些代码吗? 【参考方案1】:

吹毛求疵:我假设您知道 DialogFlow 会按照 DialogFlow 操作中指定/注册的方式调用您的代码?所以您的代码只能响应 DialogFlow,而不能调用它。

简答/重定向: 不要使用 Google.Apis.Dialogflow.v2(使用 GoogleCloudDialogflowV2WebhookRequestGoogleCloudDialogflowV2WebhookResponse),而是使用 Google.Cloud.Dialogflow.v2(使用 WebhookRequestWebhookResponse) - 见eTag-error。我还将在下面提到其他一些替代方案。

Google.Cloud.Dialogflow.v2

使用Google.Cloud.Dialogflow.v2 NuGet(编辑:FWIW:此代码是为 beta 预览版编写的):

    [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" ; ;
    

编辑:模型绑定可能无法正确绑定“ProtoBuf-json”中的所有属性(例如WebhookRequest.outputContexts[N].parameters), 所以应该使用Google.Protobuf.JsonParser(例如参见this documentation)。

这个解析器可能会遇到未知字段,所以人们可能也想忽略它。所以现在我使用这段代码(我可能有一天会通过将HttpContext.Request.InputStream 设为参数来使泛型方法更通用,从而更有用):

    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;
    

顺便说一句:这个“ProtoBuf-json”也是使用WebhookResponse.ToString() 的原因,而Google.Protobuf.JsonFormatter.ToDiagnosticString 又使用了Google.Protobuf.JsonFormatter.ToDiagnosticString

微软的 BotBuilder

Microsoft 的 BotBuilder 包和Visual Studio template。 我还没有使用它,但期望大致相同的代码?

手写专有代码

Madoka Chiyoda (Chomado) 在Github 提供了一个传入请求代码的简单示例(Google 称为 NLU 响应)。来电只是简单的解析给她DialogFlowResponseModel:

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

Gactions

如果您打算以后不使用DialogFlow,请注意Gactions 的界面与DialogFlow 的界面有很大不同。 json-parameters 和 return-values 有一些重叠,但没有任何东西可以让你获得任何编程时间(可能会因为开始'over'而失去一些时间)。

但是,从 DialogFlow 开始可能会让您获得一些快速的对话体验(例如问答设计/原型制作)。 DialogFlow-API 确实有一个 NuGet 包,而 Gactions 接口没有 NuGet 包just yet。

【讨论】:

没有这样的包可用了 @Sana,Google.Cloud.Dialogflow.v2 1.0.0-beta02 仍然可用,链接也仍然有效。正如“Beta”和“目前处于预览状态”所暗示的那样,如果您还检查 NuGet 预发行版,您就可以看到它。因此,我会考虑您的评论并否决一个问题,答案是:如果您选中“包括预发布”复选框,您可以在 NuGet-GUI (VS2017) 中看到预发布。在 NuGet 命令行界面中,您可以添加 -prerelease 开关以实现相同目的。 @Sana,FWIW,我只是碰巧注意到Google.Cloud.Dialogflow.v2 已经过测试版,1.1.0 可用。 (虽然我已经有一段时间没有使用它了。)【参考方案2】:

如果我正确理解您的问题,您想从 C# 应用程序中调用 DialogFlow API(而不是编写从 DialogFlow 调用的实现端点。如果是这种情况,这里是进行该调用的示例:

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();

在早期版本的 DialogFlowAPI 中,我在尝试重新部署 channel.ShutDownAsync() 似乎可以解决的 Web api 项目时遇到了文件锁定问题。我认为这已在最近的版本中得到修复。

这是我用过的最简单的 DF 请求版本。在这篇文章中有一个更复杂的版本在输入上下文中传递: Making DialogFlow v2 DetectIntent Calls w/ C# (including input context)

【讨论】:

以上是关于如何在 C# 中调用 google.apis.dialogflow.v2的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中获取调用方法 [重复]

如何在 C# 中调用跨域 API

如何在 c# 中调用 python 脚本?

如何在 c++ 中调用 c# 方法?

如何使用 SMO 在存储过程中调用 c# 函数?

如何在 C# 中调用自定义 url 协议?