Godsayah
Godsayah

Reputation: 144

Authenticating Request with Google.Apis.DialogFlow.V2

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

Upvotes: 1

Views: 7505

Answers (4)

Francisco Goldenstein
Francisco Goldenstein

Reputation: 13777

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

Upvotes: 0

Codebricks
Codebricks

Reputation: 1263

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}");

Upvotes: 1

Godsayah
Godsayah

Reputation: 144

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

Upvotes: 1

mattcarrollcode
mattcarrollcode

Reputation: 3479

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:

Upvotes: 0

Related Questions