rustymilky 0.1.0

Milky 协议的 Rust SDK
Documentation
use anyhow::Result;
use futures_util::StreamExt;
use rustymilky::{
  MilkyClient, MilkyTransport, MilkyTransportEvent,
  protocol::{
    Event, GetImplInfoInput, GroupMemberEntity, IncomingMessage, IncomingSegment,
    IncomingSegmentMentionData, OutgoingSegment, SendGroupMessageInput,
  },
};

#[tokio::main]
async fn main() -> Result<()> {
  let client = MilkyClient::new("http://127.0.0.1:3100", None)?;

  let impl_info = client.request(GetImplInfoInput {}).await?;
  println!(
    "Milky Server: {}, {}",
    impl_info.impl_name, impl_info.impl_version
  );

  let mut source = client.event_sse().await?;
  loop {
    tokio::select! {
      signal = tokio::signal::ctrl_c() => {
        signal?;
        source.close();
        println!("Milky stopping...");
        break;
      }
      event = source.next() => {
        let Some(event) = event else {
          break;
        };

        handle_event(&client, &mut source, event?).await?;
      }
    }
  }

  Ok(())
}

async fn handle_event(
  client: &MilkyClient,
  source: &mut MilkyTransport,
  event: MilkyTransportEvent,
) -> Result<()> {
  match event {
    MilkyTransportEvent::Open => println!("Milky Connected"),
    MilkyTransportEvent::Reconnecting {
      attempt,
      next_delay,
    } => {
      println!(
        "Milky reconnecting: attempt {}, waiting {:?}",
        attempt, next_delay
      );
    }
    MilkyTransportEvent::Reconnected => {
      println!("Milky reconnected");
    }
    MilkyTransportEvent::Push(Event::MessageReceive {
      data:
        IncomingMessage::Group {
          peer_id,
          group_member: GroupMemberEntity {
            user_id, nickname, ..
          },
          message_seq,
          segments,
          ..
        },
      self_id,
      ..
    }) => {
      if segments.len() > 1
        && matches!(
          segments[0],
          IncomingSegment::Mention(IncomingSegmentMentionData { user_id, .. }) if user_id == self_id
        )
      {
        if let IncomingSegment::Text(text) = &segments[1] {
          let text = text.trim().to_string();
          println!(
            "Mentioned By: {} ({}), Received: {}",
            nickname, user_id, text
          );

          client
            .request(SendGroupMessageInput {
              group_id: peer_id,
              message: vec![
                OutgoingSegment::Reply(message_seq),
                OutgoingSegment::Text(text),
              ],
            })
            .await?;

          println!("Reply Sent");
        }
      }
    }
    MilkyTransportEvent::Push(Event::BotOffline { .. }) => {
      println!("Milky bot offline, stopping...");
      source.close();
    }

    _ => {}
  }

  Ok(())
}