{"id":13475282,"url":"https://github.com/VirtusLab-Open-Source/strapi-plugin-comments","last_synced_at":"2025-03-26T23:30:42.046Z","repository":{"id":38084861,"uuid":"273151853","full_name":"VirtusLab-Open-Source/strapi-plugin-comments","owner":"VirtusLab-Open-Source","description":"A plugin for Strapi Headless CMS that provides end to end comments feature with their moderation panel, bad words filtering, abuse reporting and more.","archived":false,"fork":false,"pushed_at":"2024-09-23T22:17:25.000Z","size":5805,"stargazers_count":412,"open_issues_count":22,"forks_count":65,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-10-30T08:51:32.547Z","etag":null,"topics":["api","comments","customizable","rest","strapi","strapi-admin-panel","strapi-plugin"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/VirtusLab-Open-Source.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-18T05:44:01.000Z","updated_at":"2024-10-25T05:40:33.000Z","dependencies_parsed_at":"2024-01-16T07:23:15.194Z","dependency_job_id":"df170a95-17ba-488a-a590-31c32e93170d","html_url":"https://github.com/VirtusLab-Open-Source/strapi-plugin-comments","commit_stats":{"total_commits":186,"total_committers":18,"mean_commits":"10.333333333333334","dds":"0.28494623655913975","last_synced_commit":"70dd408aa9d3cee2f928c555e99bf79b82147fe4"},"previous_names":["virtuslab/strapi-plugin-comments"],"tags_count":86,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VirtusLab-Open-Source%2Fstrapi-plugin-comments","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VirtusLab-Open-Source%2Fstrapi-plugin-comments/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VirtusLab-Open-Source%2Fstrapi-plugin-comments/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VirtusLab-Open-Source%2Fstrapi-plugin-comments/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VirtusLab-Open-Source","download_url":"https://codeload.github.com/VirtusLab-Open-Source/strapi-plugin-comments/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245753831,"owners_count":20666820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","comments","customizable","rest","strapi","strapi-admin-panel","strapi-plugin"],"created_at":"2024-07-31T16:01:19.031Z","updated_at":"2025-03-26T23:30:42.027Z","avatar_url":"https://github.com/VirtusLab-Open-Source.png","language":"TypeScript","readme":"\u003cdiv align=\"center\" style=\"max-width: 10rem; margin: 0 auto\"\u003e\n  \u003cimg style=\"width: 150px; height: auto;\" src=\"https://www.sensinum.com/img/open-source/strapi-plugin-comments/logo.png\" alt=\"Logo - Strapi Comments plugin\" /\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eStrapi v5 - Comments plugin\u003c/h1\u003e\n  \u003cp\u003ePowerful Strapi based comments moderation tool for you and your users\u003c/p\u003e\n  \u003ca href=\"https://www.npmjs.org/package/strapi-plugin-comments\"\u003e\n    \u003cimg alt=\"GitHub package.json version\" src=\"https://img.shields.io/github/package-json/v/VirtusLab-Open-Source/strapi-plugin-comments?label=npm\u0026logo=npm\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.org/package/strapi-plugin-comments\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/strapi-plugin-comments.svg\" alt=\"Monthly download on NPM\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://circleci.com/gh/VirtusLab-Open-Source/strapi-plugin-comments\"\u003e\n    \u003cimg src=\"https://circleci.com/gh/VirtusLab-Open-Source/strapi-plugin-comments.svg?style=shield\" alt=\"CircleCI\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/VirtusLab-Open-Source/strapi-plugin-comments\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/VirtusLab-Open-Source/strapi-plugin-comments/coverage.svg?branch=master\" alt=\"codecov.io\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n---\n\n\u003cdiv style=\"margin: 20px 0\" align=\"center\"\u003e\n  \u003cimg style=\"width: 100%; height: auto;\" src=\"https://www.sensinum.com/img/open-source/strapi-plugin-comments/preview.png\" alt=\"UI preview\" /\u003e\n\u003c/div\u003e\n\nA plugin for [Strapi Headless CMS](https://github.com/strapi/strapi) that provides end to end comments feature with their moderation panel, bad words filtering, abuse reporting and much more.\n\n### Table of Contents\n\n1. [💎 Versions](#-versions)\n2. [✨ Features](#-features)\n3. [⏳ Installation](#-installation)\n4. [🖐 Requirements](#-requirements)\n5. [🔧 Configuration](#-configuration)\n   - [Settings page](#in-v203-and-newer)\n   - [Plugin file](#in-v202-and-older--default-configuration-state-for-v203-and-newer)\n6. [🕸️ Public API - REST](#%EF%B8%8F-public-rest-api-specification)\n7. [🕸️ Public API - GraphQL](#%EF%B8%8F-public-graphql-specification)\n8. [🌿 Model lifecycle hooks](#model-life-cycle-hooks)\n9. [⚗️ Custom fields](#-custom-fields)\n10. [🧩 Examples](#-examples)\n11. [💬 FAQ](#-faq)\n12. [🤝 Contributing](#-contributing-to-the-plugin)\n13. [👨‍💻 Community support](#-community-support)\n\n## 💎 Versions\n\n- **Strapi v5** - (current) [v3.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments)\n- **Strapi v4** - [v2.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/tree/strapi-v4)\n- **Strapi v3** - [v1.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/tree/strapi-v3)\n\n## ✨ Features\n\n- **Comments Public REST + GraphQL API:** Elegant, entirely customizable and a fully extensible admin panel.\n- **Strapi \u0026amp; generic users:** Support for built-in \u0026amp; also generic non-Strapi users that might be the comments authors.\n- **Strapi Custom Fields support:** Improve an experience of your Content Types by using [dedicated set of custom fields](https://docs-next.strapi.io/dev-docs/custom-fields) for each of them and automate client side processing of Comments.\n- **Any Content Type relation:** Comments can be linked to any of your Content Types by default. Simply, you're controlling it.\n- **Moderation Panel:** Search \u0026 Filter through the bucket with your auditory comments. Manage them by blocking single ones or full threads. All in combined list \u0026amp; hierarchical tree view of threads.\n- **Automated Bad Words filtering:** By default end users are not allowed to post abusing comments where bad words have been used.\n- **Abuse Reporting \u0026 Reviewing:** Don't allow inferior language, react to reports from your community, send email notifications about issued reports\n\n## ⏳ Installation\n\n### Via Strapi Marketplace\n\nAs a ✅ **verified** plugin by Strapi team we're available on the [**Strapi Marketplace**](https://market.strapi.io/plugins/strapi-plugin-comments) as well as **In-App Marketplace** where you can follow the installation instructions.\n\n\u003cdiv style=\"margin: 20px 0\" align=\"center\"\u003e\n  \u003cimg style=\"width: 100%; height: auto;\" src=\"https://www.sensinum.com/img/open-source/strapi-plugin-comments/marketplace.png\" alt=\"Strapi In-App Marketplace\" /\u003e\n\u003c/div\u003e\n\n### Via command line\n\n(Use **yarn** to install this plugin within your Strapi project (recommended). [Install yarn with these docs](https://yarnpkg.com/lang/en/docs/install/).)\n\n```bash\nyarn add strapi-plugin-comments@latest\n```\n\nAfter successful installation you've to re-build your Strapi instance. To archive that simply use:\n\n```bash\nyarn build\nyarn develop\n```\n\nThe **Comments** plugin should appear in the **Plugins** section of Strapi sidebar after you run app again.\n\nAs a next step you must configure your the plugin by the way you want to. See [**Configuration**](#🔧-configuration) section.\n\nAll done. Enjoy 🎉\n\n## 🖐 Requirements\n\nComplete installation requirements are exact same as for Strapi itself and can be found in the documentation under [Installation Requirements](https://docs.strapi.io/dev-docs/intro).\n\n**Minimum environment requirements**\n\n- Node.js `\u003e=18.0.0 \u003c=22.x.x`\n- NPM `\u003e=6.x.x`\n\nIn our minimum support we're following [official Node.js releases timelines](https://nodejs.org/en/about/releases/).\n\n**Supported Strapi versions**:\n\n- Strapi v5.10.3 (recently tested)\n- Strapi v5.x\n\n\u003e This plugin is designed for **Strapi v5**. To get support for other Strapi versions, please follow the [versions](#-versions) section.\n\n**Plugin dependencies**\n- `@strapi/plugin-graphql` - required to run GraphQL handled by this plugin \n\n**We recommend always using the latest version of Strapi to start your new projects**.\n\n## 🔧 Configuration\n\nTo start your journey with **Comments plugin** you must first setup it using the dedicated Settings page or for any version, put your configuration in `config/plugins.{js|ts}`. Anyway we're recommending the click-through option where your configuration is going to be properly validated.\n\n### Settings page\n\nOn the dedicated page, you will be able to set up all crucial properties which drive the plugin and customize each individual collection for which **Comments plugin** should be enabled.\n\n\u003cdiv style=\"margin: 20px 0\" align=\"center\"\u003e\n  \u003cimg style=\"width: 100%; height: auto;\" src=\"https://www.sensinum.com/img/open-source/strapi-plugin-comments/configuration.png\" alt=\"Plugin configuration\" /\u003e\n\u003c/div\u003e\n\n\u003e _Note_\n\u003e Default configuration for your plugin is fetched from `config/plugins.{js|ts}` or directly from the plugin itself. If you would like to customize the default state to which you might revert, please follow the next section.\n\n### File\n\nTo setup amend default plugin configuration we recommend to put following snippet as part of `config/plugins.{js|ts}` or `config/\u003cenv\u003e/plugins.{js|ts}` file. If the file does not exist yet, you have to create it manually. If you've got already configurations for other plugins stores by this way, use just the `comments` part within exising `plugins` item.\n\n```ts\n  module.exports = ({ env }) =\u003e ({\n  //...\n  comments: {\n    enabled: true,\n    config: {\n      badWords: false,\n      moderatorRoles: [\"Authenticated\"],\n      approvalFlow: [\"api::page.page\"],\n      entryLabel: {\n        \"*\": [\"Title\", \"title\", \"Name\", \"name\", \"Subject\", \"subject\"],\n        \"api::page.page\": [\"MyField\"],\n      },\n      blockedAuthorProps: [\"name\", \"email\"],\n      reportReasons: {\n        MY_CUSTOM_REASON: \"MY_CUSTOM_REASON\",\n      },\n      gql: {\n        // ...\n      },\n    },\n  },\n  //...\n});\n```\n\n### Properties\n\n- `enabledCollections` - list of Collection and Single Types for which plugin should be enabled in format like `'api::\u003ccollection name\u003e.\u003ccontent type name\u003e'`. By default it's empty and none comments are not enabled for any of type in Strapi.\n- `no-profanity` - Enabled support for [profanity filtering](https://www.npmjs.com/package/no-profanity). Can be turned off or altered using the [options reference](https://www.npmjs.com/package/no-profanity?activeTab=readme#options). Default value: `true`.\n- `moderatorRoles` - Optional list of names of roles. Users with those roles will be notified by email when a new abuse report is created. This feature requires a built-in [Strapi email plugin](https://docs.strapi.io/dev-docs/plugins/email) configured.\n- `approvalFlow` - list of Content Types which are supporting approval flow. Values must be in format like `'api::\u003ccollection name\u003e.\u003ccontent type name\u003e'`. For not included, posted comments are going to be immediately visible.\n- `entryLabel` - ordered list of property names per Content Type to generate related entity label. Keys must be in format like `'api::\u003ccollection name\u003e.\u003ccontent type name\u003e'`. Default formatting set as `*`.\n- `reportReasons` - set of enums you would like to use for issuing abuse reports. Provided by default `'BAD_LANGUAGE'`, `'DISCRIMINATION'` and `'OTHER'`.\n- `gql` - specific configuration for GraphQL. See [Additional GQL Configuration](#additional-gql-configuration)\n- `blockedAuthorProps` - list of author's entity properties removed from a response for client side\n\n## Additional GQL Configuration\n\nAll you need to do is to install and enable `@strapi/plugin-graphql` for you instance based on the **[official Strapi v4 docs](https://docs.strapi.io/dev-docs/plugins/graphql#configurations)** and decide if you would like to call it by anyone (open for world) or only by authenticated users (Strapi users).\n\n\u003e **Important!**\n\u003e If you're using `config/plugins.{js|ts}` to configure your plugins , please put `comments` property before `graphql`. Otherwise types are not going to be properly added to GraphQL Schema. That's because of dynamic types which base on plugin configuration which are added on `boostrap` stage, not `register`. This is not valid if you're using `graphql` plugin without any custom configuration, so most of cases in real.\n\n```json\n{\n  // ...\n  \"gql\": {\n    \"auth\": true // Default: false\n  }\n  // ...\n}\n```\n\n### Properties\n\n- `auth` - does GraphQL Queries should be authenticated or not? Default: `false`\n\n### Queries\n\nSee [available GQL specification section](#public-graphql-specification).\n\n\u003e If `auth` is set to `true` you must provide relevant authentication headers to all requests like for example:\n\u003e\n\u003e ```json\n\u003e {\n\u003e   \"Authorization\": \"Bearer \u003cyour token here\u003e\"\n\u003e }\n\u003e ```\n\n## 👤 RBAC\n\nPlugin provides granular permissions based on Strapi RBAC functionality.\n\n### Mandatory permissions\n\nFor any role different than **Super Admin**, to access the **Comments panel** you must set following permissions:\n\n- _Plugins_ -\u003e _Content-type-builder_ -\u003e _Read_ - gives you ability to fetch Content Type schema\n- _Plugins_ -\u003e _Comments_ -\u003e _Comments: Read_ - gives you the basic read access to **Comments Panel**\n\n### Optional permissions\n\nFeature / Capability focused permissions:\n\n- _Plugins_ -\u003e _Comments_ -\u003e _Comments: Moderate_ - allows you to block, unblock, approve \u0026amp; reject comments\n- _Plugins_ -\u003e _Comments_ -\u003e _Reports: Read_ - allows you to see the list of issued abuse reports against comments\n- _Plugins_ -\u003e _Comments_ -\u003e _Reports: Moderate_ - allows you to review (resolve) issued abuse reports against comments\n\n## Base Comment model\n\n```json\n{\n  \"documentId\": \"njx99iv4p4txuqp307ye8625\",\n  \"content\": \"My comment content\",\n  \"blocked\": null,\n  \"blockedThread\": true,\n  \"blockReason\": null,\n  \"authorUser\": null,\n  \"removed\": null,\n  \"approvalStatus\": \"APPROVED\", // Only in case of enabled approval flow. Default: null\n  \"author\": {\n    \"id\": \"207ccfdc-94ba-45eb-979c-790f6f49c392\", // For Strapi users id reflects to the format used by your Strapi\n    \"name\": \"Joe Doe\", // For Strapi users it is equal to 'username' field\n    \"email\": \"jdoe@sample.com\",\n    \"avatar\": null\n  },\n  \"createdAt\": \"2020-07-14T20:13:01.649Z\",\n  \"updatedAt\": \"2020-07-14T20:13:01.670Z\",\n  \"related\": {}, // Related content type entity\n  \"reports\": [] // Reports issued against this comment\n}\n```\n\n## 🕸️ Public REST API specification\n\n**Strapi Users vs. Generic authors**\n\n\u003e Keep in mind that if you're using auth / authz your requests to setup proper user contexts it has got higher priority in order to take author data comparing to `author` property provided as part of your payload.\n\n### Get Comments\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Get Comments](#get-comments-1)_\n\n`GET \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e`\n\nReturn a hierarchical tree structure of comments for specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625`.\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625`\n\n**Example response body**\n\n```json\n[\n  {\n    // -- Comment Model fields ---,\n    \"children\": [\n      {\n        // -- Comment Model fields ---,\n        \"children\": [\n          // ...\n        ]\n      }\n      // ...\n    ]\n  }\n  // ...\n]\n```\n\n#### Strapi REST API properties support:\n\n- [field selection](https://docs.strapi.io/dev-docs/api/rest/populate-select#field-selection)\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n\n### Get Comments (flat structure)\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Get Comments (flat structure)](#get-comments-flat-structure-1)_\n\n`GET \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e/flat`\n\nReturn a flat structure of comments for specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625`\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625/flat`\n\n**Example response body**\n\n```json\n{\n  \"data\": [\n    {\n      // -- Comment Model fields ---\n    },\n    {\n      // -- Comment Model fields ---\n    }\n    // ...\n  ],\n  \"meta\": {\n    \"pagination\": {\n      // payload based on Strapi REST Pagination specification\n    }\n  }\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful. Response with list of comments (can be empty)\n- `400` - Bad Request. Requested list for not valid / not existing Content Type\n\n#### Strapi REST API properties support:\n\n- [filtering](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication#filtering)\n- [field selection](https://docs.strapi.io/dev-docs/api/rest/populate-select#field-selection)\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n- [pagination](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#pagination)\n\n### Get Comments (by Author)\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Get Comments (by Author)](#get-comments-by-author-1)_\n\n`GET \u003chost\u003e/api/comments/author/\u003cid\u003e/\u003c?type\u003e`\n\nReturn a flat structure of comments by specified Author for example `Author` with `ID: 1`\n\n**Example URL**: `https://localhost:1337/api/comments/author/1` - get comments by `ID: 1` of Strapi User\n**Example URL**: `https://localhost:1337/api/comments/author/1/generic` - get comments by `ID: 1` of Generic User\n\n#### Skipping fields\n\nTo skip a field from the response you can use a query param called `omit`. It is a list of `Comment` entity fields you want to ignore. For example `?omit[]=author\u0026omit[]=related`.\n\n**Remember!** `id` field is required so it will not be skipped.\n\n**Example response body**\n\n```json\n{\n  \"data\": [\n    {\n      // -- Comment Model fields ---\n    },\n    {\n      // -- Comment Model fields ---\n    }\n    // ...\n  ],\n  \"meta\": {\n    \"pagination\": {\n      // payload based on Strapi REST Pagination specification\n    }\n  }\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful. Response with list of comments (can be empty)\n- `400` - Bad Request. Requested list for not valid / not existing Content Type\n\n#### Strapi REST API properties support:\n\n- [filtering](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication#filtering)\n- [field selection](https://docs.strapi.io/dev-docs/api/rest/populate-select#field-selection)\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n- [pagination](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#pagination)\n\n### Post a Comment\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Post a Comments](#post-a-comment-1)_\n\n`POST \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e`\n\nPosts a Comment related to specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625`\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625`\n\n**Example request body**\n\n_Generic (non Strapi User)_\n\n```json\n{\n  \"author\": {\n    \"id\": \"\u003cany ID like value\u003e\",\n    \"name\": \"Joe Doe\",\n    \"email\": \"jdoe@sample.com\",\n    \"avatar\": \"\u003cany image url\u003e\"\n  },\n  \"content\": \"My sample response\",\n  \"threadOf\": 2 // id of comment we would like to start / continue the thread (Optional)\n}\n```\n\n_Strapi user_\n\n\u003e Author is taken directly from the request context\n\n```json\n{\n  \"content\": \"My sample response\",\n  \"threadOf\": 2 // id of comment we would like to start / continue the thread (Optional)\n}\n```\n\n**Example response body**\n\n```json\n{\n  // -- Comment Model fields ---\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful. Response with created Comment Model\n- `400` - Bad Request. Missing field values or bad words check fails. Error message will provide relevant reason.\n\n### Update Comment\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Update Comments](#update-comment-1)_\n\n`PUT \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e/comment/\u003ccommentId\u003e`\n\nUpdates a specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625`\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625/comment/2`\n\n**Example request body**\n\n_Generic (non Strapi User)_\n\n```json\n{\n  \"author\": {\n    \"id\": \"\u003cany ID like value\u003e\"\n  },\n  \"content\": \"My sample response\"\n}\n```\n\n_Strapi user_\n\n\u003e Author is taken directly from the request context\n\n```json\n{\n  \"content\": \"My sample response\"\n}\n```\n\n**Example response body**\n\n```json\n{\n  // -- Comment Model fields ---\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful. Response with updated Comment Model\n- `400` - Bad Request. Missing field values or bad words check fails. Error message will provide relevant reason.\n- `409` - Conflict. Occurs when trying to update a non existing or not own comment. Possible cause might be that `authorId` or `authorUser` mismatch with existing comment.\n\n### Delete Comment\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Delete Comment](#delete-comment-1)_\n\n`DELETE \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e/comment/\u003ccommentId\u003e?authorId=\u003cauthorId\u003e`\n\nDeletes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625`.\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625/comment/1?authorId=1`\n\n**Example response body**\n\n```json\n{\n  // -- Empty Response ---\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful with blank Response.\n- `409` - Conflict. Occurs when trying to delete a non existing comment.\n\n### Issue Abuse Report against specified Comment\n\n_GraphQL equivalent: [Public GraphQL API -\u003e Issue Abuse Report against specified Comment](#issue-abuse-report-against-specified-comment-1)_\n\n`POST \u003chost\u003e/api/comments/api::\u003ccollection name\u003e.\u003ccontent type name\u003e:\u003centity document id\u003e/comment/\u003ccommentId\u003e/report-abuse`\n\nReports abuse in specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Page` with `documentId: njx99iv4p4txuqp307ye8625` and requests moderator attention.\n\n**Example URL**: `https://localhost:1337/api/comments/api::page.page:njx99iv4p4txuqp307ye8625/comment/2/report-abuse`\n\n**Example request body**\n\n```json\n{\n  \"reason\": \"\u003creason enum\u003e\",\n  \"content\": \"This comment is not relevant\"\n}\n```\n\n_Available reason enums:_ `BAD_WORDS`, `OTHER`, `DISCRIMINATION` (want more? See [configuration section](#configuration).)\n\n**Example response body**\n\n```json\n{\n  // -- Comment Abuse Report fields ---\n}\n```\n\n**Possible response codes**\n\n- `200` - Successful. Response with reported abuse.\n- `409` - Conflict. Occurs when trying to report an abuse to a non existing comment.\n\n## 🕸️ Public GraphQL specification\n\n**Strapi Users vs. Generic authors**\n\n\u003e Keep in mind that if you're using auth / authz your requests to setup proper user contexts it has got higher priority in order to take author data comparing to `author` property provided as part of your payload.\n\n**Testing**\n\n\u003e To test all queries and understand the schemas use GraphQL Playground exposed by `@strapi/plugin-graphql` on `http://localhost:1337/graphql`\n\n### Get Comments\n\n_REST API equivalent: [Public REST API -\u003e Get Comments](#get-comments)_\n\n**Example request**\n\n```graphql\nquery {\n  findAllInHierarchy(relation: \"api::page.page:njx99iv4p4txuqp307ye8625\") {\n    id\n    content\n    blocked\n    children {\n      id\n      content\n    }\n    threadOf {\n      id\n    }\n    author {\n      id\n      name\n    }\n  }\n}\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"findAllInHierarchy\": [\n      {\n        \"id\": 1,\n        \"content\": \"Test\",\n        \"blocked\": false,\n        \"children\": [\n          {\n            \"id\": 6,\n            \"content\": \"Text to search for\"\n          }\n          // ...\n        ],\n        \"threadOf\": null,\n        \"author\": {\n          \"id\": \"123456\",\n          \"name\": \"Joe Doe\"\n        }\n      }\n      // ...\n    ]\n  }\n}\n```\n\n#### Strapi GraphQL API properties support:\n\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n\n### Get Comments (flat structure)\n\n_REST API equivalent: [Public REST API -\u003e Get Comments (flat structure)](#get-comments-flat-structure)_\n\n**Example request**\n\n```graphql\nquery {\n  findAllFlat(\n    relation: \"api::page.page:njx99iv4p4txuqp307ye8625\"\n    filters: { content: { contains: \"Test\" } }\n  ) {\n    id\n    content\n    blocked\n    threadOf {\n      id\n    }\n    author {\n      id\n      name\n    }\n  }\n}\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"findAllFlat\": [\n      {\n        \"id\": 3,\n        \"content\": \"Test\",\n        \"blocked\": false,\n        \"threadOf\": null,\n        \"author\": {\n          \"id\": \"123456\",\n          \"name\": \"Joe Doe\"\n        }\n      },\n      // ...\n    ]\n  }\n}\n```\n\n#### Strapi GraphQL API properties support:\n\n- [filtering](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication#filtering)\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n- [pagination](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#pagination)\n\n### Get Comments (by Author)\n\n_REST API equivalent: [Public REST API -\u003e Get Comments (by Author)](#get-comments-by-author)_\n\n**Example request**\n\n```graphql\nquery {\n  findAllPerAuthor(authorId: 1, authorType: STRAPI) { // authorType might be one of [GENERIC, STRAPI]\n    data {\n      id\n      content\n      blocked\n      threadOf {\n        id\n      }\n    }\n  }\n}\n\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"findAllPerAuthor\": {\n      \"data\": [\n        {\n          \"id\": 4,\n          \"content\": \"Hackaton test comment\",\n          \"blocked\": false,\n          \"threadOf\": {\n            \"id\": 1\n          }\n        }\n      // ...\n      ]\n    }\n  }\n```\n\n#### Strapi GraphQL API properties support:\n\n- [filtering](https://docs.strapi.io/dev-docs/api/rest/filters-locale-publication#filtering)\n- [sorting](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#sorting)\n- [pagination](https://docs.strapi.io/dev-docs/api/rest/sort-pagination#pagination)\n\n### Post a Comment\n\n_REST API equivalent: [Public REST API -\u003e Post a Comment](#post-a-comment)_\n\n**Example request**\n\n```graphql\nmutation createComment {\n  createComment(\n    input: {\n      relation: \"api::page.page:njx99iv4p4txuqp307ye8625\"\n      content: \"Hello World!\"\n      threadOf: 3\n      author: { id: \"12345678\", name: \"John Wick\", email: \"test@test.pl\" } # Optional if using auth / authz requests\n    }\n  ) {\n    id\n    content\n    threadOf {\n      id\n    }\n    author {\n      id\n      name\n    }\n  }\n}\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"createComment\": {\n      \"id\": 34,\n      \"content\": \"Hello World!\",\n      \"threadOf\": {\n        \"id\": 3\n      },\n      \"author\": {\n        \"id\": \"12345678\",\n        \"name\": \"John Wick\"\n      }\n    }\n  }\n}\n```\n\n### Update Comment\n\n_REST API equivalent: [Public REST API -\u003e Update Comment](#update-comment)_\n\n**Example request**\n\n```graphql\nmutation updateComment {\n  updateComment(\n    input: {\n      id: 34\n      relation: \"api::page.page:njx99iv4p4txuqp307ye8625\"\n      content: \"I've changed it!\"\n      author: { id: \"12345678\" } # Optional if using auth / authz requests\n    }\n  ) {\n    id\n    content\n    threadOf {\n      id\n    }\n    author {\n      id\n      name\n    }\n    createdAt\n    updatedAt\n  }\n}\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"updateComment\": {\n      \"id\": 34,\n      \"content\": \"I've changed it!\",\n      \"threadOf\": {\n        \"id\": 3\n      },\n      \"author\": {\n        \"id\": \"12345678\",\n        \"name\": \"John Wick\"\n      },\n      \"createdAt\": \"2022-01-26T07:45:35.978Z\",\n      \"updatedAt\": \"2022-01-26T07:47:44.659Z\"\n    }\n  }\n}\n```\n\n### Delete Comment\n\n_REST API equivalent: [Public REST API -\u003e Delete Comment](#delete-comment)_\n\n**Example request**\n\n```graphql\nmutation removeComment {\n  removeComment(\n    input: {\n      id: 33\n      relation: \"api::page.page:njx99iv4p4txuqp307ye8625\"\n      author: { id: \"12345678\" } # Optional if using auth / authz requests\n    }\n  ) {\n    id\n    removed\n  }\n}\n```\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"removeComment\": {\n      \"id\": 33,\n      \"removed\": true\n    }\n  }\n}\n```\n\n### Issue Abuse Report against specified Comment\n\n_REST API equivalent: [Public REST API -\u003e Issue Abuse Report against specified Comment](#issue-abuse-report-against-specified-comment)_\n\n**Example request body**\n\n```graphql\nmutation createAbuseReport {\n  createAbuseReport(\n    input: {\n      commentId: 34\n      relation: \"api::page.page:njx99iv4p4txuqp307ye8625\"\n      reason: BAD_LANGUAGE\n      content: \"Rude language\"\n    }\n  ) {\n    id\n    reason\n    content\n    related {\n      id\n      author {\n        id\n        name\n      }\n    }\n  }\n}\n```\n\n_Available reason enums:_ `BAD_WORDS`, `OTHER`, `DISCRIMINATION` (want more? See [configuration section](#configuration).)\n\n**Example response**\n\n```json\n{\n  \"data\": {\n    \"createAbuseReport\": {\n      \"id\": 28,\n      \"content\": \"Rude language\",\n      \"reason\": \"DISCRIMINATION\",\n      \"related\": {\n        \"id\": 34,\n        \"author\": {\n          \"id\": \"12345678\",\n          \"name\": \"John Wick\"\n        }\n      }\n    }\n  }\n}\n```\n\n## 🧩 Examples\n\nLive example of plugin usage can be found in the [VirtusLab Strapi Examples](https://github.com/VirtusLab/strapi-examples/tree/master/strapi-plugin-comments) repository.\n\n## ⚗️ Custom fields\n\nFor developers who upgrades their Strapi instance custom field from Comments plugin is available. Custom field can be picked from content types' edit page or added in definition file.\n\nRead more about this feature in [Strapi's docs](https://docs-next.strapi.io/dev-docs/custom-fields).\n\n## Model lifecycle hooks\n\nComments plugin allows to register lifecycle hooks for `Comment` and `Comment report` content types.\n\nYou can read more about lifecycle hooks [here](https://docs.strapi.io/dev-docs/backend-customization/models#lifecycle-hooks). (You can set a listener for all of the hooks).\n\nLifecycle hooks can be register either in `register()` or `bootstrap()` methods of your server. You can register more than one listener for a specified lifecycle hook. For example: you want to do three things on report creation and do not want to handle all of these actions in one big function. You can split logic in as many listeners as you want.\n\nListeners can by sync and `async`.\n\n\u003eBe aware that lifecycle hooks registered in `register()` may be fired by plugin's bootstrapping. If you want listen to events triggered after server's startup use `bootstrap()`.\n\nExample:\n\n```ts\n  const commentsCommonService = strapi\n    .plugin(\"comments\")\n    .service(\"common\");\n\n  commentsCommonService.registerLifecycleHook({\n    callback: async ({ action, result }) =\u003e {\n      const saveResult = await logIntoSystem(action, result);\n\n      console.log(saveResult);\n    },\n    contentTypeName: \"comment\",\n    hookName: \"afterCreate\",\n  });\n\n  commentsCommonService.registerLifecycleHook({\n    callback: async ({ action, result }) =\u003e {\n      const saveResult = await logIntoSystem(action, result);\n\n      console.log(saveResult);\n    },\n    contentTypeName: \"report\",\n    hookName: \"afterCreate\",\n  });\n```\n\n## 💬 FAQ\n\n### GraphQL tricks\n\n**Q:** I would like to use GraphQL schemas but I'm not getting any response, just 403 or 500 for every query or even proper types etc. What should I do?\n\n**A:** There is a one trick you might try. Strapi by default is ordering plugins by the way which takes `strapi-plugin-graphql` to initialize earlier than other plugins so types might not be injected. If you don't have it yet, please create `config/plugins.{js|ts}` file and put there following lines (put `graphql` at the end):\n\n```ts\nmodule.exports = {\n  'comments': { enabled: true },\n  'graphql': { enabled: true },\n};\n```\n\nIf you already got it, make sure that `comments` plugin is inserted before `graphql`. That should do the job.\n\n\n## 🤝 Contributing to the plugin\n\nFeel free to fork and make a Pull Request to this plugin project. All the input is warmly welcome!\n\n## 👨‍💻 Community support\n\nFor general help using Strapi, please refer to [the official Strapi documentation](https://strapi.io/documentation/). For additional help, you can use one of these channels to ask a question:\n\n- [Discord](https://discord.strapi.io/) We're present on official Strapi Discord workspace. Find us by `[VirtusLab]` prefix and DM.\n- [Slack - VirtusLab Open Source](https://virtuslab-oss.slack.com) We're present on a public channel #strapi-molecules\n- [GitHub](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/issues) (Bug reports, Contributions, Questions and Discussions)\n- [E-mail](mailto:strapi@virtuslab.com) - we will respond back as soon as possible\n\n## 📝 License\n\n[MIT License](LICENSE.md) Copyright (c) [VirtusLab Sp. z o.o.](https://virtuslab.com/) \u0026amp; [Strapi Solutions](https://strapi.io/).\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FVirtusLab-Open-Source%2Fstrapi-plugin-comments","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FVirtusLab-Open-Source%2Fstrapi-plugin-comments","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FVirtusLab-Open-Source%2Fstrapi-plugin-comments/lists"}