Digital Developer Conference: Cloud Security 2021 – Build the skills to secure your cloud and data Register free

Create an artificial intelligence bookmark organizer for the Chrome browser

You often find interesting articles that you want to bookmark to read later. However, saving a lot of these in proper fashion often requires you to manually create meaningful folder structure so that you can refer to them easily. With cognitive solutions offered by IBM Watson, you can create a browser extension to do this for you automatically. In this tutorial, learn how to create a browser extension that uses Watson Natural Language Understanding to automatically organize the web pages you bookmark.

Learning objectives

In this tutorial, you create a Google Chrome browser extension that uses Watson Natural Language Understanding to automatically store the bookmarked URL in its proper directory structure so that you don’t have to manually do it for each page you want to bookmark.

Prerequisites

Before beginning, you need an IBM Cloud account.

Estimated time

It should take you approximately 15 minutes to complete this tutorial.

Steps

Use the following steps to create your own instance of the Watson Bookmark.

Step 1: Create Watson services on IBM Cloud

  1. Log in to IBM Cloud.

  2. Click Catalog, and search for Natural Language Understanding.

  3. Create a Natural Language Understanding service. After the service is created, you are directed to the service page where you can see the service credentials. Click Service credentials, then select the Auto-generated service credentials check box, and click the down arrow. You see the API key for the newly created service.

    Creating a natural language understanding service

    Note the API key appearing here because you need it in the next step.

