New Community Plugin: Content Moderation

Shada - Feb 17 '22 - - Dev Community

About the plugin

image3.png

Our plugin is a powerful Strapi-based comments moderation tool for you and your users, covering user-moderator flow end to end with its dedicated panel, bad words filtering, abuse reporting, comprehensive Public REST API & GraphQL coverage, and much more.

Comments Public REST + GraphQL API: Elegant, entirely customizable, and fully extensible admin panel.
Strapi & generic users: Support for built-in & also generic non-Strapi users that might be the comment authors.
Any Content Type relation: Comments can be linked to any of your Content Types by default. Simply, you're controlling it.
Moderation Panel: Search & Filter through the bucket with your auditory comments. Manage them by blocking single ones or entire threads. All in the combined list & hierarchical tree view of threads.
Automated Bad Words filtering: By default, end users cannot post abusive comments where bad words have been used.
Abuse Reporting & Reviewing: Don't allow inferior language, react to reports from your community, send email notifications about abuse reports

Why we built it

As in most cases, plugin implementation is an outcome of business requirements. It wasn't different in our case, but the origin of requirements was quite specific. In late 2020, while working with one of our strategic clients - a leading global retailer company - we started researching alternatives to existing CMS as part of the digital transformation services we've been providing. One of the criteria was having built-in functionality or the possibility to fast implement an extension, where Strapi becomes a leader and stays in this position till the end.

But back to the plugin itself. As part of the mentioned research, the first version of Strapi v3 was implemented in 5 nights of crunching by myself, where I've proved all requirements are fulfilled with significantly lower effort than other solutions. That was a lot of fun as being in a manager position, I was keeping myself away from coding ^^

I've published it and involved my team in the maintenance and future development. We've received a lot of positive community feedback and decided to commit to it permanently.

Just over a year after, Strapi v4 was released, and here I set myself almost the same challenge. So I re-implemented all the lessons learned with v3 in the new version - using the Plugin API and a fancy design system in cooperation with the Strapi Team. Now it's done!

How it works under the hood

Compared to version 1.x, the newest 2.x is the full re-implementation, not a simple migration. It has been designed and implemented to have the most flexibility possible using Plugin API, and we've made a small step back in the approach to linking comments with Collection Types. Previously we based these on Polymorphic relations, which were complex and problematic for plugin users to configure and maintain. The new version has been made entirely without it, now linking is fully managed by the plugin itself, without configuring anything via JSON schema or Content-Type Builder.

Version 2.x provides the most recent features we implemented for 1.x, like GraphQL support and comments approval process.

The first one is entirely based on abilities exposed by the default (also redesigned) Public REST API, allowing your client application users to create/modify/delete/report issues against comments. Everything with GQL flavor and custom dedicated content types + ability to filter. Simply, you don't need to choose between REST or GQL; both are the same in terms of exposed functionality.

image1.png

Mentioned approval flow was one of the community wanted and most recently introduced functionality, but we did it now much more straightforward. Moreover, the new version doesn't require any work on the Collection Types end; by the simple plugin config entry, you're controlling which Collections should contain such flow and which not.

image4.png

The same approach has been used for rendering entities titles, ordered set of parameters per Collection, simple isn't it? There are, of course, some defaults, so most probably, you don't need to do anything with it.

Last but not least, bad word filtering, the same package used to do it as it fulfills your needs in the previous version, applied ability to customize a list of unwelcome words, and you don't need to review every comment.

image5.png

Did I mention reporting issues against comments? Yep, it's also included but now with the possibility to define your own reasons for the report. Same simple interface and moderation.

And finally, dual support for Strapi users (Authenticated) and generic ones. Now you don't need to choose which type of user will be able to post a comment and how you're going to handle it. The plugin is doing that all on your behalf and recognizes who does what.

Everything is done based on Plugin API and dedicated services for moderation, client and common usage. Easy to customize and extend via the Strapi Extensions, so you can lift everything for your custom requirement.

What's next, i.e the roadmap

The list of functionalities we've got is not yet completed, and we're looking forward to providing a lot more to the community. As a team, we would like to start from:

Settings page - to allow you to configure the plugin without needing even a single line of code
Reports page - a dedicated place for report reviewers to do their daily job with reported issues
Dashboard page - an all-in-one place to see what has happened recently in a feedback loop with your users and see some crucial stats from the moderator point of view
Advanced filtering - we would like to make the Discovery screen much more flexible to filter by linked entities, etc.
Moderator answer in place - you won't need to switch to the client application to answer the comment, it will be possible straight from the Moderation Panel, and your answer is going to be specially marked in the Public API and GraphQL responses
Importing from WordPress and Disqus - complex import and linking fix module which helps you migrate to Strapi

That's all we've got in our minds at this very moment, but as we know from almost 1.5 years of experience working with the Strapi community, that's probably just the beginning. So we are fully open to your ideas, requirements and requests to accommodate them as part of our backlog, which we're maintaining as the product board. So you can check it here to see how we're progressing.

How to contribute / call to action

By design, VirtusLab Open Source initiatives are open for external contributors as that's the flavor and power of work with the community. The Strapi plugins we've created are following this in a nutshell, so if you've got some ideas, improvements and tweaks you think might be part of the Strapi Comments Plugin by VirtusLab, you can contribute to it very straightforward:

Report your idea/need as an issue on the plugin repository
If you would like to contribute, fork us, implement what require and raise the PR
That's all. After review, your piece of code is going to become part of the plugin

If you would like to discuss the idea or have any questions, please drop us an email at strapi@virtuslab.com - or catch any of [VirtusLab] prefixed people on Strapi Discord. We're there and looking forward to connecting with you!

NPM package URL
https://www.npmjs.com/package/strapi-plugin-comments

Repository URL
https://github.com/VirtusLab-Open-Source/strapi-plugin-comments

Marketplace URL
https://market.strapi.io/plugins/strapi-plugin-comments

About VirtusLab

VirtusLab is a Poland-based tech company with a broad spectrum of digital services to create strategic value for our clients.
Our team of experts helps businesses of all sizes succeed in their digital transformation initiatives. They lead projects and implement the best solutions using modern methodologies and technologies in data engineering & data science, cloud-native system designs, and customer-centric, reactive applications with efficient and blazingly fast frontend.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .