The Natural Language API is a pretrained machine learning model that can analyze syntax, extract entities, and evaluate the sentiment of text. It can called from Google Docs to perform all of these functions.

This codelab will walk you through calling the Natural Language API to recognize the sentiment of selected text in a Google Doc and highlight it based on that sentiment.

What are we going to be building?

Once this codelab is complete, you will be able to select text in a document and mark its sentiment, using a menu choice, as shown below.

Text will be highlighted in red for negative sentiment, green for positive sentiment, and yellow for neutral sentiment.

What you'll learn

What you'll need

This codelab is focused on calling the Natural Language API from Google Docs. Non-relevant concepts and code blocks are glossed over and are provided for you to simply copy and paste.

Self-paced environment setup

  1. If you don't already have a Google Account (Gmail or Google Apps), you must create one.
  2. Sign-in to Google Cloud Platform console (console.cloud.google.com) and create a new project:

  1. Next, you'll need to enable billing in the Developers Console in order to use Google Cloud resources like the Natural Language API. There should be no charge for using Google Cloud Platform during this codelab since the first 5,000 calls of the Natural Language API each month are free.

New users of Google Cloud Platform are eligible for a $300 free trial.

Log into the Google Cloud Console from a browser tab/window, at https://console.cloud.google.com.

Here's what you should see once logged in :

Enable the Natural Language API

Enable the Natural Language API by selecting Enable API at the top of the dashboard and selecting the Natural Language API.

Get API key

We'll need to generate an API key to pass in our request URL.

To create an API key, navigate to the API Manager section of your project dashboard:

Next, navigate to the Credentials tab and click Create credentials:

In the drop down menu, select API key:

Copy the API key you are given to a text file or a Google Doc to use in a later step. Once you have the API key you are ready to move into Google Docs.

Before you can call the Natural Language API, you'll need to have an Apps Script program to create the menu, link it to a function to mark the text, and extract the text from the user selection.

/**
* @OnlyCurrentDoc
*
* The above comment directs Apps Script to limit the scope of file
* access for this add-on. It specifies that this add-on will only
* attempt to read or modify the files in which the add-on is used,
* and not all of the user's files. The authorization request message
* presented to users will reflect this limited scope.
*/


/**
* Creates a menu entry in the Google Docs UI when the document is
* opened.
* 
*/
function onOpen() {
  var ui = DocumentApp.getUi();
  
  ui.createMenu('Natural Language Tools')
    .addItem('Mark Sentiment', 'markSentiment')
    .addToUi();
}
/**
* Gets the user-selected text and highlights it based on sentiment 
* with green for positive sentiment, red for negative, and yellow 
* for neutral.
* 
*/
function markSentiment() {
  var POSITIVE_COLOR = '#00ff00';  //  Colors for sentiments
  var NEGATIVE_COLOR = '#ff0000';
  var NEUTRAL_COLOR = '#ffff00';
  var NEGATIVE_CUTOFF = -0.2;   //  Thresholds for sentiments
  var POSITIVE_CUTOFF = 0.2;
  
  var selection = DocumentApp.getActiveDocument().getSelection();
  if (selection) {
    var string = getSelectedText();
    
    var sentiment = retrieveSentiment(string);
  
    //  Select the appropriate color   
    var color = NEUTRAL_COLOR;
    if (sentiment <= NEGATIVE_CUTOFF) {
      color = NEGATIVE_COLOR;
    }
    if (sentiment >= POSITIVE_CUTOFF) {
      color = POSITIVE_COLOR;
    }
    
    //  Highlight the text 
    var elements = selection.getSelectedElements();
    for (var i = 0; i < elements.length; i++) {
      if (elements[i].isPartial()) {
        var element = elements[i].getElement().editAsText();
        var startIndex = elements[i].getStartOffset();
        var endIndex = elements[i].getEndOffsetInclusive();
        element.setBackgroundColor(startIndex, endIndex, color);
  
      } else {
        var element = elements[i].getElement().editAsText();
        foundText = elements[i].getElement().editAsText();
        foundText.setBackgroundColor(color);
      } 
    }
  }
}
/**
 * Returns a string with the contents of the selected text.
 * If no text is selected, returns an empty string.
 */
function getSelectedText() {
  var selection = DocumentApp.getActiveDocument().getSelection();
  var string = "";
  if (selection) {
    var elements = selection.getSelectedElements();
    
    for (var i = 0; i < elements.length; i++) {
      if (elements[i].isPartial()) {
        var element = elements[i].getElement().asText();
        var startIndex = elements[i].getStartOffset();
        var endIndex = elements[i].getEndOffsetInclusive() + 1;
        var text = element.getText().substring(startIndex, endIndex);
        string = string + text;
        
      } else {
        var element = elements[i].getElement();
        // Only translate elements that can be edited as text; skip
        // images and other non-text elements.
        if (element.editAsText) {
          string = string + element.asText().getText();
        }
      }
    }
  }
  return string;
}

/** Given a string, will call the Natural Language API and retrieve 
  * the sentiment of the string.  The sentiment will be a real 
  * number in the range -1 to 1, where -1 is highly negative 
  * sentiment and 1 is highly positive.
*/
function retrieveSentiment (line) {
//  TODO:  Call the Natural Language API with the line given
//         and return the sentiment value. 
  return 0.0;
}

Once your program can extract text from the selection and highlight it, it's time to call the Natural Language API. All of this will be done in the body of the retrieveSentiment function.

Return to the Tools -> Script Editor in Google Docs.

In the retrieveSentiment function:

  var apiKey = "your key here";
var apiEndpoint = 
'https://language.googleapis.com/v1/documents:analyzeSentiment?key=' 
+ apiKey;
  var docDetails = {
    language: 'en-us',
    type: 'PLAIN_TEXT',
    content: line
  };
  var nlData = {
    document: docDetails,
    encodingType: 'UTF8'
  };
  var nlOptions = {
    method : 'post',
    contentType: 'application/json',
    payload : JSON.stringify(nlData)
  };
  var response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
  var data = JSON.parse(response);
  
  var sentiment = 0.0;
  //  Ensure all pieces were in the returned value
  if (data && data.documentSentiment 
          && data.documentSentiment.score){
     sentiment = data.documentSentiment.score;
  }
  
  return sentiment;

The complete code to retrieve the sentiment is below.

function retrieveSentiment (line) {
  var apiKey = "your key here";
  var apiEndpoint = 
'https://language.googleapis.com/v1/documents:analyzeSentiment?key=' 
+ apiKey;

  //  Create a structure with the text, its language, its type,
  //  and its encoding
  var docDetails = {
    language: 'en-us',
    type: 'PLAIN_TEXT',
    content: line
  };
  
  var nlData = {
    document: docDetails,
    encodingType: 'UTF8'
  };
  
  //  Package all of the options and the data together for the call
  var nlOptions = {
    method : 'post',
    contentType: 'application/json',
    payload : JSON.stringify(nlData)
  };
  
  //  And make the call
  var response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
  
  var data = JSON.parse(response);
  
  var sentiment = 0.0;
  //  Ensure all pieces were in the returned value
  if (data && data.documentSentiment 
          && data.documentSentiment.score){
     sentiment = data.documentSentiment.score;
  }
  
  return sentiment;
}

Save your script, reload the document, and try out the full program. You may need to re-authorize with your credentials to enable the new functionality. Select different sections of your document to see how the sentiment may differ over its parts.

You've created a Google Doc and called the Natural Language API to analyze the sentiment of selected portions of the document.

If you are done with this example, return to the Credentials section of the Google Cloud Console and delete the API key to ensure it is not used elsewhere.