tatertot
tatertot

Reputation: 133

Blogger API Sample Code

So this is my first question on StackOverflow, so please let me know if there's something I've neglected to include!

I'm trying to get Blog post data from public Blogger blogs for some language analysis research that I'm doing. Although the java API seems pretty straight-forward, I've found that Google's code sample at https://developers.google.com/blogger/docs/3.0/reference/posts/list#examples does not work, as there are many dependencies missing, ranging from LocalServerReceiver() to a whole host of dependencies needed for OAuthorization. The API explorer works just fine, but obviously, I need something for my own code.

I also tried utilizing code fragments from other StackOverflow questions that I saw were similar to mine, and am still facing dependency issues.

Here's a list of some of the questions I've looked at, which have not solved my issue due to some sort of code deprecation:

I've used the OAuthPlayground to get an authorization code, and have been trying to replicate some of the functionality of iamkhova's solution in Proper Form of API request to Blogger using Java/App Engine -error 401. Note that I'm not actually trying to write anything to any of the blogs I'm accessing. I just want to be able to get the post data for analysis.

Currently I've just altered iamkhova's solution by taking out the logger, and adding a getPosts() function that duplicates what I need from Google's sample code.

   public class BlogHandler
{
  static final String API_KEY = {My API Key};
  public Blogger blogger = null;
  public Blog blog;
  public java.util.List<Post> posts;

  public BlogHandler() {}

  public void executeGetBlogByUrl (String url) throws IOException {
     GetByUrl request = blogger.blogs().getByUrl( url );
     this.blog = request.setKey(API_KEY).execute();

   }
  public void getPosts() throws IOException
  {
      List postsListAction = blogger.posts().list(this.blog.getId());

    // Restrict the result content to just the data we need.
    postsListAction.setFields("items(author/displayName,content,published,title,url),nextPageToken");

    // This step sends the request to the server.
    PostList posts = postsListAction.execute();

    // Now we can navigate the response.
    int postCount = 0;
    int pageCount = 0;
    while (posts.getItems() != null && !posts.getItems().isEmpty()) {
            for (Post post : posts.getItems()) {
                    System.out.println("Post #"+ ++postCount);
                    System.out.println("\tTitle: "+post.getTitle());
                    System.out.println("\tAuthor: "+post.getAuthor().getDisplayName());
                    System.out.println("\tPublished: "+post.getPublished());
                    System.out.println("\tURL: "+post.getUrl());
                    System.out.println("\tContent: "+post.getContent());
            }

            // Pagination logic
            String pageToken = posts.getNextPageToken();
            if (pageToken == null || ++pageCount >= 5) {
                    break;
            }
            System.out.println("-- Next page of posts");
            postsListAction.setPageToken(pageToken);
            posts = postsListAction.execute();
    }

  }

   public void setupService () throws IOException {

    AppIdentityCredential credential = null;
    credential  = new AppIdentityCredential(Arrays.asList(BloggerScopes.BLOGGER)); // Add your scopes here
    this.blogger = new Blogger.Builder(new UrlFetchTransport(), new JacksonFactory(), credential).setApplicationName("chsBlogResearch").build();
   }

}

Currently, I'm having the following error:

Exception in thread "main" com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'memcache' or call 'Get()' was not found.
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:173)
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:171)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
    at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:26)
    at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:49)
    at com.google.appengine.api.appidentity.AppIdentityServiceImpl.getAccessToken(AppIdentityServiceImpl.java:286)
    at com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential.intercept(AppIdentityCredential.java:98)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at BloggerData.BlogHandler.executeGetBlogByUrl(BlogHandler.java:29)

Clicking on the code lines for both the errors in MemcacheServiceImpl and AppIdentityServiceImpl tell me that there are no lines of code at that point. I'm using Maven within Eclipse for dependencies.

The only thing I'm not really sure about in this code is the idea of scopes, but I don't think that that should be causing my errors.

I would appreciate any ideas on this, as getting this post data has been way more time-consuming than I thought it would be!

Update: getting strange exception trying to implement asynchronous http in google app engine for java provided a little more insight on the error above. Apparently this ApiProxy jar cannot be called through a console app.

Upvotes: 2

Views: 5437

Answers (2)

Shubhra Sinha
Shubhra Sinha

Reputation: 47

From the multiple links, I got the following standalone java class WORKING for blogger api v3 (used api key and oauth2 credentials). Although I've to manually paste the token from request uri on console.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.security.GeneralSecurityException;
    import java.util.Arrays;
    import java.util.List;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.json.JSONException;
    import org.json.JSONObject;
    import com.google.api.client.auth.oauth2.Credential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
    import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
    import com.google.api.client.http.HttpTransport;
    import com.google.api.client.http.javanet.NetHttpTransport;
    import com.google.api.client.json.jackson2.JacksonFactory;
    import com.google.api.services.blogger.BloggerScopes;


    public class PostInsert {
        private static final String REDIRECT_URI = "YOUR REDIRECT URI";
        private static final String CLIENT_SECRET = "YOUR CLIENT SECRET";
        private static final String CLIENT_ID = "YOUR CLIENT_ID";

        public static void main(String[] args) {

            try {
                HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
                JacksonFactory JSON_FACTORY = new JacksonFactory();
                Credential credential = getCredentials(HTTP_TRANSPORT, JSON_FACTORY, Arrays.asList(BloggerScopes.BLOGGER));

                final JSONObject obj = new JSONObject();
                obj.put("id", "<enter your blogid>");

                final JSONObject requestBody = new JSONObject();                

                requestBody.put("title", "adding on 15feb 1.56pm");

                requestBody.put("content", "add this");

                final HttpPost request = new HttpPost("https://www.googleapis.com/blogger/v3/blogs/<enter your blogid>/posts?key=<enter your api key>");
                request.addHeader("Authorization", "Bearer " + credential.getAccessToken());
                request.addHeader("Content-Type", "application/json");
                HttpClient mHttpClient = new DefaultHttpClient();
                request.setEntity(new StringEntity(requestBody.toString()));
                final HttpResponse response = mHttpClient.execute(request);
                System.out.println( response.getStatusLine().getStatusCode() + "   " + 
                        response.getStatusLine().getReasonPhrase()
                        );
            } catch (JSONException | IOException | GeneralSecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

            public static GoogleCredential getCredentials(HttpTransport httpTransport, JacksonFactory jacksonFactory,
                    List<String> scopes) throws IOException, GeneralSecurityException {
                GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, jacksonFactory,
                        CLIENT_ID, CLIENT_SECRET, scopes).setAccessType("online").setApprovalPrompt("auto").build();
                String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();
                System.out.println("Please open the following URL in your " + "browser then type the authorization code:");
                System.out.println("  " + url);
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String code = br.readLine();
                GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute();
                System.out.println("Response : " + response.toPrettyString());
                GoogleCredential credential = 
                        new GoogleCredential.Builder()
                            .setTransport(httpTransport)
                            .setJsonFactory(jacksonFactory)
                            .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
                            .build();
                credential.setAccessToken(response.getAccessToken());
                return credential;
            }       
    }

Upvotes: 0

tatertot
tatertot

Reputation: 133

Not really a super helpful answer, but it's what ended up working in my situation.

The Google Java API client is extremely out of date, so I ended up switching to the Google API Python client instead, since it's updated better, and OAuth actually works in the Python client. It's located at: https://github.com/google/google-api-python-client. The sample files are very useful, and actually intuitive.

Note that Google's Java API samples are all broken, at least on the Blogger side of things.

Upvotes: 2

Related Questions