notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

message.rs (2330B)


      1 use nostrdb::Transaction;
      2 use notedeck::enostr::RelayId;
      3 use notedeck::{AppContext, RelayType};
      4 
      5 use crate::cache::{ConversationCache, ConversationId};
      6 use crate::nip17::{build_rumor_json, giftwrap_message, query_participant_dm_relays, OsRng};
      7 
      8 pub fn send_conversation_message(
      9     conversation_id: ConversationId,
     10     content: String,
     11     cache: &ConversationCache,
     12     ctx: &mut AppContext<'_>,
     13 ) {
     14     if content.trim().is_empty() {
     15         return;
     16     }
     17 
     18     let Some(conversation) = cache.get(conversation_id) else {
     19         tracing::warn!("missing conversation {conversation_id} for send action");
     20         return;
     21     };
     22 
     23     let Some(selected_kp) = ctx.accounts.selected_filled() else {
     24         tracing::warn!("cannot send message without a full keypair");
     25         return;
     26     };
     27 
     28     let Some(rumor_json) = build_rumor_json(
     29         &content,
     30         &conversation.metadata.participants,
     31         selected_kp.pubkey,
     32     ) else {
     33         tracing::error!("failed to build rumor for conversation {conversation_id}");
     34         return;
     35     };
     36 
     37     let Some(sender_secret) = ctx.accounts.selected_filled().map(|f| f.secret_key) else {
     38         return;
     39     };
     40 
     41     let txn = Transaction::new(ctx.ndb).expect("txn");
     42     let mut rng = OsRng;
     43     for participant in &conversation.metadata.participants {
     44         let Some(gifrwrap_note) =
     45             giftwrap_message(&mut rng, sender_secret, participant, &rumor_json)
     46         else {
     47             continue;
     48         };
     49         if participant == selected_kp.pubkey {
     50             let Some(giftwrap_json) = gifrwrap_note.json().ok() else {
     51                 continue;
     52             };
     53 
     54             if let Err(e) = ctx.ndb.process_client_event(&giftwrap_json) {
     55                 tracing::error!("Could not ingest event: {e:?}");
     56             }
     57         }
     58 
     59         let participant_relays = query_participant_dm_relays(ctx.ndb, &txn, participant);
     60         let relay_type = if participant_relays.is_empty() {
     61             RelayType::AccountsWrite
     62         } else {
     63             RelayType::Explicit(
     64                 participant_relays
     65                     .into_iter()
     66                     .map(RelayId::Websocket)
     67                     .collect(),
     68             )
     69         };
     70 
     71         let mut publisher = ctx.remote.publisher(ctx.accounts);
     72         publisher.publish_note(&gifrwrap_note, relay_type);
     73     }
     74 }