Skip to content

Commit

Permalink
🆕 Added support for Customer Care API endpoint for Tone Analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
Shubhanjan Shekhar committed Apr 11, 2017
1 parent b748977 commit 7a5fcfe
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
package com.ibm.watson.developer_cloud.tone_analyzer.v3;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ibm.watson.developer_cloud.http.HttpHeaders;
import com.ibm.watson.developer_cloud.http.HttpMediaType;
import com.ibm.watson.developer_cloud.http.RequestBuilder;
import com.ibm.watson.developer_cloud.http.ServiceCall;
import com.ibm.watson.developer_cloud.service.WatsonService;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneAnalysis;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneOptions;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.UtterancesTone;
import com.ibm.watson.developer_cloud.util.RequestUtils;
import com.ibm.watson.developer_cloud.util.ResponseConverterUtils;
import com.ibm.watson.developer_cloud.util.Validator;
Expand All @@ -35,6 +37,7 @@
public class ToneAnalyzer extends WatsonService {

private static final String PATH_TONE = "/v3/tone";
private static final String PATH_CHAT_TONE = "/v3/tone_chat";
private static final String SERVICE_NAME = "tone_analyzer";
private static final String TEXT = "text";
private static final String URL = "https://gateway.watsonplatform.net/tone-analyzer/api";
Expand Down Expand Up @@ -107,4 +110,21 @@ public ServiceCall<ToneAnalysis> getTone(String text, ToneOptions options) {

return createServiceCall(requestBuilder.build(), ResponseConverterUtils.getObject(ToneAnalysis.class));
}

/**
* Analyzes the "tone" of a list of utterances in a conversation. The text is analyzed from several chat tones, and
* confidence score is given back for tones which are present in the text
*
* @param jsonText The text in JSON format to analyze
* @return the {@link UtterancesTone} with the response
*/
public ServiceCall<UtterancesTone> getChatTone(String jsonText) {
Validator.notNull(jsonText, "text cannot be null");

RequestBuilder requestBuilder = RequestBuilder.post(PATH_CHAT_TONE).query(VERSION_DATE, versionDate);
JsonObject contentJson = new JsonParser().parse(jsonText).getAsJsonObject();
requestBuilder.bodyJson(contentJson);

return createServiceCall(requestBuilder.build(), ResponseConverterUtils.getObject(UtterancesTone.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.ibm.watson.developer_cloud.tone_analyzer.v3.model;

import com.google.gson.annotations.SerializedName;
import com.ibm.watson.developer_cloud.service.model.GenericModel;

import java.util.List;

/**
* This object represents the results of Tone Chat analysis on an utterance. It has the utterance text from the original
* input. It holds a list of scores for individual chat tones.
*/
public class UtteranceAnalysis extends GenericModel {

@SerializedName("id")
int id;

@SerializedName("text")
String text;

List<ToneScore> tones;

/**
* Gets the id.
* @return the id
*/
public int getId() {
return id;
}

/**
* Sets the id.
* @param id the new id
*/
public void setId(int id) {
this.id = id;
}

/**
* Gets the text.
* @return the text
*/
public String getText() {
return text;
}

/**
* Sets the text.
* @param text the new text
*/
public void setText(String text) {
this.text = text;
}

/**
* Gets the chat tones.
* @return the chat tones
*/
public List<ToneScore> getTones() {
return tones;
}

/**
* Sets the chat tones.
* @param tones the new chat tones
*/
public void setTones(List<ToneScore> tones) {
this.tones = tones;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.ibm.watson.developer_cloud.tone_analyzer.v3.model;

import com.google.gson.annotations.SerializedName;
import com.ibm.watson.developer_cloud.service.model.GenericModel;

import java.util.ArrayList;
import java.util.List;

/**
* Main object containing the result of running the Tone Analyzer Chat Analysis on a conversation. It contains a list
* of utterance-level analysis results.
*/
public class UtterancesTone extends GenericModel {

@SerializedName("utterancesTone")
List<UtteranceAnalysis> utterancesTone = new ArrayList<>();

/**
* Gets the utterances tone.
* @return the utterances tone
*/
public List<UtteranceAnalysis> getUtterancesTone() {
return utterancesTone;
}

/**
* Sets the utterances tone.
* @param utterancesTone the new utterances tone
*/
public void setUtterancesTone(List<UtteranceAnalysis> utterancesTone) {
this.utterancesTone = utterancesTone;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.ibm.watson.developer_cloud.WatsonServiceTest;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.Tone;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneAnalysis;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.UtterancesTone;
import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.ToneOptions;

/**
Expand All @@ -34,6 +35,17 @@ public class ToneAnalyzerIT extends WatsonServiceTest {
+ "product suite. We have a competitive data analytics product "
+ "suite in the industry. But we need to do our job selling it! ";

private String jsonText = "{\"utterances\": ["
+ "{\"text\": \"My charger isn't working.\", \"user\": \"customer\"},"
+ "{\"text\": \"Thanks for reaching out. Can you give me some more detail about the issue?\","
+ " \"user\": \"agent\"},"
+ "{\"text\": \"I put my charger in my tablet to charge it up last night and it keeps saying it isn't charging."
+ " The charging icon comes on, but it stays on even when I take the charger out. Which is ridiculous, it's brand"
+ " new.\", \"user\": \"customer\"},"
+ "{\"text\": \"I'm sorry you're having issues with charging. What kind of charger are you using?\","
+ " \"user\": \"agent\"}"
+ " ]}";

/*
* (non-Javadoc)
*
Expand Down Expand Up @@ -86,4 +98,16 @@ private void assertToneAnalysis(ToneAnalysis tone) {
Assert.assertEquals(4, tone.getSentencesTone().size());
Assert.assertEquals("I know the times are difficult!", tone.getSentencesTone().get(0).getText());
}

/**
* Test to get chat tones from jsonText.
*/
@Test
public void testGetChatTone() {
UtterancesTone utterancesTone = service.getChatTone(jsonText).execute();

Assert.assertNotNull(utterancesTone);
Assert.assertEquals(4, utterancesTone.getUtterancesTone().size());
Assert.assertEquals("My charger isn't working.", utterancesTone.getUtterancesTone().get(0).getText());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;

import com.ibm.watson.developer_cloud.tone_analyzer.v3.model.UtterancesTone;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -38,7 +39,9 @@ public class ToneAnalyzerTest extends WatsonServiceUnitTest {

private static final String VERSION_DATE = "version";
private static final String FIXTURE = "src/test/resources/tone_analyzer/tone.json";
private static final String CHAT_FIXTURE = "src/test/resources/tone_analyzer/tone_chat.json";
private static final String TONE_PATH = "/v3/tone";
private static final String CHAT_TONE_PATH = "/v3/tone_chat";

/** The service. */
private ToneAnalyzer service;
Expand Down Expand Up @@ -111,4 +114,41 @@ public void testGetTones() throws InterruptedException, IOException {
path = path + "&tones=emotion,language,social";
assertEquals(path, request.getPath());
}

/**
* Test to get Chat tones.
*
* @throws InterruptedException the interrupted exception
* @throws IOException Signals that an I/O exception has occurred.
*/
@Test
public void testGetChatTones() throws IOException, InterruptedException {
String jsonText = "{\"utterances\": ["
+ "{\"text\": \"My charger isn't working.\", \"user\": \"customer\"},"
+ "{\"text\": \"Thanks for reaching out. Can you give me some more detail about the issue?\","
+ " \"user\": \"agent\"},"
+ "{\"text\": \"I put my charger in my tablet to charge it up last night and it keeps saying it isn't"
+ " charging. The charging icon comes on, but it stays on even when I take the charger out. "
+ "Which is ridiculous, it's brand new.\", \"user\": \"customer\"},"
+ "{\"text\": \"I'm sorry you're having issues with charging. What kind of charger are you using?\","
+ " \"user\": \"agent\"}"
+ " ]}";

UtterancesTone mockResponse = loadFixture(CHAT_FIXTURE, UtterancesTone.class);
server.enqueue(jsonResponse(mockResponse));
server.enqueue(jsonResponse(mockResponse));
server.enqueue(jsonResponse(mockResponse));

// execute request
UtterancesTone serviceResponse = service.getChatTone(jsonText).execute();

// first request
RecordedRequest request = server.takeRequest();

String path = StringUtils.join(CHAT_TONE_PATH, "?", VERSION_DATE, "=", ToneAnalyzer.VERSION_DATE_2016_05_19);
assertEquals(path, request.getPath());
assertNotNull(request.getHeader(HttpHeaders.AUTHORIZATION));
assertEquals(serviceResponse, mockResponse);
assertEquals(HttpMediaType.APPLICATION_JSON, request.getHeader(HttpHeaders.ACCEPT));
}
}
8 changes: 8 additions & 0 deletions tone-analyzer/src/test/resources/tone_analyzer/chat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"utterances": [
{"text": "My charger isn't working.", "user": "customer"},
{"text": "Thanks for reaching out. Can you give me some more detail about the issue?", "user": "agent"},
{"text": "I put my charger in my tablet to charge it up last night and it keeps saying it isn't charging. The charging icon comes on, but it stays on even when I take the charger out. Which is ridiculous, it's brand new.", "user": "customer"},
{"text": "I'm sorry you're having issues with charging. What kind of charger are you using?", "user": "agent"}
]
}
42 changes: 42 additions & 0 deletions tone-analyzer/src/test/resources/tone_analyzer/tone_chat.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"utterances_tone": [
{
"utterance_id": 0,
"utterance_text": "My charger isn't working.",
"tones": [
{
"score": 0.536082,
"tone_id": "sad",
"tone_name": "sad"
}
]
},
{
"utterance_id": 1,
"utterance_text": "Thanks for reaching out. Can you give me some more detail about the issue?",
"tones": [
{
"score": 0.956453,
"tone_id": "polite",
"tone_name": "polite"
}
]
},
{
"utterance_id": 2,
"utterance_text": "I put my charger in my tablet to charge it up last night and it keeps saying it isn't charging. The charging icon comes on, but it stays on even when I take the charger out. Which is ridiculous, it's brand new.",
"tones": []
},
{
"utterance_id": 3,
"utterance_text": "I'm sorry you're having issues with charging. What kind of charger are you using?",
"tones": [
{
"score": 0.856453,
"tone_id": "polite",
"tone_name": "polite"
}
]
}
]
}

0 comments on commit 7a5fcfe

Please sign in to comment.