Files
talk/plugins/talk-plugin-toxic-comments/server/hooks.js
T
2018-11-06 12:39:16 -07:00

120 lines
3.2 KiB
JavaScript

const { getScores, submitFeedback, isToxic } = require('./perspective');
const { SEND_FEEDBACK } = require('./config');
const { ErrToxic } = require('./errors');
const { merge } = require('lodash');
const debug = require('debug')('talk:plugin:toxic-comments');
function handlePositiveToxic(input) {
input.status = 'SYSTEM_WITHHELD';
input.actions =
input.actions && input.actions.length >= 0 ? input.actions : [];
input.actions.push({
action_type: 'FLAG',
user_id: null,
group_id: 'TOXIC_COMMENT',
metadata: {},
});
}
async function getScore(body) {
// Try getting scores.
let scores;
try {
scores = await getScores(body);
} catch (err) {
// Warn and let mutation pass.
debug('Error sending to API: %o', err);
return;
}
return scores;
}
// Create all the hooks that will enable Perspective to add scores to Comments.
const hooks = {
RootMutation: {
editComment: {
pre: async (_, { edit: { body }, edit }) => {
const scores = await getScore(body);
if (isToxic(scores)) {
handlePositiveToxic(edit);
}
},
},
createComment: {
async pre(_, { input }, _context, _info) {
const scores = await getScore(input.body);
if (isToxic(scores)) {
if (input.checkToxicity) {
throw new ErrToxic();
}
// Mark the comment as positive toxic.
handlePositiveToxic(input);
}
// Attach scores to metadata.
input.metadata = Object.assign({}, input.metadata, {
perspective: scores,
});
},
},
},
};
// If feedback sending is enabled, we need to add in the hooks for processing
// feedback.
if (SEND_FEEDBACK) {
// statusMap provides a map of Talk names to ones Perspective are expecting.
const statusMap = {
ACCEPTED: 'APPROVED',
REJECTED: 'DELETED',
};
// Merge these hooks into the hooks for plugging into the graph operations.
merge(hooks, {
RootMutation: {
// Hook into mutations associated with accepting/rejecting comments.
setCommentStatus: {
async post(root, args, ctx) {
if (ctx.user && args.status in statusMap) {
const comment = await ctx.loaders.Comments.get.load(args.id);
if (comment) {
const asset = await ctx.loaders.Assets.getByID.load(
comment.asset_id
);
// Submit feedback.
submitFeedback(comment, asset, statusMap[args.status]);
}
}
},
},
// Hook into mutations associated with featuring comments.
addTag: {
async post(root, args, ctx) {
if (
ctx.user &&
args.tag.name === 'FEATURED' &&
args.tag.item_type === 'COMMENTS'
) {
const comment = await ctx.loaders.Comments.get.load(args.tag.id);
if (comment) {
const asset = await ctx.loaders.Assets.getByID.load(
comment.asset_id
);
// Submit feedback.
submitFeedback(comment, asset, 'HIGHLIGHTED');
}
}
},
},
},
});
}
module.exports = hooks;