Skip to content

Commit

Permalink
Supports publishing to multiple nostr relay (#318)
Browse files Browse the repository at this point in the history
* Supports publishing to multiple nostr relay

* Recover panic

* Refine parameter
  • Loading branch information
waybackarchiver authored Feb 21, 2023
1 parent 8d3da0b commit 7060849
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 28 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ You can also specify configuration options either via command flags or via envir
| - | `WAYBACK_SLACK_BOT_TOKEN` | - | `Bot User OAuth Token` for Slack workspace, use `User OAuth Token` if requires create external link |
| - | `WAYBACK_SLACK_CHANNEL` | - | Channel ID of Slack channel |
| - | `WAYBACK_SLACK_HELPTEXT` | - | The help text for Slack slash command |
| - | `WAYBACK_NOSTR_RELAY_URL` | `wss://nostr.developer.li` | Nostr relay server url |
| - | `WAYBACK_NOSTR_PRIVATE_KEY` | - | The private key of a Nostr account |
| - | `WAYBACK_NOSTR_RELAY_URL` | `wss://nostr.developer.li` | Nostr relay server url, multiple separated by comma |
| - | `WAYBACK_NOSTR_PRIVATE_KEY` | - | The private key of a Nostr account |
| `--tor` | `WAYBACK_USE_TOR` | `false` | Snapshot webpage via Tor anonymity network |
| `--tor-key` | `WAYBACK_TOR_PRIVKEY` | - | The private key for Tor Hidden Service |
| - | `WAYBACK_TOR_LOCAL_PORT` | `8964` | Local port for Tor Hidden Service, also support for a **reverse proxy**. This is ignored if `WAYBACK_LISTEN_ADDR` is set. |
Expand Down
13 changes: 8 additions & 5 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1285,19 +1285,19 @@ func TestPublishToSlackChannel(t *testing.T) {
func TestNostrRelayURL(t *testing.T) {
var tests = []struct {
url string
exp string
exp []string
}{
{
url: "",
exp: defNostrRelayURL,
exp: []string{defNostrRelayURL},
},
{
url: "wss://example.com",
exp: "wss://example.com",
exp: []string{"wss://example.com"},
},
{
url: "example.com",
exp: "example.com",
exp: []string{"example.com"},
},
}

Expand All @@ -1313,7 +1313,10 @@ func TestNostrRelayURL(t *testing.T) {
}

got := opts.NostrRelayURL()
if got != test.exp {
if len(got) < 1 {
t.Fatalf(`Unexpected set nostr relay url, got %v instead of %v`, got, test.exp)
}
if got[0] != test.exp[0] {
t.Fatalf(`Unexpected set nostr relay url, got %v instead of %v`, got, test.exp)
}
})
Expand Down
6 changes: 3 additions & 3 deletions config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,8 @@ func (o *Options) PublishToNotion() bool {
}

// NostrRelayURL returns the relay url of Nostr server.
func (o *Options) NostrRelayURL() string {
return o.nostr.url
func (o *Options) NostrRelayURL() []string {
return strings.Split(o.nostr.url, ",")
}

// NostrPrivateKey returns the private key of Nostr account.
Expand All @@ -664,7 +664,7 @@ func (o *Options) NostrPrivateKey() string {

// PublishToNostr determines whether the results should be published on Nostr.
func (o *Options) PublishToNostr() bool {
return o.NostrRelayURL() != "" && o.NostrPrivateKey() != ""
return len(o.NostrRelayURL()) > 0 && o.NostrPrivateKey() != ""
}

// TorPrivKey returns the private key of Tor service.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/iawia002/lux v0.14.0
github.com/jedib0t/go-pretty/v6 v6.4.0
github.com/mattn/go-mastodon v0.0.5-0.20210515144304-86627ec7d635
github.com/nbd-wtf/go-nostr v0.13.1-0.20230205201056-ab2db2dfc5d9
github.com/nbd-wtf/go-nostr v0.13.1
github.com/phf/go-queue v0.0.0-20170504031614-9abe38d0371d
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,8 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nbd-wtf/go-nostr v0.13.1-0.20230205201056-ab2db2dfc5d9 h1:YIJjaVL5Xogzq7mEeJauXGMumE6IZJSAcBb42mF5eJo=
github.com/nbd-wtf/go-nostr v0.13.1-0.20230205201056-ab2db2dfc5d9/go.mod h1:qFFTIxh15H5GGN0WsBI/P73DteqsevnhSEW/yk8nEf4=
github.com/nbd-wtf/go-nostr v0.13.1 h1:YwjO5fhipinxOZ7MQztFhaHCLfUoCc36skEJ36dWwVg=
github.com/nbd-wtf/go-nostr v0.13.1/go.mod h1:qFFTIxh15H5GGN0WsBI/P73DteqsevnhSEW/yk8nEf4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
Expand Down
44 changes: 30 additions & 14 deletions publish/nostr.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/wabarc/wayback/errors"
"github.com/wabarc/wayback/metrics"
"github.com/wabarc/wayback/template/render"
"golang.org/x/sync/errgroup"
)

var _ Publisher = (*nostrBot)(nil)
Expand All @@ -33,10 +34,6 @@ func NewNostr(client *nostr.Relay) *nostrBot {
return new(nostrBot)
}

if client == nil {
client = relayConnect(config.Opts.NostrRelayURL())
}

return &nostrBot{client: client}
}

Expand Down Expand Up @@ -64,12 +61,9 @@ func (n *nostrBot) Publish(ctx context.Context, cols []wayback.Collect, args ...
}

func (n *nostrBot) publish(ctx context.Context, note string) error {
if !config.Opts.PublishToNostr() || n.client == nil {
if !config.Opts.PublishToNostr() {
return fmt.Errorf("publish to nostr abort")
}
if n.client.Connection == nil {
return fmt.Errorf("publish to nostr failed: %v", <-n.client.ConnectionError)
}

if note == "" {
return fmt.Errorf("nostr validation failed: note can't be blank")
Expand Down Expand Up @@ -98,17 +92,39 @@ func (n *nostrBot) publish(ctx context.Context, note string) error {
if err := ev.Sign(sk); err != nil {
return fmt.Errorf("calling sign err: %v", err)
}
// send the text note
status := n.client.Publish(ctx, ev)
if status != nostr.PublishStatusSucceeded {
return fmt.Errorf("published status is %s, not %s", status, nostr.PublishStatusSucceeded)

g, ctx := errgroup.WithContext(ctx)
for _, relay := range config.Opts.NostrRelayURL() {
logger.Debug(`publish note to relay: %s`, relay)
relay := relay
g.Go(func() error {
defer func() {
// recover from upstream panic
if r := recover(); r != nil {
logger.Error("publish to %s failed: %v", relay, r)
}
}()
client := relayConnect(ctx, relay)
if client.Connection == nil {
return fmt.Errorf("publish to %s failed: %v", relay, <-client.ConnectionError)
}
// send the text note
status := client.Publish(ctx, ev)
if status != nostr.PublishStatusSucceeded {
return fmt.Errorf("published to %s status is %s, not %s", relay, status, nostr.PublishStatusSucceeded)
}
return nil
})
}
if err := g.Wait(); err != nil {
return err
}

return nil
}

func relayConnect(url string) *nostr.Relay {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
func relayConnect(ctx context.Context, url string) *nostr.Relay {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
relay, err := nostr.RelayConnect(ctx, url)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion wayback.1
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ Notion integration token\&.
Notion database ID for archiving results\&.
.TP
.B WAYBACK_NOSTR_RELAY_URL
Nostr relay server url\&.
Nostr relay server url, multiple separated by comma\&.
.TP
.B WAYBACK_NOSTR_PRIVATE_KEY
The private key of a Nostr account\&.
Expand Down

0 comments on commit 7060849

Please sign in to comment.