1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::user::CaracalUser;
use nostr_sdk::prelude::*;
use std::sync::Arc;
use std::time::Duration;
pub async fn user_subscribe(user: &CaracalUser) {
let Ok(contacts) =
user.client.get_contact_list(Duration::from_secs(5)).await
else {
eprintln!("Failed to retrieve contact list");
return;
};
let now = Timestamp::now();
let sub_id = SubscriptionId::new("user");
user.client.connect().await;
user.client.unsubscribe(&sub_id).await;
let subscription = Filter::new()
.kind(Kind::RelayList)
.kind(Kind::InboxRelays)
.kind(Kind::Metadata)
.kind(Kind::ContactList)
.kind(Kind::TextNote)
.kind(Kind::LongFormTextNote)
.kind(Kind::Reaction)
.since(now - (86400 * 120))
.authors(contacts.into_iter().map(|c| c.public_key));
if let Err(e) = user
.client
.subscribe_with_id(sub_id, subscription, None)
.await
{
eprintln!("Error subscribing: {e}")
}
}
pub async fn handle_nostr_notifications(
client: Arc<Client>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
client
.handle_notifications(|notification| async {
if let RelayPoolNotification::Event {
relay_url: _,
subscription_id: _,
event,
} = notification
{
match event.kind {
Kind::TextNote => {
if let Err(err) = client
.subscribe(
Filter::new()
.kind(Kind::Metadata)
.author(event.pubkey)
.limit(1),
None,
)
.await
{
eprintln!("Metadata sub failed: {err}");
}
}
Kind::RelayList => {
for (url, _metadata) in
nip65::extract_relay_list(&event)
{
let Ok(_) = client.add_discovery_relay(url).await
else {
continue;
};
let Ok(_) = client.add_read_relay(url).await else {
continue;
};
}
}
_ => {}
}
} else if let RelayPoolNotification::Message {
relay_url: _,
message,
} = notification
&& let RelayMessage::Event {
subscription_id: _,
ref event,
} = message
{
if let Kind::RelayList = event.kind {
for (url, _metadata) in
nip65::extract_relay_list(event)
{
let Ok(_) =
client.add_discovery_relay(url).await
else {
continue;
};
let Ok(_) = client.add_read_relay(url).await
else {
continue;
};
}
}
}
Ok(false)
})
.await?;
Ok(())
}