Ivan Krsul
Ivan Krsul

Reputation: 51

Using Google.Apis.Translate.v3beta1 in .NET to translate a PPT file - Error 403: "Provided scope(s) are not authorized"

I have been trying to use the .NET API for Google.Apis.Translate.v3beta1 to translate a PPTX or DOCX file, retaining the document format. In theory, this is possible as per the description in https://cloud.google.com/translate/docs/advanced/translate-documents#translate_documents_online but the documentation is so poor, that it's impossible to guess how this should work.

I was hoping that someone out there knows how this API is supposed to work.

This is what I tried.

As hinted by the documentation this is my code in C#:

public async Task doitAsync()
{
    string keyFile = @"mykeyfile.p12";

    // Get the certificate 
    var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.Exportable);

    // Create the credential so we can generate an access token
    ServiceAccountCredential credential = new ServiceAccountCredential(
       new ServiceAccountCredential.Initializer("[email protected]")
       {
           Scopes = new[] { Google.Apis.Translate.v3beta1.TranslateService.Scope.CloudTranslation },
           ProjectId = "myproject",
           KeyId = "some long key like 3aedc7cfe17d2ad83813f162f4af50597bade165d619d65eab6b5"

       }.FromCertificate(certificate));

    // Get a request token 
    bool success = await credential.RequestAccessTokenAsync(new CancellationToken());
    string token = credential.Token.AccessToken;

    string json = File.ReadAllText("params.json");

    Google.Apis.Translate.v3beta1.TranslateService serv = new Google.Apis.Translate.v3beta1.TranslateService();
    var client = serv.HttpClient;
    client.BaseAddress = new Uri("https://translation.googleapis.com/v3beta1/projects");
    var httpContent = new StringContent(json, Encoding.UTF8, "application/json");

    var response = await client.PostAsync(
        "https://translation.googleapis.com/v3beta1/projects/myproject/locations/global:translateDocument?access_token=" + token,
        httpContent);

    if (response.IsSuccessStatusCode)
    {
        string res = await response.Content.ReadAsStringAsync();
        Console.WriteLine("Success: " + res);
    }
    else
    {
        string res = await response.Content.ReadAsStringAsync();
        Console.WriteLine("Failure: " + res);
    }
}

The result of executing this code is always:

Failure: {
  "error": {
    "code": 403,
    "message": "Provided scope(s) are not authorized",
    "errors": [
      {
        "message": "Provided scope(s) are not authorized",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED"
  }
}

However, my service account is associated to the Translation API.

So I was hoping that someone out there has some experience with the .NET API for Google.Apis.Translate.v3beta1 and can shed some light as to how this is supposed to be invocated, or can point out what I am missing.

Upvotes: 1

Views: 669

Answers (1)

Ivan Krsul
Ivan Krsul

Reputation: 51

So, if you add this as your Scope it will work:

Scopes = new[] { 
    Google.Apis.Translate.v3beta1.TranslateService.Scope.CloudTranslation,
    "https://www.googleapis.com/auth/cloud-platform"
},

Thanks to Ricco for his assistance.

Upvotes: 1

Related Questions