Search code examples
google-oauthgoogle-indexing-api

google oauth 2 authorization when using their indexing api


I'm trying to make sense of the google indexing api but their documentation is horrible. I've gone through setting up the service account and downloading the json file along with the remaining prerequisites. The next step is to get an access token to authenticate.

I'm in a .net environment but they don't give an example for that. I did find some example of using a .net library to do it here, but after the following code I'm not sure what service would be created to then make the call to the indexing api. I don't see a google.apis.indexing library in the nuget package manager.

UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets,
        new[] { "https://www.googleapis.com/auth/indexing" },
        "user", CancellationToken.None, new FileDataStore("IndexingStore"));
}

In their example code it looks like just a simple json post. I tried that but of course it doesn't work because I'm not authenticated. I'm just not sure how to tie all of this together in a .net environment.


Solution

  • You're right, Google's documentation for this is either not there or is terrible. Even their own docs have broken or unfinished pages in them and in one of them you're pointed to a nuget package that doesn't exist. It is possible to get this to work though by cobbling together other Auth examples on SA and then following the Java indexing documentation.

    First, you'll need to use nuget package manager to add the main api package and the auth package:

    Then try the following:

    using System;
    using System.Configuration;
    using System.IO;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Http;
    using Newtonsoft.Json;
    
    namespace MyProject.Common.GoogleForJobs
    {
        public class GoogleJobsClient
        {
            public async Task<HttpResponseMessage> AddOrUpdateJob(string jobUrl)
            {
                return await PostJobToGoogle(jobUrl, "URL_UPDATED");
            }
    
            public async Task<HttpResponseMessage> CloseJob(string jobUrl)
            {
                return await PostJobToGoogle(jobUrl, "URL_DELETED");
            }
    
            private static GoogleCredential GetGoogleCredential()
            {
                var path = ConfigurationManager.AppSettings["GoogleForJobsJsonFile"];
                GoogleCredential credential;
                using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleCredential.FromStream(stream)
                        .CreateScoped(new[] { "https://www.googleapis.com/auth/indexing" });
                }
    
                return credential;
            }
    
            private async Task<HttpResponseMessage> PostJobToGoogle(string jobUrl, string action)
            {
                var googleCredential = GetGoogleCredential();
                var serviceAccountCredential = (ServiceAccountCredential) googleCredential.UnderlyingCredential;
    
                const string googleApiUrl = "https://indexing.googleapis.com/v3/urlNotifications:publish";
    
                var requestBody = new
                {
                    url = jobUrl,
                    type = action
                };
    
                var httpClientHandler = new HttpClientHandler();
    
                var configurableMessageHandler = new ConfigurableMessageHandler(httpClientHandler);
    
                var configurableHttpClient = new ConfigurableHttpClient(configurableMessageHandler);
    
                serviceAccountCredential.Initialize(configurableHttpClient);
    
                HttpContent content = new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json");
                var response = await configurableHttpClient.PostAsync(new Uri(googleApiUrl), content);
    
                return response;
            }
        }
    }
    

    You can then just call it like this

    var googleJobsClient = new GoogleJobsClient();
    var result = await googleJobsClient.AddOrUpdateJob(url_of_vacancy);
    

    Or if you're not inside an async method

    var googleJobsClient = new GoogleJobsClient();
    var result = googleJobsClient.AddOrUpdateJob(url_of_vacancy).Result;