2023-01-27 03:22:44 -08:00
import type {
2023-03-09 09:13:15 -08:00
IExecuteFunctions ,
2021-08-01 04:27:57 -07:00
ILoadOptionsFunctions ,
INodeExecutionData ,
INodePropertyOptions ,
INodeType ,
INodeTypeDescription ,
2023-02-27 19:39:43 -08:00
JsonObject ,
2021-08-01 04:27:57 -07:00
} from 'n8n-workflow' ;
2023-01-27 03:22:44 -08:00
import { NodeOperationError } from 'n8n-workflow' ;
2021-08-01 04:27:57 -07:00
2023-01-13 09:11:56 -08:00
import ISO6391 from 'iso-639-1' ;
2023-01-27 03:22:44 -08:00
import type {
AttributesValuesUi ,
CommentAnalyzeBody ,
Language ,
RequestedAttributes ,
} from './types' ;
2021-08-01 04:27:57 -07:00
2022-08-17 08:50:24 -07:00
import { googleApiRequest } from './GenericFunctions' ;
2021-08-01 04:27:57 -07:00
export class GooglePerspective implements INodeType {
description : INodeTypeDescription = {
displayName : 'Google Perspective' ,
name : 'googlePerspective' ,
2024-06-06 04:34:30 -07:00
icon : { light : 'file:googlePerspective.svg' , dark : 'file:googlePerspective.dark.svg' } ,
2022-08-17 08:50:24 -07:00
group : [ 'transform' ] ,
2021-08-01 04:27:57 -07:00
version : 1 ,
description : 'Consume Google Perspective API' ,
subtitle : '={{$parameter["operation"]}}' ,
defaults : {
name : 'Google Perspective' ,
} ,
2022-08-17 08:50:24 -07:00
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
2021-08-01 04:27:57 -07:00
credentials : [
{
name : 'googlePerspectiveOAuth2Api' ,
required : true ,
} ,
] ,
properties : [
{
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
2022-05-20 14:47:24 -07:00
noDataExpression : true ,
2021-08-01 04:27:57 -07:00
options : [
{
name : 'Analyze Comment' ,
value : 'analyzeComment' ,
} ,
] ,
default : 'analyzeComment' ,
} ,
{
displayName : 'Text' ,
name : 'text' ,
type : 'string' ,
default : '' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
operation : [ 'analyzeComment' ] ,
2021-08-01 04:27:57 -07:00
} ,
} ,
} ,
{
displayName : 'Attributes to Analyze' ,
name : 'requestedAttributesUi' ,
type : 'fixedCollection' ,
2022-04-22 09:29:51 -07:00
default : { } ,
2021-08-01 04:27:57 -07:00
typeOptions : {
multipleValues : true ,
} ,
placeholder : 'Add Atrribute' ,
required : true ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
operation : [ 'analyzeComment' ] ,
2021-08-01 04:27:57 -07:00
} ,
} ,
options : [
{
displayName : 'Properties' ,
name : 'requestedAttributesValues' ,
values : [
{
displayName : 'Attribute Name' ,
name : 'attributeName' ,
type : 'options' ,
options : [
{
name : 'Flirtation' ,
value : 'flirtation' ,
} ,
{
name : 'Identity Attack' ,
value : 'identity_attack' ,
} ,
{
name : 'Insult' ,
value : 'insult' ,
} ,
{
name : 'Profanity' ,
value : 'profanity' ,
} ,
{
name : 'Severe Toxicity' ,
value : 'severe_toxicity' ,
} ,
{
name : 'Sexually Explicit' ,
value : 'sexually_explicit' ,
} ,
{
name : 'Threat' ,
value : 'threat' ,
} ,
{
name : 'Toxicity' ,
value : 'toxicity' ,
} ,
] ,
2022-08-17 08:50:24 -07:00
description :
'Attribute to analyze in the text. Details <a href="https://developers.perspectiveapi.com/s/about-the-api-attributes-and-languages">here</a>.' ,
2021-08-01 04:27:57 -07:00
default : 'flirtation' ,
} ,
{
displayName : 'Score Threshold' ,
name : 'scoreThreshold' ,
type : 'number' ,
typeOptions : {
numberPrecision : 2 ,
minValue : 0 ,
maxValue : 1 ,
} ,
2022-08-17 08:50:24 -07:00
description :
'Score above which to return results. At zero, all scores are returned.' ,
2021-08-01 04:27:57 -07:00
default : 0 ,
} ,
] ,
} ,
] ,
} ,
{
displayName : 'Options' ,
name : 'options' ,
type : 'collection' ,
displayOptions : {
show : {
2022-08-17 08:50:24 -07:00
operation : [ 'analyzeComment' ] ,
2021-08-01 04:27:57 -07:00
} ,
} ,
default : { } ,
2024-07-29 05:27:23 -07:00
placeholder : 'Add option' ,
2021-08-01 04:27:57 -07:00
options : [
{
2022-06-03 10:23:49 -07:00
displayName : 'Language Name or ID' ,
2021-08-01 04:27:57 -07:00
name : 'languages' ,
type : 'options' ,
typeOptions : {
loadOptionsMethod : 'getLanguages' ,
} ,
default : '' ,
2022-08-17 08:50:24 -07:00
description :
'Languages of the text input. If unspecified, the API will auto-detect the comment language. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.' ,
2021-08-01 04:27:57 -07:00
} ,
] ,
} ,
] ,
} ;
methods = {
loadOptions : {
2023-04-19 07:00:49 -07:00
// Get all the available languages to display them to user so that they can
2021-08-01 04:27:57 -07:00
// select them easily
async getLanguages ( this : ILoadOptionsFunctions ) : Promise < INodePropertyOptions [ ] > {
const returnData : INodePropertyOptions [ ] = [ ] ;
const supportedLanguages = [
'English' ,
'Spanish' ,
'French' ,
'German' ,
'Portuguese' ,
'Italian' ,
'Russian' ,
] ;
2022-08-17 08:50:24 -07:00
const languages = ISO6391 . getAllNames ( ) . filter ( ( language : string ) = >
supportedLanguages . includes ( language ) ,
) ;
2021-08-01 04:27:57 -07:00
for ( const language of languages ) {
const languageName = language ;
const languageId = ISO6391 . getCode ( language ) ;
returnData . push ( {
name : languageName ,
value : languageId ,
} ) ;
}
return returnData ;
} ,
} ,
} ;
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [ ] [ ] > {
const items = this . getInputData ( ) ;
const operation = this . getNodeParameter ( 'operation' , 0 ) ;
2022-08-30 08:55:33 -07:00
const returnData : INodeExecutionData [ ] = [ ] ;
2021-08-01 04:27:57 -07:00
let responseData ;
for ( let i = 0 ; i < items . length ; i ++ ) {
try {
if ( operation === 'analyzeComment' ) {
// https://developers.perspectiveapi.com/s/about-the-api-methods
const attributes = this . getNodeParameter (
2022-08-17 08:50:24 -07:00
'requestedAttributesUi.requestedAttributesValues' ,
i ,
[ ] ,
2021-08-01 04:27:57 -07:00
) as AttributesValuesUi [ ] ;
if ( ! attributes . length ) {
throw new NodeOperationError (
this . getNode ( ) ,
2022-08-17 08:50:24 -07:00
'Please enter at least one attribute to analyze.' ,
{ itemIndex : i } ,
2021-08-01 04:27:57 -07:00
) ;
}
const requestedAttributes = attributes . reduce < RequestedAttributes > ( ( acc , cur ) = > {
return Object . assign ( acc , {
[ cur . attributeName . toUpperCase ( ) ] : {
scoreType : 'probability' ,
scoreThreshold : cur.scoreThreshold ,
} ,
} ) ;
} , { } ) ;
const body : CommentAnalyzeBody = {
comment : {
type : 'PLAIN_TEXT' ,
text : this.getNodeParameter ( 'text' , i ) as string ,
} ,
requestedAttributes ,
} ;
const { languages } = this . getNodeParameter ( 'options' , i ) as { languages : Language } ;
if ( languages ? . length ) {
body . languages = languages ;
}
2022-08-17 08:50:24 -07:00
responseData = await googleApiRequest . call (
this ,
'POST' ,
'/v1alpha1/comments:analyze' ,
body ,
) ;
2021-08-01 04:27:57 -07:00
}
} catch ( error ) {
2024-06-19 22:45:00 -07:00
if ( this . continueOnFail ( error ) ) {
2022-08-30 08:55:33 -07:00
const executionErrorData = this . helpers . constructExecutionMetaData (
this . helpers . returnJsonArray ( { error : error.message } ) ,
{ itemData : { item : i } } ,
) ;
returnData . push ( . . . executionErrorData ) ;
2021-08-01 04:27:57 -07:00
continue ;
}
throw error ;
}
2022-08-30 08:55:33 -07:00
const executionData = this . helpers . constructExecutionMetaData (
2023-02-27 19:39:43 -08:00
this . helpers . returnJsonArray ( responseData as JsonObject ) ,
2022-08-30 08:55:33 -07:00
{ itemData : { item : i } } ,
) ;
returnData . push ( . . . executionData ) ;
2021-08-01 04:27:57 -07:00
}
2023-09-05 03:59:02 -07:00
return [ returnData ] ;
2021-08-01 04:27:57 -07:00
}
}