Create a coupon-finding app by combining Yelp, Google Maps, Twitter, and Klout services

IBM Bluemix is an ideal platform for building applications that bring together diverse services in new ways. This tutorial show you how to build an application that combines services to find coupons for highly rated businesses near a given location.

The primary application is a Java™ app running on Liberty with a MongoLab database service. Data is collected from external APIs including Yelp, Google, Twitter, and Klout. The application collects data, merges, and then optimizes results using an aggregation sort and sorting based on reviews.

On the Bluemix platform, you can combine diverse services in new ways to build new application capabilities.

What you need to build your application

Step 1. Download application to Eclipse

We developed the application with Eclipse, so here are step-by-step directions to import, deploy, and modify the application using Eclipse.

  1. Click the Get the code button, above, to go to the DevOps Services project.
  2. Click EDIT CODE.
  3. Highlight the main project, kapoor|TravelSavingsApp, and right-click.
  4. Click Export > Zip and save the file locally. Screenshot of saving the zip file locally
  5. Import the zip file into Eclipse by clicking File > Import > General > Existing Projects into Workspace. Then click Next.
  6. Select the exported zip file, and the Eclipse project is constructed locally. Screenshot of selecting the imported zip file

Step 2. Install the Bluemix plugin for Eclipse

To use Bluemix with Eclipse, install the IBM Eclipse Tools for Bluemix plugin, which enables deployment and integration of applications with IBM Bluemix or other Cloud Foundry clouds. Bluemix is based on Cloud Foundry and supports the Cloud Foundry APIs.

  1. In Eclipse, click Help > Eclipse Marketplace….

    Note: If your Eclipse installation doesn’t have the Marketplace, you can install it under Help > Install New Software. Select your Eclipse download site and, under General Purpose Tools, click to add Marketplace Client.

  2. Search Bluemix for IBM Eclipse Tools for Bluemix.
  3. Click Install.

Step 3. Configure Eclipse for Bluemix

To deploy the application from Eclipse to Bluemix, Eclipse needs to be configured with your Bluemix account information.

  1. From the Java EE perspective in Eclipse, in the bottom window section, select the Servers tab. (Alternatively, you can click Window > Show View > Servers.)

    Note: If your Eclipse installation doesn’t have Java EE, you can install the components under Help > Install New Software and select your Eclipse download site. Click to add Web, XML, Java EE, and OSGi Enterprise Development.

  2. Right-click inside the Servers panel and select New > Server.
  3. Select IBM > IBM Bluemix, and click Next. Screenshot of defining a new server
  4. Enter your login information for Bluemix in the email and password sections. Click Validate Account. Screenshot of validating your Bluemix account
  5. Click Finish. The link with your Bluemix account is created. Screenshot of your Bluemix account link

Step 4. Deploy the application

Your Eclipse environment is now set up, and you can deploy your own copy of the application to Bluemix.

  1. Right-click the Bluemix server and select Add and Remove….
  2. Select your Yelpon Travel Services project from the window on the left, and click Add >. Screenshot of adding your app to the Bluemix server
  3. Click Finish.
  4. In Application details, enter a Name. This name must be unique, because it is used for the hostname on Bluemix. Click Finish. Screenshot of naming your app

Your application is deployed onto Bluemix. However, the application needs a MongoLab database to run properly. So, after the initial deployment, you need to create the service and bind it, as described next.

Step 5. Create and bind the MongoLab database service to your application

  1. Log in to Bluemix, and find your new application on the Dashboard.
  2. On the Dashboard, under Development Services, select ADD A SERVICE. Screenshot of starting to add a service to your app

    Screenshot of starting to add a service to your app

  3. Scroll through the catalog and, under Data Management, select the MongoLab service. Screenshot of adding the MongoLab service to your app

    Screenshot of adding the MongoLab service to your app

  4. On the Add Service panel, select all the defaults and click CREATE. This action binds the MongoLab database to your application. Screenshot of binding the MongoLab service to your app

Step 6. Add a user-defined service to read Yelp, Twitter, and Klout properties

To execute Yelp APIs, you need several properties from the yelp.com site: yelpConsumerKey, yelpConsumerSecret, yelpToken, and yelpTokenSecret.

To get the Twitter name for any business returned by Yelp, you need to go to twitter.com and get these properties: t4jAccessToken, t4jAccessTokenSecret, t4jConsumerKey, and t4jConsumerSecret.

To get the Klout score for the Twitter name, go to klout.com and get the kloutkey.

