Sonntag, 10. Januar 2016

Migrate Blog to blogger.com

I was running a blog for many years, it was once developed on Java technology by myself. It has always been fun developing this blog, I was my playground for trying out new technologies.
But over time it became a burden to me. It was obvious that design and technology is moving on, but I did not have the time to update my own implementation. Furthermore, the implementation was big mess by now.
Of course I was not willing to give up the 600 posts, because this is an important documentation of my life.

So I started to look into possibilities of migrating to a cloud blogging software. I ended with blogger.com because it has a good REST API and even a Java client library which utilizes this API.
But I was googling for quite a long time to understand the propper usage of this library. There are different versions of the API and even Google has wrong examples on its website.
Therefore I am posting my solution how I finally managed to use the Blogger API v3 with Goole's Java client library. Maybe it will help somebody.
But there is one big obstacle: The blogger API allows only 50 post creations per day. And  there is no way around it. It contacted Google in severaly ways. They suggested to submit this as a feature request, what I did.

You will get this error when you post more than 50.

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "usageLimits",
    "message" : "Rate Limit Exceeded",
    "reason" : "rateLimitExceeded"
  } ],
  "message" : "Rate Limit Exceeded"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)

...
}

The result is the blog at blog.alpenkarte.eu

Finaly the code that worked for me:

import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.List;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.blogger.Blogger;
import com.google.api.services.blogger.Blogger.Posts.Insert;
import com.google.api.services.blogger.BloggerScopes;
import com.google.api.services.blogger.model.Post;

public class BloggerAccess {
   
    private static final String BLOG_ID = "1234";
    private static final String SERVICE_ACCOUNT_EMAIL = "demo@gmail.com";

   
      private static NetHttpTransport HTTP_TRANSPORT;
      private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
      private static final java.io.File DATA_STORE_DIR =
              new java.io.File(System.getProperty("user.home"), ".store/plus_sample");
     
      private static final String[] SCOPES =
                new String[] {
                  "https://www.googleapis.com/auth/blogger"
                };
       
      private static FileDataStoreFactory dataStoreFactory;



   
    public static Post savePost(String content, String title, DateTime date, String metaData, List<String> labels)  throws Exception {

        HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);

        Credential credential = authorizeService();

        // Construct the Blogger API access facade object.
        Blogger blogger = new Blogger.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName("BlogMigration").build();
        Post post = new Post();
        post.setContent(content);
        post.setTitle(title);
        post.setPublished(date);
        post.setCustomMetaData(metaData);
        post.setLabels(labels);
        Insert insert = blogger.posts().insert(BLOG_ID, post);

        Post postResponse = insert.execute();
        String postURL = postResponse.getUrl();
        System.out.println("POST URL: " + postURL);
        return postResponse;
    }
   
   
   
    private static Credential authorizeService() throws Exception {
         
        URL url = BloggerAccess.class.getResource("BlogMigration-e3489c32f480.p12");
        File authFile = new File(url.getPath());
         
          GoogleCredential credential = new GoogleCredential.Builder()
                      .setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY)
                    .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                    .setServiceAccountScopes(Collections.singleton(BloggerScopes.BLOGGER))
                    .setServiceAccountPrivateKeyFromP12File(authFile)
                    .build();
         
         //Get the Access Token from https://developers.google.com/oauthplayground/               credential.setAccessToken("ya29.ZQIAFc34WrvahPSGiChzybthrltfra6i2Va3WNaRkaSPC8gfL4XkTJgv8884fxO4R5c7");
         
          return credential;
   
        }

}