diff --git a/.gitignore b/.gitignore index 9789028..91a1af7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ user_reposted_notes.json user_received_direct_messages.json user_reacted_notes.json user_data.json -user_contact_list.json \ No newline at end of file +user_contact_list.json +user_deleted_notes.json \ No newline at end of file diff --git a/README.md b/README.md index 16c1bf0..cab062b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Nostr Logo `NostrO` is designed for conducting *Open Source Intelligence* (OSINT) operations on [Nostr](https://nostr.com/). -NostrO facilitates operations such as retrieving relay infos, keyword search on notes filtered by user, and more. +NostrO facilitates operations such as retrieving relay or user infos, search on notes, and more. > **Warning** > The tool is currently in a very early and experimental phase. @@ -184,7 +184,7 @@ returned events saved to user_reposted_notes.json nostro notes --userreacted npub1rusgp3upyrtpsy2pcqznl6e8hejg9ne8u2eg05gzc4n2cctsugksvcx2np nos.lol returned events saved to user_reacted_notes.json ``` - - + +For all available command use the cli `help` function. diff --git a/internal/commands/notes.go b/internal/commands/notes.go index a7b1411..eca8835 100644 --- a/internal/commands/notes.go +++ b/internal/commands/notes.go @@ -16,6 +16,7 @@ var notesUserTagged bool var notesUserReposted bool var notesUserReacted bool var notesUserWritten bool +var notesUserDeletion bool var NotesCmd = &cobra.Command{ Use: "notes", @@ -235,6 +236,60 @@ var NotesCmd = &cobra.Command{ } else { panic(err) } + } else if notesUserDeletion { + if len(args) != 2 { + return fmt.Errorf("user npbu key and relay name are required") + } + npub := args[0] + url := args[1] + // connect to relay + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + relay, err := nostr.RelayConnect(ctx, url) + if err != nil { + panic(err) + } + // create filters + var filters nostr.Filters + if _, v, err := nip19.Decode(npub); err == nil { + t := make(map[string][]string) + // making a "p" tag for the above public key. + // this filters for messages tagged with the user, mainly replies. + t["p"] = []string{v.(string)} + filters = []nostr.Filter{{ + Kinds: []int{int(nostr.KindDeletion)}, + Authors: []string{v.(string)}, + //Tags: t, + Limit: 300, + }} + } else { + panic("not a valid npub!") + } + // create a subscription and submit to relay + // results will be returned on the sub.Events channel + sub, _ := relay.Subscribe(ctx, filters) + + // we will append the returned events to this slice + evs := make([]nostr.Event, 0) + + go func() { + <-sub.EndOfStoredEvents + cancel() + }() + for ev := range sub.Events { + evs = append(evs, *ev) + } + + filename := "user_deleted_notes.json" + if f, err := os.Create(filename); err == nil { + fmt.Fprintf(os.Stderr, "returned events saved to %s\n", filename) + // encode the returned events in a file + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + enc.Encode(evs) + f.Close() + } else { + panic(err) + } } else { cmd.Help() } @@ -247,4 +302,5 @@ func init() { NotesCmd.Flags().BoolVarP(¬esUserReposted, "userreposted", "", false, "Retrieve from the specified relay the last 300 notes from the specified user that have been reposted.") NotesCmd.Flags().BoolVarP(¬esUserReacted, "userreacted", "", false, "Retrieve from the specified relay the last 300 reaction received by notes from the specified user.") NotesCmd.Flags().BoolVarP(¬esUserWritten, "userwritten", "", false, "Retrieve from the specified relay the last 300 notes written by the specified user.") + NotesCmd.Flags().BoolVarP(¬esUserDeletion, "userdeletion", "", false, "Retrieve from the specified relay the last 300 notes deleted by the specified user.") }