From 48e8fc05453ec7c8ab31bec1edae38a1418bdc63 Mon Sep 17 00:00:00 2001
From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com>
Date: Mon, 20 Nov 2023 03:39:27 +0000
Subject: [PATCH 1/4] build: update dependencies for toxic detection

---
 Dockerfile | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 4cafb73..15e297a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,15 +27,16 @@ RUN apt update -y && \
     rm -rf /var/lib/apt/lists/*
 
 # Prepare nostr-filter
-ENV NOSTR_FILTER_COMMIT_HASH_VERSION=9c7d7b85e7ab62ebf5ac7232b21fec08384efbb0
-RUN git clone --branch main https://github.com/atrifat/nostr-filter && \
+ENV NOSTR_FILTER_COMMIT_HASH_VERSION=29d5c56d3583b2ea63f2ffb826d3b93b7fa45abd
+ENV NOSTR_FILTER_BRANCH=main
+RUN git clone --branch $NOSTR_FILTER_BRANCH https://github.com/atrifat/nostr-filter && \
     cd /builder/nostr-filter && \
     git reset --hard $NOSTR_FILTER_COMMIT_HASH_VERSION && \
     git clean -df && \
     npm ci --omit=dev && npx tsc
 
 # Prepare nostr-monitoring-tool
-ENV NOSTR_MONITORING_TOOL_VERSION=v0.3.0
+ENV NOSTR_MONITORING_TOOL_VERSION=v0.4.0
 RUN git clone --depth 1 --branch $NOSTR_MONITORING_TOOL_VERSION https://github.com/atrifat/nostr-monitoring-tool && \
     cd /builder/nostr-monitoring-tool && \
     npm ci --omit=dev
@@ -83,6 +84,21 @@ ENV NOSTR_MONITORING_BOT_PUBLIC_KEY=
 ENV WHITELISTED_PUBKEYS=
 ENV LISTEN_PORT=7860
 ENV ENABLE_FORWARD_REQ_HEADERS=false
+# (Default: sfw, Options: all, sfw, partialsfw, and nsfw) Filter hate speech (toxic comment).
+ENV DEFAULT_FILTER_CONTENT_MODE=sfw
+ENV DEFAULT_FILTER_NSFW_CONFIDENCE=75
+# (Default: all, Multiple Options: all, or other language code)
+ENV DEFAULT_FILTER_LANGUAGE_MODE=all
+# (Default: 15, Options: 0-100) Default minimum probability/confidence score to determine the classification of language
+ENV DEFAULT_FILTER_LANGUAGE_CONFIDENCE=15
+# (Default: no, Options: all, no, yes) Filter hate speech (toxic comment). "all" will disable filtering, "no" will filter out any detected hate speech content, "yes" will select only detected hate speech content
+ENV DEFAULT_FILTER_HATE_SPEECH_TOXIC_MODE=no
+# (Default: 75, Options: 0-100) Default minimum probability/confidence score to determine the classification of hate speech (toxic comment)
+ENV DEFAULT_FILTER_HATE_SPEECH_TOXIC_CONFIDENCE=75
+# (Default: max, Options: max, sum) Methods to determine toxic content by using max value from all toxic classes score or sum value of all toxic classes score
+ENV DEFAULT_FILTER_HATE_SPEECH_TOXIC_EVALUATION_MODE=max
+# (Default: all, Options: all, nostr, activitypub) Filter user type. "nostr" for native nostr users and "activitypub" for activitypub users coming from bridge
+ENV DEFAULT_FILTER_USER_MODE=all
 
 # ENV variable for nostr-monitoring-tool
 ENV ENABLE_NSFW_CLASSIFICATION=true

From faaa4d19aa451ed70e5fba7ca71c5c6e1d3140b3 Mon Sep 17 00:00:00 2001
From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com>
Date: Tue, 21 Nov 2023 00:57:59 +0000
Subject: [PATCH 2/4] docs: update .env.example for toxic detection

---
 .env.example | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/.env.example b/.env.example
index 8b62fba..695e679 100644
--- a/.env.example
+++ b/.env.example
@@ -8,6 +8,13 @@ ENABLE_LANGUAGE_DETECTION=true
 LANGUAGE_DETECTOR_ENDPOINT=http://localhost:5000/detect
 LANGUAGE_DETECTOR_TOKEN=
 LANGUAGE_DETECTOR_TRUNCATE_LENGTH=350
+ENABLE_HATE_SPEECH_DETECTION = true
+# (Required if ENABLE_HATE_SPEECH_DETECTION == true) set this to your own hate-speech-detector-api instance (https://github.com/atrifat/hate-speech-detector-api)
+HATE_SPEECH_DETECTOR_ENDPOINT = http://localhost:8083/predict
+# (Optional) set this to your own hate-speech-detector-api api_key if required 
+HATE_SPEECH_DETECTOR_TOKEN =
+# (Default: 350) Set to 0 if you don't want to truncate text, or set to any positive number to truncate the text characters
+HATE_SPEECH_DETECTOR_TRUNCATE_LENGTH = 350
 # (Required for classification filtering)
 NOSTR_MONITORING_BOT_PRIVATE_KEY=
 RELAYS_SOURCE=wss://relay.nostr.band,wss://relay.damus.io,wss://nos.lol,wss://relay.mostr.pub
@@ -25,4 +32,20 @@ NOSTR_MONITORING_BOT_PUBLIC_KEY=
 WHITELISTED_PUBKEYS=
 LISTEN_PORT=7860
 # (Optional) Set true to enable forwarding of request headers to upstream server, useful if relays behind reverse proxy
-ENABLE_FORWARD_REQ_HEADERS=false
\ No newline at end of file
+ENABLE_FORWARD_REQ_HEADERS=false
+# (Optional. Default: sfw. Options: all, sfw, partialsfw, and nsfw) Filter hate speech (toxic comment).
+DEFAULT_FILTER_CONTENT_MODE=sfw
+# (Optional. Default: 75, Options: 0-100) Default minimum probability/confidence score to determine the classification of nsfw content
+DEFAULT_FILTER_NSFW_CONFIDENCE=75
+# (Optional. Default: all. Multiple Options: all, or other language code)
+DEFAULT_FILTER_LANGUAGE_MODE=all
+# (Optional. Default: 15. Options: 0-100) Default minimum probability/confidence score to determine the classification of language
+DEFAULT_FILTER_LANGUAGE_CONFIDENCE=15
+# (Optional. Default: no. Options: all, no, yes) Filter hate speech (toxic comment). "all" will disable filtering, "no" will filter out any detected hate speech content, "yes" will select only detected hate speech content
+DEFAULT_FILTER_HATE_SPEECH_TOXIC_MODE=no
+# (Optional. Default: 75. Options: 0-100) Default minimum probability/confidence score to determine the classification of hate speech (toxic comment)
+DEFAULT_FILTER_HATE_SPEECH_TOXIC_CONFIDENCE=75
+# (Optional. Default: max. Options: max, sum) Methods to determine toxic content by using max value from all toxic classes score or sum value of all toxic classes score
+DEFAULT_FILTER_HATE_SPEECH_TOXIC_EVALUATION_MODE=max
+# (Optional. Default: all. Options: all, nostr, activitypub) Filter user type. "nostr" for native nostr users and "activitypub" for activitypub users coming from bridge
+DEFAULT_FILTER_USER_MODE=all
\ No newline at end of file

From 1f185634fb1cc94350c5c89f7b937073f59e9d3d Mon Sep 17 00:00:00 2001
From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com>
Date: Tue, 21 Nov 2023 00:59:14 +0000
Subject: [PATCH 3/4] docs: update readme with hate speech detection

---
 README.md | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index ec3f76c..6931014 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # nostr-filter-relay
 
-A nostr relay docker image package which filter content based on content type (SFW/NSFW), user type, language, and various rules.
+A nostr relay docker image package which filter content based on content type (SFW/NSFW), user type, language, hate speech (toxic comment), and various rules.
 
 This docker image consists of several software packages:
 
@@ -23,8 +23,8 @@ A relay software package that filter note (kind: 1) contents in various category
 - [x] NSFW/SFW content detection
 - [x] Language detection
 - [x] User type filtering (Nostr user/non bridged user, activitypub bridged user)
+- [x] Hate speech (Toxic comment) detection
 - [ ] (WIP) Sentiment analysis
-- [ ] (WIP) Hate-speech detection
 - [ ] (Planned) Topic classification
 - [x] All other features included in [atrifat/nostr-filter](https://github.com/atrifat/nostr-filter) and [atrifat/nostr-monitoring-tool](https://github.com/atrifat/nostr-monitoring-tool)
 
@@ -35,6 +35,7 @@ The following softwares are required if you want to run your own nostr-filter-re
 - Docker
 - Personal instance of [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api). Check [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api) Github repository for more instructions.
 - Personal instance of [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate). Check [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate) Github repository for more instructions.
+- Personal instance of [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api). Check [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api) Github repository for more instructions.
 
 ## Getting Started
 
@@ -45,7 +46,9 @@ git clone https://github.com/atrifat/nostr-filter-relay
 cd nostr-filter-relay
 ```
 
-Before running nostr-filter-relay, make sure you have already configured your own personal instance of [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api) and [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate). Copy `.env.example` into `.env` file and change the configuration according to your own settings.
+Before running nostr-filter-relay, make sure you have already configured your own personal instance of [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api), [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate), and [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api). You don't have to run all of them only if you enable classification for certain task (Example: NSFW detection only).
+
+Copy `.env.example` into `.env` file and change the configuration according to your own settings.
 
 ### Published Docker Image
 
@@ -85,7 +88,27 @@ docker run --init --env-file .env -p 7860:7860 -it --name nostr-filter-relay -d
 
 ## License
 
-MIT
+MIT License
+
+Copyright (c) 2023 Rif'at Ahdi Ramadhani
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
 
 ## Author
 

From ca52b00b63a151f433cdc9f391ba8371581fa09a Mon Sep 17 00:00:00 2001
From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com>
Date: Tue, 21 Nov 2023 01:54:15 +0000
Subject: [PATCH 4/4] docs: update usage with hate speech filter example

---
 USAGE.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 9 deletions(-)

diff --git a/USAGE.md b/USAGE.md
index d7ea414..1cc6e0c 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -2,21 +2,19 @@
 
 ## Basic Usage
 
-nostr-filter-relay can be used and activated as relay for "Global" feed in your Nostr clients. Simply add `wss://nostr-id-relay.hf.space` (public demo relay, or change it into your own nostr-relay-filter url) to your nostr clients and set it to enable reading in "Global" relay settings.
+nostr-filter-relay can be used and activated as relay for "Global" feed in our Nostr clients. Simply add `wss://nostr-id-relay.hf.space` (public demo relay, or change it into our own nostr-relay-filter url) to our nostr clients and set it to enable reading in "Global" relay settings.
 
-If you don't add any parameter (?) behind the url of `wss://nostr-id-relay.hf.space` then it is equal to using relay with parameters as default values:
+If we don't add any parameter (?) behind the url of `wss://nostr-id-relay.hf.space` then it is equal to using relay with parameters using its default values:
 
-```
-wss://nostr-id-relay.hf.space/?content=sfw&user=all&lang=all&nsfw_confidence=75&lang_confidence=15
-```
+`wss://nostr-id-relay.hf.space/?user=all&lang=all&content=sfw&nsfw_confidence=75&lang_confidence=15&toxic=no&toxic_confidence=75`
 
-You can customize the parameter based on your needs. Check **Examples** for to get the gists of how to use nostr-filter-relay.
+Default values above will make relay filter events focus on **"General common users"** by serving **'family-friendly'** note events by default. However, we can customize the parameter (using single or multiple parameters) based on our needs. Check **Examples** to get the gists on how to use nostr-filter-relay.
 
 ## Examples
 
-The following are various examples of how to use nostr-filter-relay which illustrated by some (fictional or maybe factual) scenarios. Check **Advanced Usage** sections for more information about the parameters.
+The following are various examples on how to use nostr-filter-relay which illustrated by some (fictional or maybe factual) scenarios.
 
-Scenarios:
+### Content Type (SFW/NSFW) Filtering Example
 
 > **Note**
 >
@@ -62,6 +60,8 @@ Scenarios:
 >
 > Add `wss://nostr-id-relay.hf.space/?content=all`
 
+### User Type Filtering Example
+
 > **Note**
 >
 > "Hmm, i see some **bridged content** from activitypub/fediverse/mastodon (mostr.pub). I **don't want to see** any of them"
@@ -78,6 +78,8 @@ Scenarios:
 >
 > Add `wss://nostr-id-relay.hf.space/?user=activitypub`
 
+### Language Filtering Example
+
 > **Note**
 >
 > "Apaan nih isinya bule semua. Warga +62 mana suaranya ya?" (context simplified: I'm **Indonesian**)
@@ -94,6 +96,42 @@ Scenarios:
 >
 > Add `wss://nostr-id-relay.hf.space/?lang=zh,ja`
 
+### Hate speech (Toxic comments) Filtering Example
+
+> **Note**
+>
+> "I don't want to see any insult, vulgar comment, identity hate, or any toxic comments"
+>
+> **Answer**
+>
+> Add `wss://nostr-id-relay.hf.space/?toxic=no` (default value: no, valid value: no, yes, all)
+
+> **Note**
+>
+> "I don't care whether to see insult, vulgar comment, identity hate, or any toxic comments"
+>
+> **Answer**
+>
+> Add `wss://nostr-id-relay.hf.space/?toxic=all` (default value: no, valid value: no, yes, all)
+
+> **Note**
+>
+> "I want to see only insult, vulgar comment, identity hate, or any toxic comments"
+>
+> **Answer**
+>
+> Add `wss://nostr-id-relay.hf.space/?toxic=yes` (default value: no, valid value: no, yes, all)
+
+> **Note**
+>
+> "I don't want to see any insult, vulgar comment, identity hate, or any toxic comments. I want to set minimum probability score to be high (90% minimum score)."
+>
+> **Answer**
+>
+> Add `wss://nostr-id-relay.hf.space/?toxic=no&toxic_confidence=90` (default toxic_confidence: 75, valid value: 0-100)
+
+### Confidence Score Filtering Example
+
 > **Note**
 >
 > "There are still some **false positive** (Non-NSFW content is classified as NSFW) in your filter relay. I will adjust and **increase** the minimum confidence thresold percentage on my own."
@@ -118,6 +156,8 @@ Scenarios:
 >
 > Add `wss://nostr-id-relay.hf.space/?lang_confidence=65` (default value: 15, valid value: 0-100)
 
+### Multiple Parameters Filtering Example
+
 > **Note**
 >
 > "I want to see english content. It should be highly accurate"
@@ -134,6 +174,8 @@ Scenarios:
 >
 > Add `wss://nostr-id-relay.hf.space/?lang=ar&lang_confidence=90&content=sfw&nsfw_confidence=50&user=nostr` (multiple parameters)
 
+### Non Example
+
 > **Note**
 >
 > "Your filter relay software is sucks"
@@ -148,4 +190,4 @@ Scenarios:
 >
 > **Answer**
 >
-> Hi, feel free to add the relay into your nostr clients and adjust the parameters based on your need. It is up to **you/me/us/anyone** whether **you/me/us/anyone** want to add the relay or not. Have a good day, thank you :)
\ No newline at end of file
+> Hi, feel free to add the relay into your nostr clients and adjust the parameters based on your need. It is up to **you/me/us/anyone** whether **you/me/us/anyone** want to add the relay or not. Have a good day, thank you :)