1

I am trying to make a chat application project with abusive text detection. I found code for the chat application online and want to add text detection using Perspective API. The API has several attributes for toxicity, threat etc. I am able to set the attributes inside the API function but I am unable to access them outside it.

Here is the relevant code:-

  const sendMessage = asyncHandler(async (req, res) => {
  const { content, chatId } = req.body;

  let toxicity, insult, profanity, threat;

  if (!content || !chatId) {
    console.log("Invalid data passed into request");
    return res.sendStatus(400);
  }

  let newMessage = {
    sender: req.user._id,
    content: content,
    chat: chatId,
    toxicity: toxicity,
    insult: insult,
    profanity: profanity,
    threat: threat,
  };

  let inputText = newMessage.content;

  // Perspective API
  google
    .discoverAPI(process.env.DISCOVERY_URL)
    .then((client) => {
      const analyzeRequest = {
        comment: {
          text: inputText,
        },
        requestedAttributes: {
          TOXICITY: {},
          INSULT: {},
          PROFANITY: {},
          THREAT: {},
        },
      };

      client.comments.analyze(
        {
          key: process.env.API_KEY,
          resource: analyzeRequest,
        },
        (err, response) => {
          if (err) throw err;
          // console.log(JSON.stringify(response.data, null, 2));
          toxicity = (response.data.attributeScores.TOXICITY.summaryScore.value * 100).toFixed(2);
          insult = (response.data.attributeScores.INSULT.summaryScore.value * 100).toFixed(2);
          profanity = (response.data.attributeScores.PROFANITY.summaryScore.value * 100).toFixed(2);
          threat = (response.data.attributeScores.THREAT.summaryScore.value * 100).toFixed(2);

          newMessage.toxicity = toxicity;
          newMessage.insult = insult;
          newMessage.profanity = profanity;
          newMessage.threat = threat;
          console.log("1-" + newMessage.toxicity); // This returns the desired output
        }
      );
    })
    .catch((err) => {
      throw err;
    });
  //

  console.log("2-" + newMessage.toxicity); // This returns undefined

  try {
    let message = await Message.create(newMessage);

    message = await message.populate("sender", "name profilePic");
    message = await message.populate("chat");
    message = await User.populate(message, {
      path: "chat.users",
      select: "name profilePic email",
    });

    await Chat.findByIdAndUpdate(req.body.chatId, {
      latestMessage: message,
    });

    res.json(message);
  } catch (error) {
    res.status(400);
    throw new Error(error.message);
  }
});

I want newMessage to be updated after the API call. After coming across this post, I found that console.log("2-" + newMessage.toxicity) executes before console.log("1-" + newMessage.toxicity). I tried using callbacks and async/await but couldn't make it work.

Sravan
  • 17
  • 7

1 Answers1

1

The console.log("2-" + newMessage.toxicity) is outside the google.discoverAPI call so it execute instantly.

you can try something like this

const sendMessage = asyncHandler(async (req, res) => {
  const { content, chatId } = req.body;

  let toxicity, insult, profanity, threat;

  if (!content || !chatId) {
    console.log("Invalid data passed into request");
    return res.sendStatus(400);
  }

  let newMessage = {
    sender: req.user._id,
    content: content,
    chat: chatId,
    toxicity: toxicity,
    insult: insult,
    profanity: profanity,
    threat: threat,
  };

  let inputText = newMessage.content;

  // Perspective API
  const client = await google
    .discoverAPI(process.env.DISCOVERY_URL)
    
  const analyzeRequest = {
     comment: {
       text: inputText,
    },
    requestedAttributes: {
       TOXICITY: {},
       INSULT: {},
       PROFANITY: {},
       THREAT: {},
      },
    };
    await new Promise((resolve, reject) => {
   
      client.comments.analyze(
        {
          key: process.env.API_KEY,
          resource: analyzeRequest,
        },
        (err, response) => {
          if (err) {
           reject(err)
          }
          
          // console.log(JSON.stringify(response.data, null, 2));
          toxicity = (response.data.attributeScores.TOXICITY.summaryScore.value * 100).toFixed(2);
          insult = (response.data.attributeScores.INSULT.summaryScore.value * 100).toFixed(2);
          profanity = (response.data.attributeScores.PROFANITY.summaryScore.value * 100).toFixed(2);
          threat = (response.data.attributeScores.THREAT.summaryScore.value * 100).toFixed(2);

          newMessage.toxicity = toxicity;
          newMessage.insult = insult;
          newMessage.profanity = profanity;
          newMessage.threat = threat;
          console.log("1-" + newMessage.toxicity);
          resolve()
        }
      );
    })
    .catch((err) => {
      throw err;
    });
  //

  console.log("2-" + newMessage.toxicity); // This returns undefined

  try {
    let message = await Message.create(newMessage);

    message = await message.populate("sender", "name profilePic");
    message = await message.populate("chat");
    message = await User.populate(message, {
      path: "chat.users",
      select: "name profilePic email",
    });

    await Chat.findByIdAndUpdate(req.body.chatId, {
      latestMessage: message,
    });

    res.json(message);
  } catch (error) {
    res.status(400);
    throw new Error(error.message);
  }
});

R4ncid
  • 6,944
  • 1
  • 4
  • 18