forked from coracle/caravel
Fix relay selection
This commit is contained in:
@@ -8,15 +8,14 @@ Members:
|
|||||||
- `name: String` - the name of the bot, from `ROBOT_NAME`
|
- `name: String` - the name of the bot, from `ROBOT_NAME`
|
||||||
- `description: String` - the description of the bot, from `ROBOT_DESCRIPTION`
|
- `description: String` - the description of the bot, from `ROBOT_DESCRIPTION`
|
||||||
- `picture: String` - the picture URL for the bot, from `ROBOT_PICTURE`
|
- `picture: String` - the picture URL for the bot, from `ROBOT_PICTURE`
|
||||||
- `outbox_relays: Vec<String>` - outbox relay URLs, from `ROBOT_OUTBOX_RELAYS`
|
- `outbox_client: nostr_sdk::Client` - used for publishing relay lists and metadata, connects to `ROBOT_OUTBOX_RELAYS`
|
||||||
- `indexer_relays: Vec<String>` - indexer relay URLs, from `ROBOT_INDEXER_RELAYS`
|
- `indexer_client: nostr_sdk::Client` - used for publishing relay lists, connects to `ROBOT_INDEXER_RELAYS`
|
||||||
- `messaging_relays: Vec<String>` - messaging relay URLs, from `ROBOT_MESSAGING_RELAYS`
|
- `messagins_client: nostr_sdk::Client` - used for sending and receiving dms, connects to `ROBOT_MESSAGING_RELAYS`
|
||||||
- `client: nostr_sdk::Client`
|
|
||||||
|
|
||||||
## `pub fn new() -> Self`
|
## `pub fn new() -> Self`
|
||||||
|
|
||||||
- Reads environment and populates members. Relay urls should be split and normalized.
|
- Reads environment and populates members. Relay urls should be split and normalized.
|
||||||
- Publishes a `kind 0` nostr profile, a `kind 10002` relay list, and `kind 10050` relay selections using `client`
|
- Publishes a `kind 0` nostr profile, a `kind 10002` relay list, and `kind 10050` relay selections
|
||||||
|
|
||||||
## `pub async fn send_dm(&self, recipient: &str, message: &str) -> Result<()>`
|
## `pub async fn send_dm(&self, recipient: &str, message: &str) -> Result<()>`
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -16,9 +16,8 @@ pub struct Repo {
|
|||||||
|
|
||||||
impl Repo {
|
impl Repo {
|
||||||
pub async fn new() -> Result<Self> {
|
pub async fn new() -> Result<Self> {
|
||||||
let raw_database_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
|
let raw_database_url = std::env::var("DATABASE_URL")
|
||||||
format!("sqlite://{}/data/caravel.db", env!("CARGO_MANIFEST_DIR"))
|
.unwrap_or_else(|_| format!("sqlite://{}/data/caravel.db", env!("CARGO_MANIFEST_DIR")));
|
||||||
});
|
|
||||||
let database_url = normalize_sqlite_url(&raw_database_url);
|
let database_url = normalize_sqlite_url(&raw_database_url);
|
||||||
|
|
||||||
if let Some(path) = database_url.strip_prefix("sqlite://")
|
if let Some(path) = database_url.strip_prefix("sqlite://")
|
||||||
@@ -30,7 +29,8 @@ impl Repo {
|
|||||||
std::fs::create_dir_all(parent)?;
|
std::fs::create_dir_all(parent)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let connect_options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true);
|
let connect_options =
|
||||||
|
SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true);
|
||||||
|
|
||||||
let pool = SqlitePoolOptions::new()
|
let pool = SqlitePoolOptions::new()
|
||||||
.max_connections(5)
|
.max_connections(5)
|
||||||
|
|||||||
+34
-39
@@ -11,10 +11,9 @@ pub struct Robot {
|
|||||||
name: String,
|
name: String,
|
||||||
description: String,
|
description: String,
|
||||||
picture: String,
|
picture: String,
|
||||||
outbox_relays: Vec<String>,
|
outbox_client: Client,
|
||||||
indexer_relays: Vec<String>,
|
indexer_client: Client,
|
||||||
messaging_relays: Vec<String>,
|
messaging_client: Client,
|
||||||
client: Client,
|
|
||||||
outbox_cache: std::sync::Arc<Mutex<HashMap<String, CacheEntry>>>,
|
outbox_cache: std::sync::Arc<Mutex<HashMap<String, CacheEntry>>>,
|
||||||
dm_cache: std::sync::Arc<Mutex<HashMap<String, CacheEntry>>>,
|
dm_cache: std::sync::Arc<Mutex<HashMap<String, CacheEntry>>>,
|
||||||
}
|
}
|
||||||
@@ -49,37 +48,33 @@ impl Robot {
|
|||||||
return Err(anyhow!("ROBOT_MESSAGING_RELAYS is required"));
|
return Err(anyhow!("ROBOT_MESSAGING_RELAYS is required"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let keys = Keys::parse(&secret)?;
|
let outbox_client = client_with_relays(&secret, &outbox_relays).await?;
|
||||||
let client = Client::new(keys);
|
let indexer_client = client_with_relays(&secret, &indexer_relays).await?;
|
||||||
for relay in &outbox_relays {
|
let messaging_client = client_with_relays(&secret, &messaging_relays).await?;
|
||||||
client.add_relay(relay).await?;
|
|
||||||
}
|
|
||||||
for relay in &indexer_relays {
|
|
||||||
client.add_relay(relay).await?;
|
|
||||||
}
|
|
||||||
for relay in &messaging_relays {
|
|
||||||
client.add_relay(relay).await?;
|
|
||||||
}
|
|
||||||
client.connect().await;
|
|
||||||
|
|
||||||
let robot = Self {
|
let robot = Self {
|
||||||
secret,
|
secret,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
picture,
|
picture,
|
||||||
outbox_relays,
|
outbox_client,
|
||||||
indexer_relays,
|
indexer_client,
|
||||||
messaging_relays,
|
messaging_client,
|
||||||
client,
|
|
||||||
outbox_cache: std::sync::Arc::new(Mutex::new(HashMap::new())),
|
outbox_cache: std::sync::Arc::new(Mutex::new(HashMap::new())),
|
||||||
dm_cache: std::sync::Arc::new(Mutex::new(HashMap::new())),
|
dm_cache: std::sync::Arc::new(Mutex::new(HashMap::new())),
|
||||||
};
|
};
|
||||||
|
|
||||||
robot.publish_identity().await?;
|
robot
|
||||||
|
.publish_identity(&outbox_relays, &messaging_relays)
|
||||||
|
.await?;
|
||||||
Ok(robot)
|
Ok(robot)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn publish_identity(&self) -> Result<()> {
|
async fn publish_identity(
|
||||||
|
&self,
|
||||||
|
outbox_relays: &[String],
|
||||||
|
messaging_relays: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
let mut metadata = Metadata::new();
|
let mut metadata = Metadata::new();
|
||||||
if !self.name.is_empty() {
|
if !self.name.is_empty() {
|
||||||
metadata = metadata.name(&self.name);
|
metadata = metadata.name(&self.name);
|
||||||
@@ -91,25 +86,24 @@ impl Robot {
|
|||||||
metadata = metadata.picture(Url::parse(&self.picture)?);
|
metadata = metadata.picture(Url::parse(&self.picture)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.client
|
self.outbox_client
|
||||||
.send_event_builder(EventBuilder::metadata(&metadata))
|
.send_event_builder(EventBuilder::metadata(&metadata))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let outbox_tags = self
|
let outbox_tags = outbox_relays
|
||||||
.outbox_relays
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| Tag::parse(["r", r.as_str()]))
|
.map(|r| Tag::parse(["r", r.as_str()]))
|
||||||
.collect::<std::result::Result<Vec<_>, _>>()?;
|
.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||||
self.client
|
self.outbox_client
|
||||||
.send_event_builder(EventBuilder::new(Kind::Custom(10002), "").tags(outbox_tags))
|
.send_event_builder(EventBuilder::new(Kind::Custom(10002), "").tags(outbox_tags))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut selection_tags = Vec::new();
|
let messaging_tags = messaging_relays
|
||||||
for relay in &self.messaging_relays {
|
.iter()
|
||||||
selection_tags.push(Tag::parse(["relay", relay.as_str()])?);
|
.map(|r| Tag::parse(["relay", r.as_str()]))
|
||||||
}
|
.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||||
self.client
|
self.indexer_client
|
||||||
.send_event_builder(EventBuilder::new(Kind::Custom(10050), "").tags(selection_tags))
|
.send_event_builder(EventBuilder::new(Kind::Custom(10050), "").tags(messaging_tags))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -129,10 +123,9 @@ impl Robot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let recipient_pubkey = PublicKey::parse(recipient)?;
|
let recipient_pubkey = PublicKey::parse(recipient)?;
|
||||||
let keys = Keys::parse(&self.secret)?;
|
let client = self.messaging_client.clone();
|
||||||
let client = Client::new(keys);
|
|
||||||
for relay in dm_relays {
|
for relay in dm_relays {
|
||||||
client.add_relay(relay).await?;
|
let _ = client.add_relay(relay).await;
|
||||||
}
|
}
|
||||||
client.connect().await;
|
client.connect().await;
|
||||||
client
|
client
|
||||||
@@ -147,9 +140,11 @@ impl Robot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pubkey = PublicKey::parse(recipient)?;
|
let pubkey = PublicKey::parse(recipient)?;
|
||||||
let client = indexer_client(&self.secret, &self.indexer_relays).await?;
|
|
||||||
let filter = Filter::new().author(pubkey).kind(Kind::Custom(10002));
|
let filter = Filter::new().author(pubkey).kind(Kind::Custom(10002));
|
||||||
let events = client.fetch_events(filter, Duration::from_secs(5)).await?;
|
let events = self
|
||||||
|
.indexer_client
|
||||||
|
.fetch_events(filter, Duration::from_secs(5))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut relays = Vec::new();
|
let mut relays = Vec::new();
|
||||||
if let Some(event) = events.into_iter().max_by_key(|e| e.created_at) {
|
if let Some(event) = events.into_iter().max_by_key(|e| e.created_at) {
|
||||||
@@ -221,10 +216,10 @@ fn normalize_relay_url(url: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn indexer_client(secret: &str, indexer_relays: &[String]) -> Result<Client> {
|
async fn client_with_relays(secret: &str, relays: &[String]) -> Result<Client> {
|
||||||
let keys = Keys::parse(secret)?;
|
let keys = Keys::parse(secret)?;
|
||||||
let client = Client::new(keys);
|
let client = Client::new(keys);
|
||||||
for relay in indexer_relays {
|
for relay in relays {
|
||||||
client.add_relay(relay).await?;
|
client.add_relay(relay).await?;
|
||||||
}
|
}
|
||||||
client.connect().await;
|
client.connect().await;
|
||||||
|
|||||||
Reference in New Issue
Block a user