From be0ced31b051fc219ca9fd338154f8aa078e5d01 Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Fri, 26 Jul 2024 01:11:41 +0000 Subject: [PATCH 1/6] build: update dependencies for topic classification --- Dockerfile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d24a50d..9ed0ea5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG DENO_VERSION=1.45.0 +ARG DENO_VERSION=1.45.3 FROM debian:bookworm AS builder_strfry WORKDIR /builder @@ -27,7 +27,7 @@ RUN apt update -y && \ rm -rf /var/lib/apt/lists/* # Prepare nostr-filter -ENV NOSTR_FILTER_COMMIT_HASH_VERSION=c7f955e491fa268d2abf9feb4a31f989ef76438b +ENV NOSTR_FILTER_COMMIT_HASH_VERSION=4d719299b88203754b952809e4f937e6fd66fc34 ENV NOSTR_FILTER_BRANCH=main RUN git clone --branch $NOSTR_FILTER_BRANCH https://github.com/atrifat/nostr-filter && \ cd /builder/nostr-filter && \ @@ -36,7 +36,7 @@ RUN git clone --branch $NOSTR_FILTER_BRANCH https://github.com/atrifat/nostr-fil npm ci --omit=dev && npx tsc # Prepare nostr-monitoring-tool -ENV NOSTR_MONITORING_TOOL_VERSION=v0.5.0 +ENV NOSTR_MONITORING_TOOL_VERSION=v0.6.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 @@ -102,6 +102,10 @@ ENV DEFAULT_FILTER_HATE_SPEECH_TOXIC_EVALUATION_MODE=max ENV DEFAULT_FILTER_SENTIMENT_MODE=all # (Default: 35, Options: 0-100) Default minimum probability/confidence score in percentage to determine the classification of sentiment ENV DEFAULT_FILTER_SENTIMENT_CONFIDENCE=35 +# (Default: all, Multiple Options: list of valid topic in atrifat/nostr-filter-relay Github) Multiple options separated by comma (eg: life,music,sport,science_and_technology => filter to get life (short version of: diaries_and_life), music, sport, science_and_technology) +ENV DEFAULT_FILTER_TOPIC_MODE=all +# (Default: 35, Options: 0-100) Default minimum probability/confidence score in percentage to determine the classification of topic +ENV DEFAULT_FILTER_TOPIC_CONFIDENCE=35 # (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 @@ -125,6 +129,11 @@ ENV SENTIMENT_ANALYSIS_ENDPOINT= ENV SENTIMENT_ANALYSIS_TOKEN= ENV SENTIMENT_ANALYSIS_TRUNCATE_LENGTH=350 +ENV ENABLE_TOPIC_CLASSIFICATION=true +ENV TOPIC_CLASSIFICATION_ENDPOINT= +ENV TOPIC_CLASSIFICATION_TOKEN= +ENV TOPIC_CLASSIFICATION_TRUNCATE_LENGTH=350 + ENV NOSTR_MONITORING_BOT_PRIVATE_KEY= ENV RELAYS_SOURCE= ENV RELAYS_TO_PUBLISH=ws://127.0.0.1:7777 From 6ce0406880c9ce8c542c9e2994917e7b44b97dfe Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Fri, 26 Jul 2024 02:16:24 +0000 Subject: [PATCH 2/6] chore: update .env.example for topic classification --- .env.example | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 2c7c950..6f82f2d 100644 --- a/.env.example +++ b/.env.example @@ -4,24 +4,36 @@ NODE_ENV=production ENABLE_NSFW_CLASSIFICATION=true NSFW_DETECTOR_ENDPOINT=http://localhost:8082/predict NSFW_DETECTOR_TOKEN= + 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 +# (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 + ENABLE_SENTIMENT_ANALYSIS=true # (Required if ENABLE_SENTIMENT_ANALYSIS == true) set this to your own sentiment-analysis-api instance (https://github.com/atrifat/sentiment-analysis-api) SENTIMENT_ANALYSIS_ENDPOINT=http://localhost:8084/predict -# (Optional) set this to your own sentiment-analysis-api api_key if required +# (Optional) set this to your own sentiment-analysis-api api_key if required SENTIMENT_ANALYSIS_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 SENTIMENT_ANALYSIS_TRUNCATE_LENGTH=350 + +ENABLE_TOPIC_CLASSIFICATION=true +# (Required if ENABLE_TOPIC_CLASSIFICATION == true) set this to your own topic-classification-api instance (https://github.com/atrifat/topic-classification-api) +TOPIC_CLASSIFICATION_ENDPOINT=http://localhost:8085/predict +# (Optional) set this to your own topic-classification-api api_key if required +TOPIC_CLASSIFICATION_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 +TOPIC_CLASSIFICATION_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 @@ -40,23 +52,33 @@ 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 + # (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, Multiple Options: all,negative,neutral,positive) Multiple options separated by comma (eg: neutral,positive => filter to get both neutral and positive sentiment) DEFAULT_FILTER_SENTIMENT_MODE=all # (Optional. Default: 35, Options: 0-100) Default minimum probability/confidence score in percentage to determine the classification of sentiment DEFAULT_FILTER_SENTIMENT_CONFIDENCE=35 + +# (Default: all, Multiple Options: list of valid topic in atrifat/nostr-filter-relay Github) Multiple options separated by comma (eg: life,music,sport,science_and_technology => filter to get life (short version of: diaries_and_life), music, sport, science_and_technology) +DEFAULT_FILTER_TOPIC_MODE=all +# (Default: 35, Options: 0-100) Default minimum probability/confidence score in percentage to determine the classification of topic +DEFAULT_FILTER_TOPIC_CONFIDENCE=35 + # (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 +DEFAULT_FILTER_USER_MODE=all From 18174bd57ae0b633d8194d3e398d5121c40e04e4 Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Fri, 26 Jul 2024 02:18:28 +0000 Subject: [PATCH 3/6] docs: update readme with topic classification and additional info --- README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 29fd8ef..2c12c58 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, hate speech (toxic comment), sentiment, and various rules. +A [Nostr](https://github.com/nostr-protocol/nostr) relay docker image package which filter content based on content type (SFW/NSFW), user type, language, hate speech (toxic comment), sentiment, topic, and various rules. This docker image consists of several software packages: @@ -8,11 +8,11 @@ This docker image consists of several software packages: - [atrifat/nostr-monitoring-tool](https://github.com/atrifat/nostr-monitoring-tool) as content classification tool - [hoytech/strfry](https://github.com/hoytech/strfry) as backend relay -Several dependencies including [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api), [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api), [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api), [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api) are required depend on the features that were enabled. +Several dependencies including [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api), [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api), [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api), [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api), [atrifat/topic-classification-api](https://github.com/atrifat/topic-classification-api) are required depend on the features that were enabled. ## Demo -A public demo (beta/test) instance is available on [wss://nfrelay.app](wss://nfrelay.app) or [ws://nfrelay6saohkmipikquvrn6d64dzxivhmcdcj4d5i7wxis47xwsriyd.onion](ws://nfrelay6saohkmipikquvrn6d64dzxivhmcdcj4d5i7wxis47xwsriyd.onion) (TOR Onion Hidden Service). +A public demo (beta/test) relay is available on [wss://nfrelay.app](wss://nfrelay.app) or [ws://nfrelay6saohkmipikquvrn6d64dzxivhmcdcj4d5i7wxis47xwsriyd.onion](ws://nfrelay6saohkmipikquvrn6d64dzxivhmcdcj4d5i7wxis47xwsriyd.onion) (TOR Onion Hidden Service). ## Usage @@ -27,7 +27,7 @@ A relay software package that filter note (kind: 1) contents in various category - [x] User type filtering (Nostr user/non bridged user, activitypub bridged user) - [x] Hate speech (Toxic comment) detection - [x] Sentiment analysis -- [ ] (WIP) Topic classification +- [x] 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) ## How it works @@ -35,7 +35,7 @@ A relay software package that filter note (kind: 1) contents in various category ![nostr-filter-relay-flowchart](resources/flowchart-nostr-filter-relay.png) 1. **nostr-filter-relay** is docker image that will run several softwares: [atrifat/nostr-monitoring-tool](https://github.com/atrifat/nostr-monitoring-tool), [atrifat/nostr-filter](https://github.com/atrifat/nostr-filter), and [hoytech/strfry](https://github.com/atrifat/nostr-filter) relay in launch script at startup. -2. **nostr-monitoring-tool** is classification tool that fetch and subscribe notes (kind: 1) from various relays. It will process every notes (extraction of image url, text preprocessing) that were seen and send them into external AI classification tool. Currently, it will send processed notes content into NSFW Detector API instance (using [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api)), Language Detector API instance (using [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate)), Hate Speech Detector API instance (using [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api)), and Sentiment Analysis API instance (using [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api)). All four API services will give classification results (SFW/NSFW classification, Language classfication, Toxic classification, Sentiment Analysis) that will be saved as **custom kind 9978** in local strfry relay that has already been running. Data format is shown in [atrifat/nostr-monitoring-tool](https://github.com/atrifat/nostr-monitoring-tool) repository. +2. **nostr-monitoring-tool** is classification tool that fetch and subscribe notes (kind: 1) from various relays. It will process every notes (extraction of image url, text preprocessing) that were seen and send them into external AI classification tool. Currently, it will send processed notes content into NSFW Detector API instance (using [atrifat/nsfw-detector-api](https://github.com/atrifat/nsfw-detector-api)), Language Detector API instance (using [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate)), Hate Speech Detector API instance (using [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api)), Sentiment Analysis API instance (using [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api)), and Topic Classification API instance (using [atrifat/topic-classification-api](https://github.com/atrifat/topic-classification-api)). All five API services will give classification results (SFW/NSFW classification, Language classfication, Toxic classification, Sentiment Analysis, Topic Classification) that will be saved as **custom kind 9978** in local strfry relay that has already been running. Data format is shown in [atrifat/nostr-monitoring-tool](https://github.com/atrifat/nostr-monitoring-tool) repository. Basic Data flow: **Source Relays (notes) -> nostr-monitoring-tool (connect to external API for classification) -> local strfry** @@ -56,6 +56,7 @@ The following softwares are required if you want to run your own nostr-filter-re - Personal instance of [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate). Check [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [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. - Personal instance of [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api). Check [atrifat/sentiment-analysis-api](https://github.com/atrifat/hate-speech-detector-api) Github repository for more instructions. +- Personal instance of [atrifat/topic-classification-api](https://github.com/atrifat/topic-classification-api). Check [atrifat/topic-classification-api](https://github.com/atrifat/topic-classification-api) Github repository for more instructions. ## Getting Started @@ -66,7 +67,7 @@ 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), [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate), [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api), and [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api). You don't have to run all of them only if you enable classification for certain task (Example: NSFW detection only). +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), [atrifat/language-detector-api](https://github.com/atrifat/language-detector-api) or [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate), [atrifat/hate-speech-detector-api](https://github.com/atrifat/hate-speech-detector-api), [atrifat/sentiment-analysis-api](https://github.com/atrifat/sentiment-analysis-api), and [atrifat/topic-classification-api](https://github.com/atrifat/topic-classification-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. @@ -106,6 +107,15 @@ or run it in the background (daemon): docker run --init --env-file .env -p 7860:7860 -it --name nostr-filter-relay -d nostr-filter-relay ``` +## Support + +Development of nostr-filter-relay has been supported by [OpenSats - Fifth Nostr Grant - July 2024](https://opensats.org/blog/nostr-grants-july-2024). + +You can also support this project by: + +- ⭐ Starring the repo, reporting issue, or sending the pull requests. +- ⚡️ Sending some sats or paying my tea to my lightning address: [rifat@getalby.com](lightning:rifat@getalby.com) + ## License MIT License @@ -133,10 +143,3 @@ SOFTWARE. ## Author Rif'at Ahdi Ramadhani (atrifat) - -## Support - -You can support this project by: - -- ⭐ Starring the repo, reporting issue, and sending the pull requests. -- ⚡️ Sending some sats to my lightning address: [rifat@getalby.com](lightning:rifat@getalby.com) From 3c3fecdddb1197445c4bbdfe6033aa9c72115cfb Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Tue, 30 Jul 2024 01:49:59 +0000 Subject: [PATCH 4/6] docs: update relay usage with topic filter example --- USAGE.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/USAGE.md b/USAGE.md index c13ad55..3b9d680 100644 --- a/USAGE.md +++ b/USAGE.md @@ -6,11 +6,11 @@ nostr-filter-relay can be used and activated as relay for "Global" feed in our N If we don't add any parameter (?) behind the url of `wss://nfrelay.app` then it is equal to using relay with parameters using its default parameter values: -`wss://nfrelay.app/?user=all&lang=all&content=sfw&nsfw_confidence=75&lang_confidence=15&toxic=no&toxic_confidence=75&sentiment=all&sentiment_confidence=35` +`wss://nfrelay.app/?user=all&lang=all&content=sfw&nsfw_confidence=75&lang_confidence=15&toxic=no&toxic_confidence=75&sentiment=all&sentiment_confidence=35&topic=all&topic_confidence=35` -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. +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 **[Advanced Usage](#advanced-usage)** to get the gists on how to use nostr-filter-relay in various settings. -## Examples +## Advanced Usage The following are various examples on how to use nostr-filter-relay which illustrated by some (fictional or maybe factual) scenarios. @@ -156,6 +156,58 @@ The following are various examples on how to use nostr-filter-relay which illust > > Add `wss://nfrelay.app/?sentiment=neutral&sentiment_confidence=70` (default value: 35, valid value: 0-100) +### Topic Filtering Example + +> **Note** +> +> "I prefer getting updates on news, business information, and technology." +> +> **Answer** +> +> Add `wss://nfrelay.app/?topic=news,business,technology` (short version) or `wss://nfrelay.app/?topic=news_and_social_concern,business_and_entrepreneurs,science_and_technology` if user want to state clearly the topic category. List of known topics were provided [below](#known-topic-category). + +> **Note** +> +> "My favorite discussions are related to music and sport." +> +> **Answer** +> +> Add `wss://nfrelay.app/?topic=music,sport` + +> **Note** +> +> "I want my feeds focused on game with minimum confidence score is 70%" +> +> **Answer** +> +> Add `wss://nfrelay.app/?topic=gaming&topic_confidence=70` (default confidence value: 35, valid value: 0-100) + +#### Known Topic Category + +List of currently known topic category in nostr-filter-relay were listed as follows: + +1. **arts_and_culture** (short version: "**art**" or "**culture**") +2. **business_and_entrepreneurs** (short version: "**business**" or "**entrepreneur**") +3. **celebrity_and_pop_culture** (short version: "**celebrity**" or "**pop**") +4. **diaries_and_daily_life** (short version: "**diaries**" or "**daily**") +5. **family** +6. **fashion_and_style** (short version: "**fashion**" or "**style**") +7. **film_tv_and_video** (short version: "**film**", or "**tv**", or "**video**") +8. **fitness_and_health** (short version: "**fitness**" or "**health**") +9. **food_and_dining** (short version: "**food**" or "**dining**") +10. **gaming** +11. **learning_and_educational** (short version: "**learning**" or "**educational**") +12. **music** +13. **news_and_social_concern** (short version: "**news**" or "**social**") +14. **other_hobbies** +15. **relationships** +16. **science_and_technology** (short version: "**science**" or "**technology**") +17. **sports** +18. **travel_and_adventure** (short version: "**travel**" or "**adventure**") +19. **youth_and_student_life** (short version: "**youth**" or "**student**") + +Topic classification were categorized based on previous research from [Cardiff University - Twitter Topic Classification](https://huggingface.co/cardiffnlp/twitter-roberta-base-dec2021-tweet-topic-multi-all). + ### Confidence Score Filtering Example > **Note** @@ -200,7 +252,7 @@ The following are various examples on how to use nostr-filter-relay which illust > > Add `wss://nfrelay.app/?lang=ar&lang_confidence=90&content=sfw&nsfw_confidence=50&user=nostr` (multiple parameters) -### Non Example +## Non Example > **Note** > From a022eb8e717f8d4502f6d7c0fe8c55d2dfdb57f8 Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Tue, 30 Jul 2024 01:51:47 +0000 Subject: [PATCH 5/6] docs: update relay usage with toc and relay setting figure --- USAGE.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/USAGE.md b/USAGE.md index 3b9d680..24652e3 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,9 +1,27 @@ # Relay Usage +## Table of Content + +- [Table of Content](#table-of-content) +- [Basic Usage](#basic-usage) +- [Advanced Usage](#advanced-usage) + - [Content Type (SFW/NSFW) Filtering Example](#content-type-sfwnsfw-filtering-example) + - [User Type Filtering Example](#user-type-filtering-example) + - [Language Filtering Example](#language-filtering-example) + - [Hate speech (Toxic comments) Filtering Example](#hate-speech-toxic-comments-filtering-example) + - [Sentiment Filtering Example](#sentiment-filtering-example) + - [Topic Filtering Example](#topic-filtering-example) + - [Known Topic Category](#known-topic-category) + - [Confidence Score Filtering Example](#confidence-score-filtering-example) + - [Multiple Parameters Filtering Example](#multiple-parameters-filtering-example) +- [Non Example](#non-example) + ## Basic Usage nostr-filter-relay can be used and activated as relay for "Global" feed in our Nostr clients. Simply add `wss://nfrelay.app` (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. +![relay-setting-amethyst-example](resources/relay-setting-amethyst.jpg) + If we don't add any parameter (?) behind the url of `wss://nfrelay.app` then it is equal to using relay with parameters using its default parameter values: `wss://nfrelay.app/?user=all&lang=all&content=sfw&nsfw_confidence=75&lang_confidence=15&toxic=no&toxic_confidence=75&sentiment=all&sentiment_confidence=35&topic=all&topic_confidence=35` From d51781e8cf3564fb6db9300b54222f528bd67c89 Mon Sep 17 00:00:00 2001 From: Rif'at Ahdi R <10791791+atrifat@users.noreply.github.com> Date: Tue, 30 Jul 2024 01:53:17 +0000 Subject: [PATCH 6/6] chore: add relay setting image example --- resources/relay-setting-amethyst.jpg | Bin 0 -> 47116 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/relay-setting-amethyst.jpg diff --git a/resources/relay-setting-amethyst.jpg b/resources/relay-setting-amethyst.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1e5d966a2a9888797391ea530cc0f23d46e94ddc GIT binary patch literal 47116 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