Wednesday, March 21, 2012

Blogger API - create a new post using JavaScript

I am a heavy Blogger user.I write blogs. I never thought of wanted to know Blogger API, but I do thought of get to know Google API. I am glad that my work gives me an opportunity to explore this, for work and for myself. :) 

I'd like to thank Brett Morgan and also those responded to Issue 42 in gdata-java​script-cli​ent. Without them, I won't be able to complete this piece of code. And also, not forgetting the original source code that provide me the baseline to start to work at available here.

This piece of code will do the Google account authentication and authorization process, it will then grab your blog list, and provide a simple form for you to select a blog, taking your new post entry's title and content, and then post it. I have tested on FF3.2.26, Safari 5, Chrome, and IE8. There'll be some prompts to proceed depends on the browser that you are using.

Some special handlings were happened during my weeks of getting this piece of code in place. I can only recall a few of them.
  1. You must include an image in your html file. However, I just put a <img> tag, but the image actually does not exist, works fine.
  2. I was testing using https://localhost. It worked fine for all browsers. However, during preparing the last version of code, after Issue 42 is resolved, it doesn't work on Safari anymore. It might due to Safari update, I didn't check this out.
  3. I spent most time on authentication and authorization. The original code doesn't work on my testing. It only work fine if pre-login to Google account. Found another login methodology which work perfectly for me, which you can check out on the source code below. :) 
Not forgetting, this documentation helps most on Google API. Here's my source code, too bad, I am not able to embed it in this blog post. :P


<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <script src="https://www.google.com/jsapi?key=<Your key>" type="text/javascript"></script>
    <script type="text/javascript">
     
      google.load("gdata", "1");
     
      // To enter one or more authentication scopes, refer to the documentation for the API.
      var scopes = 'http://www.blogger.com/feeds';
     
      var bloggerService;
      var targetBlog;
      var targetBlogTitle;

      function checkAuth() {
        google.gdata.client.init(handleError);
        var authorizeButton = document.getElementById('authorize-button');
        var blogEntryForm = document.getElementById('blogEntryForm');
        var myToken = google.accounts.user.checkLogin(scopes);
        bloggerService = new google.gdata.blogger.BloggerService('<your apps name>');
        if (google.accounts.user.checkLogin(scopes)) {
          authorizeButton.style.visibility = 'hidden';
          blogEntryForm.style.visibility = '';
          bloggerService.getBlogFeed('http://www.blogger.com/feeds/default/blogs', setupBlogList, handleError);
        }
        else {
          authorizeButton.style.visibility = '';
          blogEntryForm.style.visibility = 'hidden';
        }
      }
      google.setOnLoadCallback(checkAuth);


      function myLogin() {
        var authorizeButton = document.getElementById('authorize-button');
        authorizeButton.style.visibility = 'hidden';
        google.accounts.user.login(scopes);
      }

      function postIt() {
        if (document.forms['myForm'].elements['inputTitle'].value.length < 1) {
            alert ("Error : Please insert a title!");
            return false;
        }
        var FeedURI = document.forms['myForm'].elements['href'].value;
        bloggerService.getBlogPostFeed(FeedURI, insertMyEntry, handleError);
        return;
      }

    function setupBlogList(blogEntry) {
        var targetCombo = document.getElementById('combo');
        var options;
        var entries = blogEntry.feed.entry;
        for (entry in entries) {
            options += "<option value='" + entries[entry].getEntryPostLink().href + "'>" + entries[entry].getTitle().getText() + "</option>";
         }
        targetCombo.innerHTML = "<select name=href id=href>" + options + "</select>";
    }

    function insertMyEntry(myResultFeedRoot) {
      targetBlog = myResultFeedRoot.feed.getHtmlLink().href;
      targetBlogTitle = myResultFeedRoot.feed.getTitle().getText();
      var inputTitle = document.forms['myForm'].elements['inputTitle'].value;
      var inputText = document.forms['myForm'].elements['inputText'].value;
      var blogEntry = new google.gdata.blogger.PostEntry({
        title : {
            type: 'text',
            text: inputTitle
        },
        content: {
            type: 'text',
            text: inputText
        }
      });
      myResultFeedRoot.feed.insertEntry(blogEntry, handleMyInsertedEntry, handleError);
    }

    function handleMyInsertedEntry(postEntry) {
      alert('Successful insert a blog entry!! :D');
      window.open(postEntry.entry.getHtmlLink().href, postEntry.entry.getHtmlLink().title, target='_blank');
    }

    function handleError(e) {
      alert(e.cause ? e.cause.statusText : e.message);
    }

    </script>
  </head>
  <body>
    <script src="https://apis.google.com/js/client.js"></script>
    <input type=button value=Authorize id="authorize-button" style="visibility: hidden" onclick="myLogin()">
    <div id=blogEntryForm style="visibility: hidden">
    <form id=myForm>
        <table>
            <tr>
            <td>Select a blog...</td>
            <td id='combo'>
               
            </td>
            </tr>
            <tr>
            <td>Title</td>
            <td><input type=text id=inputTitle name=inputTitle size=32></td>
            </tr>
            <tr><td colspan=2>&nbsp;</td></tr>
            <tr>
            <td>Content</td>
            <td><textarea id=inputText name=inputText rows=6 cols=26></textarea></td>
            </tr>
            <tr><td colspan=2>&nbsp;</td></tr>
            <tr><td colspan=2><input type=button value=Submit onclick="postIt()"></td></tr>
        </table>
       
    </form>
    </div>


    <div id=hidethis style="visibility: hidden">
    <p>Maybe I should add in some text here to display....</p>
    <img src=a.png>
    </div>
  </body>
</html>

1 comment: