Product Sentiments

This page explains how to use the Product Sentiments module to retrieve various product sentiments from consumer reviews.

Overview

The Product Sentiments (PS) API lets you extract various product sentiments from consumer reviews. It uses Natural Language Processing (NLP) to identify and extract the following key sentiments:

  • Positive sentiment: Overall favorable opinions and feedback.
  • Negative sentiment: Unfavorable opinions and critiques.
  • Common keywords: Frequently used terms and phrases by consumers.
  • High-quality marketing quotes: Powerful statements suitable for promotional materials and campaigns.

Tip:

To learn more about PS API, refer to Product Sentiments API.

Functionality

The PS API provides the following five independent API functionalities:

  1. Retrieve Summarized Features: Provides a list of the product's best and worst features, along with quotes, that the consumers used in their reviews to describe the product.
  2. Retrieve Quotes for Summarized Features: Provides quotes for a specific feature based on the language provided which are English, French, German, and Spanish.
  3. Retrieve Features: Provides a comprehensive list of Keywords that consumers commonly use to describe the product in their reviews.
  4. Retrieve Quotes: Provides a high-quality marketing quotes about the product. By default, five quotes are provided.
  5. Retrieve Expressions: Provides all expressions related to a product based on the provided productId, clientId, and feature. Currently, this functionality only supports English (en).

Configuration

All the above listed PS APIs require configuration. Ensure the API call contains both client id and API key.

The codes below demonstrate how to configure PS API for Android mobile environment:

private static var config: BVProductSentimentsConfiguration = {
    let analyticsConfig: BVAnalyticsConfiguration = .dryRun(configType: .production(clientId: "client_id"))
    return BVProductSentimentsConfiguration.display(
        clientKey: "api_key",
        configType: .production(clientId: "client_id"),
        analyticsConfig: analyticsConfig
    )
}()
let configurationDictionary = ["clientId": "client_id",
                               "apiKeyProductSentiments": "api_key"];
BVSDKManager.configure(withConfiguration: configurationDictionary, configType: .prod)

Retrieve summarized features

The codes below demonstrate how to configure Retrieve Summarized Features API:

let query = BVSummarisedFeaturesQuery(productId: "product_id")
            .embed(.quotes)
            .language("en")
            .configure(config)
            .handler { (response: BVProductSentimentsQueryResponse<BVSummarisedFeatures>) in
                
                if case let .failure(errors) = response {
                    print(errors)
                    errors.forEach { (error: Error) in
                        guard let bverror: BVError = error as? BVError
                        else {
                            return
                        }
                        print(bverror.message)
                    }
                    return
                }
                
                guard case let .success(result) = response else {return}
                guard let status = result.status, 
                        let sentimentsError = 
                        BVProductSentimentsError("\(status)", message: result.detail)
                else {
                    guard let bestFeatures = result.bestFeatures else {return}
                    for bestFeature in bestFeatures {
                        print(bestFeature.feature)
                        print(bestFeature.averageRatingReviews?.positive)
                        guard let quotes = bestFeature.embedded?.quotes else {return}
                        guard let firstQuote = quotes.first else {return}
                        print(firstQuote.text)
                    }


                    guard let worstFeatures = result.worstFeatures else {return}
                    print(worstFeatures.count)
                    return
                }
                print(sentimentsError.localizedDescription)
            }
let request = BVSummarisedFeaturesRequest(productId: "product_id", language: "en", embed: "quotes")
        request.load({ response in
            guard let bestFeatures = response.result.bestFeatures else {
                print("No feature received")
                return
            }
            for bestFeature in bestFeatures {
                print(bestFeature.feature ?? "")
                print(bestFeature.averageRatingReviews?.positive ?? 0)
                guard let quotes = bestFeature.embedded?.quotes, let firstQuoteText = quotes.first?.text else {return}
                print(firstQuoteText)
            }
        }) { (errors) in
            for error in errors {
                let sentimentsError = (error as NSError).bvProductSentimentsErrorCode()
		   print(sentimentsError)
                print("product sentiments request error: \(error.localizedDescription)")
            }
          } 
#import <Foundation/Foundation.h>
#import "BVSummarisedFeaturesRequest.h"

BVSummarisedFeaturesRequest *request = [[BVSummarisedFeaturesRequest alloc] initWithProductId:@"product_id" language:@"en" embed:@"quotes"];

[request load:^(BVSummarisedFeaturesResponse *response) {
    NSArray *bestFeatures = response.result.bestFeatures;
    if (bestFeatures == nil) {
        NSLog(@"No features were received.");
        return;
    }
    for (BVBestsFeature *bestFeature in bestFeatures) {
        NSLog(@"Feature: %@", bestFeature.feature ? bestFeature.feature : @"");
        NSLog(@"Positive Reviews: %ld", (long)(bestFeature.averageRatingReviews.positive ? bestFeature.averageRatingReviews.positive : 0));
        NSArray *quotes = bestFeature.embedded.quotes;
        if (quotes != nil && quotes.count > 0) {
            NSString *firstQuoteText = quotes.text;
            NSLog(@"First Quote: %@", firstQuoteText);
        }
    }
} error:^(NSArray *errors) {
    for (NSError *error in errors) {
        NSInteger sentimentsError = [error bvProductSentimentsErrorCode];
        NSLog(@"Sentiment Error Code: %ld", (long)sentimentsError);
        NSLog(@"Product sentiments request error: %@", error.localizedDescription);
    }
}];

Retrieve quotes for summarized features

The codes below demonstrate how to configure Retrieve Quotes for Summarized Features API:

let query = BVSummarisedFeaturesQuotesQuery(productId: "product_id", featureId: "feature_id", limit: 10)
            .language("en")
            .configure(config)
            .handler { (response: BVProductSentimentsQueryResponse<BVQuotes>) in
                
                if case let .failure(errors) = response {
                    print(errors)
                    errors.forEach { (error: Error) in
                        guard let bverror: BVError = error as? BVError else {return}
                        print(bverror.message)
                    }
                    return
                }
                
                guard case let .success(result) = response
                else {return}
                guard let status = result.status,
                      let sentimentsError = BVProductSentimentsError("\(status)", message: result.detail)
                else {
                    guard let quotes = result.quotes else {
                        print("No quotes for the product.")
                        return
                    }
                    print(quotes.count)
                    for quote in quotes {
                        print(quote.text)
                    }
                }
                print(sentimentsError.localizedDescription)
            }
       let request = BVSummarisedFeaturesQuotesRequest(productId: "product_id", featureId: "feature_id", language: "en", limit: 10)
        request.load({ response in
            guard let quotes = response.result.quotes else {
                print("No quotes to display")
                return
            }
            for quote in quotes {
                print(quote.text ?? "")
            }
        }) { (errors) in
            for error in errors {
                let sentimentsError = (error as NSError).bvProductSentimentsErrorCode()
                print(sentimentsError)
                print("product sentiments request error: \(error.localizedDescription)")
            }
          }
#import <Foundation/Foundation.h>
#import "BVSummarisedFeaturesQuotesRequest.h"

BVSummarisedFeaturesQuotesRequest *request = [[BVSummarisedFeaturesQuotesRequest alloc] initWithProductId:@"product_id" featureId:@"feature_id" language:@"en" limit:10];

[request load:^(BVSummarisedFeaturesQuotesResponse *response) {
    NSArray *quotes = response.result.quotes;

    if (quotes == nil) {
        NSLog(@"No quotes to display");
        return;
    }

    for (BVSummarisedFeatureQuote *quote in quotes) {
        NSLog(@"%@", quote.text ?: @"");
    }
} error:^(NSArray *errors) {
    for (NSError *error in errors) {
        NSInteger sentimentsError = [error bvProductSentimentsErrorCode];
        NSLog(@"%ld", (long)sentimentsError);
        NSLog(@"Product sentiments request error: %@", error.localizedDescription);
    }
}];

Retrieve features

The codes below demonstrate how to configure Retrieve Features API:

     let query = BVProductFeaturesQuery(productId: "product_id", limit: 10)
            .language("en")
            .configure(config)
            .handler { (response: BVProductSentimentsQueryResponse<BVProductFeatures>) in
                
                if case let .failure(errors) = response {
                    print(errors)
                    errors.forEach { (error: Error) in
                        guard let bverror: BVError = error as? BVError else {return}
                        print(bverror.message)
                    }
                    return
                }
                
                guard case let .success(result) = response else {return}
                guard let status = result.status,
                      let sentimentsError = BVProductSentimentsError("\(status)", message: result.detail)
                else {
                    guard let features = result.features else {
                        print("No features for product")
                        return
                    }
                    for feature in features {
                        print(feature.feature)
                        print(feature.nativeFeature)
                    }
                    return
                }
                print(sentimentsError.localizedDescription)
            }
        let request = BVProductFeaturesRequest(productId: "product_id", language: "en", limit: 10)
        request.load({ response in
            guard let features = response.result.features else {
                print("No features for product")
                return
            }
            for feature in features {
                print(feature.feature ?? "")
                print(feature.nativeFeature ?? "")
            }
        }) { (errors) in
            for error in errors {
                let sentimentsError = (error as NSError).bvProductSentimentsErrorCode()
                print(sentimentsError)
                print("product sentiments request error: \(error.localizedDescription)")
            }
          }
#import <Foundation/Foundation.h>
#import "BVProductFeaturesRequest.h"

BVProductFeaturesRequest *request = [[BVProductFeaturesRequest alloc] initWithProductId:@"product_id" language:@"en" limit:10];