Instead of including all the keys in the source code, you can create a user-defined service called TravelSavingsService using this command:

cf create-user-provided-service TravelSavingsService -p 
"yelpConsumerKey,yelpConsumerSecret,yelpToken,yelpTokenSecret,kloutKey,t4jAccessToken,
   t4jAccessTokenSecret,t4jConsumerKey,t4jConsumerSecret"

The user is prompted to provide each value.

Next, bind TravelSavingsService to TravelSavingsApp:

cf bind-service TravelSavingsApp TravelSavingsService

Screenshot of binding a user-defined service to your app

Screenshot of binding a user-defined service to your app

Step 7. Explore the application from the browser

Now that the application is deployed and the database service is bound, take a look at the running application.

  1. In the Bluemix Dashboard, click the Routes link. A separate browser tab opens with the running application.
  2. To use the application, input a search term (for example, pizza) and where to search (for example, zip code). Press the RetrieveResults! button. Screenshot of the input fields in your app

    Screenshot of the input fields in your app

  3. The application returns a list of businesses that match the search criteria, which is obtained from the Yelp API. The Rating is dynamically calculated using inputs from Yelp and Twitter. (You can explore the code in Step 8.) Screenshot of results returned by the app

    Screenshot of results returned by the app

  4. The application uses the Google Maps APIs to map area code to location. (Google APIs are open for developers, and you don’t need to register the app with Google.) Screenshot of a Google map

Step 8. Explore inside the code

