This server moderates Nostr notes by analyzing direct messages to the Reportinator bot account. It uses the NIP-17 standard to process "gift-wrapped" messages with a JSON payload detailing the event. Flagged messages lead to the creation of kind 1984 reports, available via wss://relay.nos.social
, for client-side moderation.
The server employs the actor model via ractor
for streamlined component communication. This strategy simplifies handling thread safety, concurrency, and ensures components are decoupled and responsibilities are isolated. It also supports asynchronous processing for a maintainable codebase.
System Architecture Diagram:
┌────────────────────────────┐ ┌───────────────────────┐ ┌──────────────────────┐
│ ┌───────────────────────┐ │ OpenAI │ Cleanstr │ Not flagged │ Manual Moderation │
│ │wss://relay.nos.social │◀─┼───Report ────│(Google Cloud Function)│───by OpenAI─────▶│ Slack Channel │
│ └────────────────────▲──┘ │ Event └───────────────────────┘ └────▲─────────────────┘
│ │ │ ▲ │ │
│ Nostr Network │ │ │ │ │
│ │ │ ┌────────────────┐ │ │
│ ┌─────────────┐ │ │ │ nostr-events │ │ │
│ │Encrypted DM │ │ │ │ Pubsub Topic │ │ │
│ └─────────────┘ │ │ └────────────────┘ │ │
│ │ │ │ ▲ │ │
└─────────────┼────────┼─────┘ │ │ │
│ │ ┌────────────┼───────────────────────────────────┼──────┼──────────┐
│ │ │ ┌──────────┴──────────┐ ┌──────────────────┴──┐ │ │
│ │ │ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ │ GooglePublisher │ │ │ │ SlackClient │ │ │ │
Gift │ │ │ └─────────────────┘ │ │ └─────────────────┘ │ │ │
Wrapped │ │ │ EventEnqueuer │ │ SlackWriter │ │ │
DM with │ │ └─────────────────────┘ └─────────────────────┘ Report │
Report Manual │ ▲ ▲ Request │
Request Report │ │ │ │ │
│ Event │ note │ │ │
│ │ │ report │ │ │
│ │ │ request │ │ │
│ │ │ │ │ │ │
│ │ │ ┌────────────────────┐ npub │ │ │
│ │ │ │ GiftUnwrapper │───report ───────┘ │ │
│ │ │ └────────────────────┘ request │ │
│ │ │ ▲ │ │
│ │ │ │ │ │
│ │ │┌──────────────────────┐ ┌──────────▼────────┐ │
│ │ ││┌────────────────────┐│ │ ┌────────────────┐│ │
│ └───────────────────┼┼┤ NostrService ││ Manual │ │ Slack endpoint ││ │
└────────────────────────────┼▶│ ││◀─────Label─────────┼─│ ││ │
││└────────────────────┘│ │ └────────────────┘│ │
││ RelayEventDispatcher │ │ Axum HTTP server │ │
│└──────────────────────┘ └───────────────────┘ │
│ Reportinator Server │
└──────────────────────────────────────────────────────────────────┘
The NostrService
listens for direct messages sent to the Reportinator account, which contain requests for the moderation of specific Nostr notes. These requests are then forwarded to the GiftUnwrapper
for initial processing in accordance with the NIP-17 standard.
After processing, the GiftUnwrapper
sends the validated and extracted messages as moderation requests to the EventEnqueuer
. This component utilizes the GooglePublisher
to publish the reports to a designated Google PubSub topic, intended for moderation request analysis on nos.social. Npub report requests skip the google topic and are posted directly to the Slack channel
It's noteworthy that this PubSub topic also consolidates moderation requests from various sources, thereby positioning this server as one among several entry points.
A Google Cloud Function linked to this topic employs AI to analyze these reports. Reports are either directly published to wss://relay.nos.social
if automatically flagged, or forwarded to a Slack channel for manual review. If flagged during the manual review, they are anonymously published through the Reportinator account back into the Nostr network.
Ensure these environment variables are set before running the Reportinator Server:
RELAY_ADDRESSES_CSV
: A comma-separated list of relay addresses for listening to direct messages.REPORTINATOR_SECRET
: The Reportinator bot's secret public key for message authentication and decryption.GOOGLE_APPLICATION_CREDENTIALS
: Path to the Google Cloud credentials file for Google Cloud PubSub topic access.SLACK_SIGNING_SECRET
: The Slack app signing secret.
-
Local Nostr Relay: Start a Nostr relay at
ws://localhost
. -
Google Cloud Access: Authenticate with Google Cloud:
gcloud auth application-default login
This command generates a credentials file, indicated by the
GOOGLE_APPLICATION_CREDENTIALS
environment variable. -
Docker Compose: With Docker set up, launch the server:
docker compose up
The server will then listen for moderation requests and publish reports to the Google Cloud PubSub topic.
Contributions are welcome! Fork the project, submit pull requests, or report issues.
This project is licensed under the MIT License. See the LICENSE file for details.