Step 2: Create a Chrome browser extension

  1. In a new directory, create a manifest.json file.

  2. Open the working directory with your favorite IDE. Open the manifest.json file and update it with the following code.

     {
         "name": "Watson Bookmark",
         "version": "1.0",
         "manifest_version": 2,
         "description": "Smart bookmark organizer which uses Watson Natural Language Understanding to organize the bookmarked url and store it in proper directory structure.",
         "icons": {
             "16": "https://developer.ibm.com/developer/default/tutorials/smart-bookmark-plugin-using-watson-nlu/images/ibmwatson.png",
             "48": "https://developer.ibm.com/developer/default/tutorials/smart-bookmark-plugin-using-watson-nlu/images/ibmwatson.png",
             "128": "https://developer.ibm.com/developer/default/tutorials/smart-bookmark-plugin-using-watson-nlu/images/ibmwatson.png"
         },
         "author": "Gaurav Kumbhat/US/IBM",
         "background": {
             "scripts": [
                 "src/watson-bookmark-plugin/jquery.min.js",
                 "src/watson-bookmark-plugin/app.js"
             ],
             "persistent": false
         },
         "permissions": [
             "storage",
             "bookmarks",
             "tabs",
             "https://api.us-south.*/"
    
         ],
         "browser_action": {
           "default_title": "Watson Bookmarks",
           "default_icon": "images/watson_logo.png"
         },
         "options_ui": {
             "page": "src/watson-bookmark-plugin/views/options.html",
             "open_in_tab": false
         }
     }
    
  3. You need a logo for your extension. You can use your own or download this one. The image name needs to match the value of the icons key in the manifest.json file. In this case, it is ibmwatson.png. Save this in the images directory of the workspace.

  4. Now open a new file, src/watson-bookmark-plugin/app.js, then copy the following code.

     function saveBookmark() {
         chrome.storage.local.get(function(nlu_creds){
             chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function (tabs) {
                 var url = tabs[0].url;
                 var title = tabs[0].title;
                 chrome.bookmarks.search(url, function(results){
                     if (results.length > 0) {
                         // Do not save it, url is already saved
                         return {};
                     }
                     else {
                         callNLUCategories(nlu_creds, url).done(function(response){
                             nlu_categories = response.categories[0].label;
                             if (nlu_categories) {
                                 folders = nlu_categories.split("/");
                                 chrome.bookmarks.getTree(function(tree){
                                     other_folder = tree[0].children[1];
                                     get_bookmark_node(other_folder, folders, 1, title, url);
                                 });
                             }
                         })
                     }
                 });
    
             });
         });
     }
    
     function get_bookmark_node(parent, folders, iter, title, url){
    
         if (iter < folders.length){
             chrome.bookmarks.search({
                 title: folders[iter]
             }, function(results){
                 if (results.length > 0){
                     get_bookmark_node(results[0], folders, iter+1, title, url);
                 }
                 else {
                     chrome.bookmarks.create({
                         'parentId': parent.id,
                         'title': folders[iter]
                     }, function(newParent){
                         get_bookmark_node(newParent, folders, iter+1, title, url);
                     });
                 }
             })
         }
         else {
             chrome.bookmarks.create({
                 'parentId': parent.id,
                 'title': title,
                 'url': url
             });
         }
     }
    
     function callNLUCategories(nlu_creds, input_url){
         const nlu_url = nlu_creds.nlu_endpoint +
         '?url=' + input_url + '&version=2018-10-15' + '&features=categories';
    
         return $.ajax({
         url: nlu_url,
         dataType: 'json',
         data: null,
         username: nlu_creds.nlu_username,
             password: nlu_creds.nlu_password
       });
     }
    
     chrome.browserAction.onClicked.addListener(function(tab) {
       saveBookmark();
     });
    
  5. To create the configuration page, open the src/watson-bookmark-plugin/views/options.html file and copy the following code.

    <!DOCTYPE html>
    <html>
    <head>
        <title>Bookmark plugin configuration options</title>
    </head>
    <body>
    <div style="margin: auto;">
        <div style="margin-bottom: 5%;font-weight: bold;margin: auto;">
            Watson Natural Language Understanding Credentials
        </div>
        <form>
            <table style="margin: auto;">
                <tr>
                    <th>
                        NLU Endpoint:
                    </th>
                    <th>
                        <input type="text" id="nlu_endpoint" style="color:black;padding:2%;width:100%">
                    </th>
                </tr>
                <tr>
                    <th>
                        Username:
                    </th>
                    <th>
                        <input type="text" id="nlu_username" value="apikey" style="color:black;padding:2%;width:100%">
                    </th>
                </tr>
                <tr>
                    <th>
                        Password:
                    </th>
                    <th>
                        <input type="password" id="nlu_password" style="color:black;padding:2%;width:100%">
                    </th>
                </tr>
                <tr>
                    <th>
                    </th>
                    <th>
                        <button id="save_button" style="color:black;padding:2%;">Save</button>
                    </th>
                </tr>
    
            </table>
        </form>
    
        <div id="status"></div>
    </div>
    </body>
    <script src="../jquery.min.js"></script>
    <script src="../routes/options.js"></script>
    </html>
    
  6. To create the pop-up page, open the src/watson-bookmark-plugin/views/popup.html file and copy the following code.

    <html>
     <head>
       <script src="../jquery.min.js"></script>
     </head>
     <body style="width: 400px">
       <div>
           <p id="saving_location"> </p>
           <input id="addLink" type="button" value="Save Bookmark"/>
       </div>
     </body>
     </html>
    
  7. To manage the credentials page, open the src/watson-bookmark-plugin/routes/options.js file and copy the following code.

     function restore_credentials() {
       chrome.storage.local.get({
           nlu_endpoint: "https://api.us-south.natural-language-understanding.watson.cloud.ibm.com/api/v1/analyze",
           nlu_username: "apikey",
           nlu_password: "sample-password"
       }, function(items) {
         document.getElementById('nlu_endpoint').value = items.nlu_endpoint;
         document.getElementById('nlu_username').value = items.nlu_username;
         document.getElementById('nlu_password').value = items.nlu_password;
       });
     }
    
     document.addEventListener('DOMContentLoaded', restore_credentials);
     document.getElementById('save_button').onclick = function() {
         var nlu_endpoint = document.getElementById("nlu_endpoint").value;
         var nlu_username = document.getElementById('nlu_username').value;
         var nlu_password = document.getElementById('nlu_password').value;
    
         chrome.storage.local.set({
             nlu_endpoint: nlu_endpoint,
             nlu_username: nlu_username,
             nlu_password: nlu_password
           }, function() {
             // Update status to let user know options were saved.
             var status = document.getElementById('status');
             status.textContent = 'Options saved!';
             setTimeout(function() {
               status.textContent = '';
           }, 1000);
         });
     }
    
  8. To make calls to the Watson API, we are using jQuery.

Step 3: Test your Chrome extension

  1. Launch Chrome, and go to the extension overview.

  2. Enable Developer mode by clicking Developer mode in the upper-right corner.

  3. Click Load unpacked.

    Loading the unpacked extension

  4. Navigate to the directory containing your unpacked extension, and click Select.

    Navigating to the directory

  5. After loading the directory, you should see that the extension is set to enabled.

  6. You have now successfully installed the plug-in. You should see the plug-in icon in your toolbar.

  7. Configure Watson Natural Language Understanding credentials:

    1. Right-click on the Watson icon on your Google Chrome browser.
    2. Select Options from the menu.
    3. Add your Natural Language Understanding instance password that you created previously.

Usage instructions

For bookmarking, click the icon with Watson symbol (or the icon image you selected) when you go to a website, and it automatically bookmarks the page appropriately. The saved bookmark can then be found under Bookmarks/Other Bookmarks/<Dir structure detected by plug-in>.

Summary

In this tutorial, you’ve successfully created a Google Chrome browser extension that used the IBM Watson Natural Language Understanding API to organize your bookmarks automatically. Enjoy!