[request load:^(BVProductFeaturesResponse *response) {
    NSArray *features = response.result.features;
    if (features == nil) {
        NSLog(@"No features found for the specified product.");
        return;
    }
    for (BVFeature *feature in features) {
        NSLog(@"%@", feature.feature ?: @"");
        NSLog(@"%@", feature.nativeFeature ?: @"");
    }
} error:^(NSArray *errors) {
    for (NSError *error in errors) {
        NSInteger sentimentsError = [error bvProductSentimentsErrorCode];
        NSLog(@"%ld", (long)sentimentsError);
        NSLog(@"Product sentiments request error: %@", error.localizedDescription);
    }
}];

Retrieve quotes

The codes below demonstrate how to configure Retrieve Quotes API:

let query = BVProductQuotesQuery(productId: "product_id", limit: 10)
            .language("en")
            .configure(config)
            .handler { (response: BVProductSentimentsQueryResponse<BVQuotes>) in
                
                if case let .failure(errors) = response {
                    print(errors)
                    errors.forEach { (error: Error) in
                        guard let bverror: BVError = error as? BVError else {return}
                        print(bverror.message)
                    }
                    return
                }
                
                guard case let .success(result) = response else {return}
                guard let status = result.status,
                      let sentimentsError = BVProductSentimentsError("\(status)", message: result.detail)
                else {
                    guard let quotes = result.quotes else {return}
                    for quote in quotes {
                        print(quote.text)
                    }
                    return
                }
                print(sentimentsError.localizedDescription)
            }
      let request = BVProductQuotesRequest(productId: "product_id", language: "en", limit: 10)
        request.load({ response in
            guard let quotes = response.result.quotes else {
                print("No quotes for product")
                return
            }
            for quote in quotes {
                print(quote.text ?? "")
            }
        }) { (errors) in
            for error in errors {
                let sentimentsError = (error as NSError).bvProductSentimentsErrorCode()
                print(sentimentsError)
                print("product sentiments request error: \(error)")
            }
          }
#import <Foundation/Foundation.h>
#import "BVProductQuotesRequest.h"

BVProductQuotesRequest *request = [[BVProductQuotesRequest alloc] initWithProductId:@"product_id" language:@"en" limit:10];

[request load:^(BVProductQuotesResponse *response) {
    NSArray *quotes = response.result.quotes;

    if (quotes == nil) {
        NSLog(@"No quotes for product");
        return;
    }

    for (BVQuote *quote in quotes) {
        NSLog(@"%@", quote.text ? quote.text : @"");
    }
} error:^(NSArray *errors) {
    for (NSError *error in errors) {
        NSInteger sentimentsError = [error bvProductSentimentsErrorCode];
        NSLog(@"%ld", (long)sentimentsError);
        NSLog(@"product sentiments request error: %@", error);
    }
}];

Retrieve expressions

The codes below demonstrate how to configure Retrieve Expressions API:

     let query = BVProductExpressionsQuery(productId: "product_id", feature: "some_feature", limit: 10)
            .language("en")
            .configure(config)
            .handler { (response: BVProductSentimentsQueryResponse<BVExpressions>) in
                
                if case let .failure(errors) = response {
                    print(errors)
                    errors.forEach { (error: Error) in
                        guard let bverror: BVError = error as? BVError else {return}
                        print(bverror.message)
                    }
                    return
                }
                
                guard case let .success(result) = response else {return}
                guard let status = result.status,
                      let sentimentsError = BVProductSentimentsError("\(status)", message: result.detail)
                else {
                    guard let expressions = result.expressions else {
                        print("No expression for product.")
                    }
                    for expression in expressions {
                        print(expression)
                    }
                    return
                }
                print(sentimentsError.localizedDescription)
            }
      let request = BVProductExpressionsRequest(productId: "product_id", feature: "some_feature", language: "en", limit: 10)
        request.load({ response in
            guard let expressions = response.result.expressions else {
                print("No expressions for product")
                return
            }
            for expression in expressions {
                print(expression)
            }
        }) { (errors) in
            for error in errors {
                let sentimentsError = (error as NSError).bvProductSentimentsErrorCode()
                print(sentimentsError)
                print("product sentiments request error: \(error)")
            }
          }
import <Foundation/Foundation.h>
#import "BVProductExpressionsRequest.h"

BVProductExpressionsRequest *request = [[BVProductExpressionsRequest alloc] initWithProductId:@"product_id" feature:@"some_feature" language:@"en" limit:10];

[request load:^(BVProductExpressionsResponse *response) {
    NSArray *expressions = response.result.expressions;
    if (expressions == nil) {
        NSLog(@"No expressions found for the specified product.");
        return;
    }
    for (NSString *expression in expressions) {
        NSLog(@"%@", expression);
    }
} error:^(NSArray<NSError *> *errors) {
    for (NSError *error in errors) {
        NSInteger sentimentsError = [error bvProductSentimentsErrorCode];
        NSLog(@"%ld", (long)sentimentsError);
        NSLog(@"Product sentiments request encountered an error: %@", error);
    }
}];