Authenticating Request with Google.Apis.DialogFlow

2019-09-20 15:23发布

I have upgraded my C# DialogFlow client from Google.Cloud.DialogFlow.V2 to Google.Apis.DialogFlow.v2 However I keep getting a 401 error when connecting to DialogFlow.

Heres is my code:

Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", cloudKeyFile);
var response = new 
  Google.Apis.Dialogflow.v2.DialogflowService().Projects.Agent.Sessions.DetectIntent(
            new Google.Apis.Dialogflow.v2.Data.GoogleCloudDialogflowV2DetectIntentRequest
            {
                QueryInput = new Google.Apis.Dialogflow.v2.Data.GoogleCloudDialogflowV2QueryInput
                {
                    Text = new Google.Apis.Dialogflow.v2.Data.GoogleCloudDialogflowV2TextInput
                    {
                        Text = queryText,
                        LanguageCode = languageCode
                    }
                }
            },
            $"projects/{ProjectId}/agent/sessions/{sessionId}")
            .Execute();

Error:

Google.Apis.Requests.RequestError Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. [401]

NOTE: cloudKeyFile is a valid auth2 key file that worked with the previous framework. (Google.Cloud.DialogFlow.V2)

Can someone guide me on what to do?

Thnx in advance

4条回答
放荡不羁爱自由
2楼-- · 2019-09-20 16:00

Other answers were useful to me but didn't work, maybe because the API changed. This is what worked for me:

            var dialogFlowConfigurationBytes = BlobManager.GetBytesByBlobUrl("your json path"); // get bytes from file using BlobManager class (utility class created by me, you could get the stream directly)

            var credentials = GoogleCredential.FromStream(new MemoryStream(dialogFlowConfigurationBytes));
            Channel channel = new Channel(IntentsClient.DefaultEndpoint.Host, IntentsClient.DefaultEndpoint.Port, credentials.ToChannelCredentials());
            var client = SessionsClient.Create(channel);

            foreach (var text in texts)
            {
                var response = client.DetectIntent(
                    session: new SessionName(dialogFlowConfiguration.ProjectId, sessionId),
                    queryInput: new QueryInput()
                    {
                        Text = new TextInput()
                        {
                            Text = text,
                            LanguageCode = languageCode
                        }
                    }
                );
            }
查看更多
Juvenile、少年°
3楼-- · 2019-09-20 16:03

Following on from Godsayer's answer I managed to get this working with a few lines of code when using a c# webclient.

First, make sure you have created a Google Service Account and granted it the relevant permissions to DialogFlow. I needed to get at Intents, Utterances etc so granted it DialogFlow API Admin.

Then, within the service account I created a new Json Key and downloaded it, storing it in a local dir in my app.

In visual studio I then installed the Google.Apis.Dialogflow.v2 nuget package.

In my console app I added the following code lines and I'm in!

using Google.Apis.Auth.OAuth2;
using Google.Apis.Dialogflow.v2;

var credentials = GoogleCredential.FromFile(@"C:\pathtofile\abc123.json");
var scopedCredentials = credentials.CreateScoped(DialogflowService.Scope.CloudPlatform);
    _oAuthToken = scopedCredentials.UnderlyingCredential.GetAccessTokenForRequestAsync().Result;
WebClient webclient = new WebClient();
webclient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
webclient.Headers.Add(HttpRequestHeader.Authorization, $"Bearer {_oAuthToken}");
查看更多
Melony?
4楼-- · 2019-09-20 16:04

Ok found a solution by programmatically adding creds to the request like this:

var creds = GoogleCredential.FromFile(cloudKeyFile);
var scopedCreds = creds.CreateScoped(DialogflowService.Scope.CloudPlatform);
var response = new DialogflowService(new BaseClientService.Initializer
        {
            HttpClientInitializer = scopedCreds,
            ApplicationName = ProjectId
        }).Projects.Agent.Sessions.DetectIntent(
            new GoogleCloudDialogflowV2DetectIntentRequest
            {
                QueryInput = new GoogleCloudDialogflowV2QueryInput
                {
                    Text = new GoogleCloudDialogflowV2TextInput
                    {
                        Text = queryText,
                        LanguageCode = languageCode
                    }
                }
            },
            $"projects/{ProjectId}/agent/sessions/{sessionId}")
            .Execute();

NOTE - remember to add relevant Scope flags!

Example that brought clarity: https://developers.google.com/api-client-library/dotnet/guide/batch

查看更多
太酷不给撩
5楼-- · 2019-09-20 16:19

Dialogflow's API authentication changes substantially from v1 to v2. Instead of using client and developer access tokens you need to use OAuth2 or OAuth2 service account with the proper scopes (https://www.googleapis.com/auth/cloud-platform) and roles (Dialogflow API Admin, Dialogflow API Client, or Dialogflow API Reader)

Sources:

查看更多
登录 后发表回答