Files
easy-nostr/src/functions/feed.rs
2025-12-19 20:25:39 +01:00

76 lines
2.3 KiB
Rust

use crate::nips::nip01::Post;
use anyhow::{Context, Result};
use nostr_sdk::prelude::*;
use std::time::Duration;
/// Fetches a timeline/feed of posts from specific users (Followed users).
///
/// # Arguments
/// * `client` - The Nostr client.
/// * `followed_pubkeys` - A list of hex strings (bech32 also works if parsed correctly, but we assume hex or wait for parsing) representing the users to follow.
///
/// The function parses the keys, creates a filter, and returns a list of sorted Posts.
pub async fn get_followed_feed(
client: &Client,
followed_pubkeys: Vec<String>,
) -> Result<Vec<Post>> {
let mut keys = Vec::new();
for key in followed_pubkeys {
// We try to parse each key. If one fails, we just ignore it or log it (here we context it).
let pk = PublicKey::parse(&key).context(format!("Invalid public key: {}", key))?;
keys.push(pk);
}
if keys.is_empty() {
return Ok(Vec::new());
}
// Create a filter for Text Notes (Kind 1) from these authors
let filter = Filter::new().kind(Kind::TextNote).authors(keys).limit(50); // Limit to 50 posts for now
let timeout = Duration::from_secs(10);
let events = client.fetch_events(filter, timeout).await?;
// Convert Events to our Post struct
let mut posts: Vec<Post> = events
.into_iter()
.map(|e| Post {
id: e.id,
author: e.pubkey,
content: e.content.clone(),
created_at: e.created_at,
})
.collect();
// Sort by created_at descending (newest first)
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(posts)
}
/// Fetches random (recent) posts from the connected Relays (Global Feed).
///
/// This is useful for discovery.
pub async fn get_random_posts(client: &Client) -> Result<Vec<Post>> {
// Filter for any Text Note, limit 20
let filter = Filter::new().kind(Kind::TextNote).limit(20);
let timeout = Duration::from_secs(10);
let events = client.fetch_events(filter, timeout).await?;
let mut posts: Vec<Post> = events
.into_iter()
.map(|e| Post {
id: e.id,
author: e.pubkey,
content: e.content.clone(),
created_at: e.created_at,
})
.collect();
// Sort by newest first
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(posts)
}