The code is a Java application, and the web UI uses HTML and JavaServer Pages (JSP). To use the Yelp APIs, you need your own keys, tokens, and secrets from Yelp.

  1. To use Yelp, create a Yelp account. Account information is kept in the src/Yelp.properties file. Replace the information in this file with your own account info. Once granted access, you can generate or change your keys as needed from the Manage API page.
  2. A Yelp request looks like this:
    // Execute a signed call to the Yelp service.  
    OAuthService service = new ServiceBuilder()
                        .provider(YelpV2API.class)
                        .apiKey("CONSUMER_KEY")
                        .apiSecret("CONSUMER_SECRET")
                        .build();
    Token accessToken = new Token("TOKEN", "TOKEN_SECRET");
    
  3. YelpCalc is the main class, where we pass the four required parameters, namely: consumerKey, consumerSecret, token, and tokenSecret.
    YelpCalc yelp = new YelpCalc(consumerKey, consumerSecret, token, tokenSecret);
    ArrayList<String> yelp_result = null;
    String yelp_response="";
    ….
    
  4. The next step in the code executes a query based on the search term and search location.
    yelp_response = yelp.yelp_query(search_term, search_location);
    yelp_result = yelp.yelp_result_list(yelp_response);
    
  5. Next, the code calculates the GPS coordinates, latitude and longitude…
    ….
    center = yelp.yelp_center(yelp_response);
    request.setAttribute("center_latitude", center[0]);
    request.setAttribute("center_longitude", center[1]);
    ….
    
  6. …and displays the results using JSP, yelpresult.jsp:
    request.getRequestDispatcher("/yelpresult.jsp").forward(request, response);
    
  7. Next, call out to the google.maps.* APIs to display the locations of businesses returned for the search item. This code snippet in result.jsp implements the algorithm:
    geocoder = new google.maps.Geocoder();
    
    geocoder.geocode(
       { 'address': address}, function(results, status) {
       if (status == google.maps.GeocoderStatus.OK) {
            console.debug('Debug information: ' + results[0].geometry.location);
            mapOptions = {
             zoom: 3,
             center: results[0].geometry.location ,
             mapTypeId: google.maps.MapTypeId.ROADMAP
             };
             map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
          <%@ page import="twitter4j.*, java.io.*, java.util.List"  %>
          <%     
             twitter4j.QueryResult result1 = (twitter4j.QueryResult) 
                  request.getAttribute("result1");
             for(twitter4j.Status status : result1.getTweets() ) {
                String text = status.getText().replace(""", "'").replace("n", " ").
                     replace("'", "");
                text = " "+text+" ";
                String location = status.getUser().getLocation();
                String screenName = status.getUser().getScreenName();
                String prof_img = status.getUser().getProfileImageURL();
    
          %>
                    
          var loc1 = "<%= location %>";
          geocoder.geocode({'address':loc1}, function (new_result) {
          // console.debug("Check here: ", new_result)
          var loc = "<%= location %>";
          var txt = '<%= text %>';
          var scrName = '<%= screenName %>';
          var profile_img = '<%= prof_img %>';
    
          var contentString = '<div id="content">'+
               '<div id="siteNotice">'+
               '</div>'+
               '<h3 id="firstHeading" class="firstHeading"><img src='+profile_img+' 
                     class="img-rounded">'+ scrName+'</h3>'+
               '<div id="bodyContent">'+
               txt  +
               '</div>'+
               '</div>';
    
          var infowindow = new google.maps.InfoWindow({
               content: contentString
            });
    
          var marker = new google.maps.Marker({
               position: new_result[0].geometry.location,
               map: map,
               title: 'Tweet'
            });
          google.maps.event.addListener(marker, 'click', function() {
             infowindow.open(map,marker);
          });
          });
          <%
             }
          %>     
    
       } else {
          alert('Geocode was not successful for the following reason: ' + status);
       }
      });
    }
    

Step 9. Integrate Klout into the application

Now, extend the code by retrieving the Klout id for each business using its Twitter name. This extension is implemented in GetKloutScore.java class. The DevOps project includes the GetKloutScore.java class and Klout.properties, twitter4j.properties, and yelpresult_klout.jsp. To begin:

  1. Check that GetKloutScore.java is in your Eclipse project under Java Resources. If not, you can import it from the DevOps Services project. Screenshot of Java Resources in your Eclipse project
  2. Update the YelpCalc class to call Klout. In the doPost() method in YelpCalc class, add the following code snippet between these two comments:
    /* Insert code to collect Klout scores for the list of businesses returned by Yelp. */
    

    and

    /* Code insertion ends here */
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
            
            // "search_term" is the parameter used in the index.html
            String search_term = request.getParameter("search_term");
            String search_location = request.getParameter("location");
    
    
            YelpCalc yelp = new YelpCalc(consumerKey, consumerSecret, token, tokenSecret);
              
            ArrayList<String> yelp_result = null;
            String yelp_response="";
            try {
                yelp_response = yelp.yelp_query(search_term, search_location);
                yelp_result = yelp.yelp_result_list(yelp_response);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            String[] center;
    
            try {
                center = yelp.yelp_center(yelp_response);
                request.setAttribute("center_latitude", center[0]);
                request.setAttribute("center_longitude", center[1]);
                System.out.println("The Latitude of center is" +  center[0]);
                System.out.println("The Longitude of center is" +  center[1]);
            } catch (JSONException e) {
                System.out.println("Unable to get Lat Long info n");
                e.printStackTrace();
            }
    
    
            request.setAttribute("query_term", search_term);
            request.setAttribute("query_location", search_location);
            request.setAttribute("query_responses", yelp_result);
    
                    
    /* Insert code to collect Klout scores for the list of businesses returned by Yelp. */
    
    
            String klout_result[]=new String [yelp_result.size()];
            String name,id;
            int i=0;
            for ( String yelp_item : yelp_result) {
            
                StringTokenizer stk = new StringTokenizer(yelp_item,"#");
                    name=stk.nextToken();
                    String score = GetKloutScore.getScore(name);
                    klout_result[i++]= name + "," + score;
                    System.out.println(klout_result[i-1]);
            }
            request.setAttribute("klout_responses", klout_result);
            
            
    /* Code insertion ends here */
            
            
            request.getRequestDispatcher("/yelpresult.jsp").forward(request, response);
    
            }
    
  3. After you do this, Eclipse shows a StringTokenizer error. To resolve it, add this import statement in YelpCalc.java:
    import java.util.StringTokenizer;
    
  4. To display the Klout score, you need to update yelpresult.jsp. The required changes are in yelpresult_klout.jsp. The quickest thing to do is just rename yelpresult_klout.jsp to yelpresult.jsp.
  5. Check that klout.properties and twitter4j.properties are in your Eclipse project. (These files are included in the DevOps project.) Another screenshot of Java Resources in your Eclipse project
  6. Create your own account on Twitter and replace the information in src > twitter4j.properties with your own.

Step 10. Build and redeploy your changes

  1. Click Project > Clean and select your Eclipse project to build it.
  2. Click the Servers view and deploy the application as described in Step 4.
  3. Navigate to your application to see the new column with Klout scores. (We found that most businesses haven’t registered, so the current Klout score is 0.) Screen shot of results returned with Klout scores

    Screen shot of results returned with Klout scores

Step 11. Calculate the Twitter score for the businesses

You can extend the code to display scores based on followerCount, retweetCount, and mentionCount for the twitterName of the business as well as the tweets on GoogleMaps. This extension is implemented in the YelpCac.java class. The DevOps project includes YelpCalc.java:

String twitterUsername = request.getParameter("twitter_name");

// The factory instance is re-useable and thread safe.
Twitter twitter = new TwitterFactory().getInstance();

try {
    User a_name = twitter.showUser(twitterUsername);
    int followerCount = a_name.getFollowersCount();
    List<Status> retweets = twitter.getUserTimeline(twitterUsername, 
        new Paging(1, 20)); // get the first twenty tweets
    int retweetCount = 0;

    for (Status tweet : retweets) {
        retweetCount += (int) tweet.getRetweetCount();
    }

    System.out.println("The rtcount is: " + retweetCount);

    int mentionCount = 0;

    int retweetScore = 0;
    int followerScore = 0;

    if (retweetCount >= 100000)
        retweetScore = 60;
    elseif (retweetCount >= 20000)
        retweetScore = 50;
    elseif (retweetCount >= 10000)
        retweetScore = 40;
    elseif (retweetCount >= 5000)
        retweetScore = 30;
    elseif (retweetCount >= 1000)
        retweetScore = 20;
    elseif (retweetCount >= 500)
        retweetScore = 10;
    elseif (retweetCount >= 100)
        retweetScore = 5;
    elseif (retweetCount >= 10)
        retweetScore = 1;

    if (followerCount >= 10000000)
        followerScore = 40;
    elseif (followerCount >= 1000000)
        followerScore = 35;
    elseif (followerCount >= 500000)
        followerScore = 30;
    elseif (followerCount >= 100000)
        followerScore = 25;
    elseif (followerCount >= 1000)
        followerScore = 20;
    elseif (followerCount >= 500)
        followerScore = 15;
    elseif (followerCount >= 100)
        followerScore = 10;
    elseif (followerCount >= 10)
        followerScore = 5;

    // Search API call to calculate the mentions out of 100
    Query query = new Query("@" + twitterUsername);
    query.setCount(100);
    query.setResultType(Query.RECENT);
    QueryResult result = twitter.search(query);
    mentionCount += result.getTweets().size();

    System.out.println("the mcount is: " + mentionCount);

    // Calculate the total score of the user.
    int totalscore = retweetScore + followerScore + mentionCount;

    System.out.println("The total score is: " + totalscore);

    // tweets to be displayed on the google maps
    Query query1 = new Query("@" + twitterUsername);
    query.setCount(20);
    query.setResultType(Query.RECENT);
    QueryResult result1 = twitter.search(query1);

This tutorial has shown how to use Eclipse to set up, update, and deploy to Bluemix a Java application that finds highly rated businesses near your location. You’ve seen how to combine data from multiple services, including Yelp, Google, Twitter, and Klout, and other programmable web APIs to retrieve, sort, and analyze data. Feel free to adapt the Java code, MongoDB, search, and analysis code for other data sources and purposes.

RELATED TOPICS:YelpGoogle MapsTwitterKlout

BLUEMIX SERVICES USED IN THIS TUTORIAL:

  • The Liberty for Java runtime helps you develop, deploy, and scale Java web apps with ease.
  • The MongoLab service provides a fully-managed, highly-available MongoDB database, along with automated backups, web-based tools, 24/7 monitoring, and expert support.

Source: Create a coupon-finding app by combining Yelp, Google Maps, Twitter, and
Klout services

Post author

Dustin Gurley is an Designer, Developer, Artist, Instructor, Critical Theorist and Systems Engineer. He has an extensive background working professionally with 2D/2.5D/3D Motion Graphics, Compositing, Film, Video, Photography and client-side performance techniques as it pertains to web development. Dustin recently completed work on his Master of Fine Art degree in Motion Media Design (Motion Graphics) from the Savannah College of Art and Design. Prior to beginning his graduate work, Dustin obtained a Bachelor of Art degree in Communication Studies with a concentration in Broadcast and Emerging Media from the University of North Carolina at Wilmington. In addition to design and modeling, Dustin enjoys toying with his view camera, working with scratch film, authoring media related material and contributing to various industry conferences. When not in front of a computer, Dustin can be found with his wife, Regina Everett Gurley. The couple enjoys dividing their time between their home just outside of Raleigh, North Carolina and the beautiful North Carolina coast. Currently, Dustin serves as the Lead Instructor of Internet Technologies for Wake Technical Community College in Raleigh, North Carolina.