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(())
}