5

I'm using the Youtube .Net libray I downloaded from Nuget.

I created a windows service which is checking a folder to upload new videos to youtube. I did the tests using a console application and for this case the user had to do authorization manually on a web browser, after that I could upload videos to youtube without any problem. The issue is when I'm trying to use the offline access.

As I'm running my code on a windows service I cannot get a the manual authorization from the user so I created my access token following this answer: https://stackoverflow.com/a/20689423/2277059

The thing is that I didn't find any example of code using the standalone version so I'm a bit lost. With my current code I'm getting all the time Error:"unauthorized_client" when trying to upload the video. The JSON file you can see on my code "client_secrets.json" is the one you automatically generate when creating the credentials for the YouTube API V3.

I tried this as well: https://stackoverflow.com/a/43895931/2277059, but got same error.

Right now I'm not refreshing the token from code, just doin it on the OAuth Playground and testing the service. Once it worked I'll research about how refresh the token with every query.

When creating the credentials I selected the type "Other" as this is a windows service.

Is it something wrong with my code or am I missing something on the configuration?

This is my code:

var token = new TokenResponse()
{
    AccessToken = "werwdsgfdg...",
    ExpiresInSeconds = 3600,
    RefreshToken = "3/dsdfsf...",
    TokenType = "Bearer"
};

Log.Info("Generating user credentials and secrets");

UserCredential credential;
string credentialsPath = System.AppDomain.CurrentDomain.BaseDirectory + "client_secrets.json";

using (var stream = new FileStream(credentialsPath, FileMode.Open, FileAccess.Read))
{
    credential = new UserCredential(new GoogleAuthorizationCodeFlow(
    new GoogleAuthorizationCodeFlow.Initializer
    {
        ClientSecrets = GoogleClientSecrets.Load(stream).Secrets,
        Scopes = new[] { YouTubeService.Scope.YoutubeUpload }
    }
    ), EsSettings.YoutubeUser, token);
}


Log.Info("Generating youtube service");
//GoogleAuthorizationCodeFlow
YouTubeService youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
});


Log.Info("Uploading...");
using (var fileStream = new FileStream(filePath, FileMode.Open))
{

    var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
    videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
    videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;


    await videosInsertRequest.UploadAsync();
}
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449

1 Answers1

3

Error:"unauthorized_client"

Means that the client id you are sending hasn't been authenticated by the user.

The reason you are getting this is beouse you are doing this

Right now I'm not refreshing the token from code, just doin it on the OAuth Playground and testing the service. Once it worked I'll research about how refresh the token with every query.

Tokens are associated with a client. your client_secrets.json file contains your client but the tokens you grabbed out of oauth playground are not associated with that client.

You should should run your code once on your own machine authenticating it. Check the credentials file which can be found in your %appData% folder for the access token and refresh token and then send those to your token.

This is what the file should contain.

{  
   "access_token":"ya29.4wEk2VsbqiPfR4oH5WaYo7aYgAmlP2KSIl-heyDnPBBHMYYKnfU6YuQ-_RsDofD8QR1T",
   "token_type":"Bearer",
   "expires_in":3600,
   "refresh_token":"1/PSvxzxGB-3XU8bF2SrG6llzO-ZizE4mftrd9Edqbubg",
   "Issued":"2015-09-03T11:43:47.681+02:00"
}

You can read about how the file was created here FileDatastore

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • Ok, first of all, thank you for your time. If I understood the steps should be the following: 1. Run my console application on my machine so I can do the manual authorization 2. Get the token file from %appdata% and set the token on my windows service 3. Set my windows service to use that token and refresh the token with every call 4. I can move my service to prod. In the meantime I'm goign to research about how to refresh the token using the .NET library. – user2277059 Jun 18 '18 at 12:14
  • You dont need to refresh the token the client library is going to do that for you as soon as the access token expires. – Linda Lawton - DaImTo Jun 18 '18 at 12:23
  • When you authenticate, the token file named Google.Apis.Auth.OAuth2.Responses.TokenResponse-user is created in C:\Users\\AppData\Roaming\Google.Apis.Auth. Using the dataStore parameter of the AuthorizeAsync method, you can specify a folder and filename for the token file. When you subsequently use the Google.Apis.Auth.OAuth2.Responses.TokenResponse-user file in your Windows Service, you do not have to refresh the token. The Google API does the refresh automatically. – Mike Meinz Jun 18 '18 at 12:29
  • @MikeMeinz thanks but i already mentioned that and linked a article on how file datastore works. Really dont want to confuse him. – Linda Lawton - DaImTo Jun 18 '18 at 12:32
  • But If I don't use the Access Token in, for example, 3 hours, next call I'm going to do the access token will be expired and the call will fail. Or it won't? – user2277059 Jun 18 '18 at 12:33
  • 2
    It will refresh automatically! Sometimes, I have waited days before reusing a token and it has always refreshed automatically. See ResumeableUpload sample at [https://github.com/google/google-api-dotnet-client-samples][1]. [1]: https://github.com/google/google-api-dotnet-client-samples – Mike Meinz Jun 18 '18 at 12:34
  • The refresh token will be used by the library to request a new access token. This is the whole magic behind offline access. you may find this interesting http://www.daimto.com/google-developer-console-oauth2/ – Linda Lawton - DaImTo Jun 18 '18 at 12:37
  • 1
    Ok guys, understood. I'm going to try the whole process and I'll let you know. Thanks a lot. – user2277059 Jun 18 '18 at 12:39
  • 1
    All good, I did what you said and all working fine. Thanks to both of you. – user2277059 Jun 18 '18 at 15:59