use futures::{TryFutureExt as _, TryStreamExt as _};
use simploxide_client::prelude::*;
use std::{error::Error, sync::Arc};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let (client, mut events) = simploxide_client::connect("ws://127.0.0.1:5225").await?;
let user = client.show_active_user().await?;
println!(
"Bot profile: {} ({})",
user.profile.display_name, user.profile.full_name
);
let (address_long, address_short) = client
.api_show_my_address(user.user_id)
.map_ok(|resp| {
(
resp.contact_link.conn_link_contact.conn_full_link.clone(),
resp.contact_link.conn_link_contact.conn_short_link.clone(),
)
})
.or_else(|_| {
client.api_create_my_address(user.user_id).map_ok(|resp| {
(
resp.conn_link_contact.conn_full_link.clone(),
resp.conn_link_contact.conn_short_link.clone(),
)
})
})
.await?;
println!("Bot long address: {address_long}");
println!("Bot short address: {address_short:?}");
let send_reply = async |dest: i64, reply: String| -> ClientResult<Arc<NewChatItemsResponse>> {
client
.api_send_messages(
ApiSendMessages::builder()
.send_ref(
ChatRef::builder()
.chat_type(ChatType::Direct)
.chat_id(dest)
.build(),
)
.live_message(false)
.composed_messages(vec![
ComposedMessage::builder()
.msg_content(MsgContent::Text {
text: reply,
undocumented: Default::default(),
})
.mentions(Default::default())
.build(),
])
.build(),
)
.await
};
'reactor: while let Some(ev) = events.try_next().await? {
match ev {
Event::ContactConnected(connected) => {
println!("{} connected", connected.contact.profile.display_name);
send_reply(
connected.contact.contact_id,
"Hello! I am a simple squaring bot - if you send me a number, I will calculate its square".to_owned()
).await?;
}
Event::NewChatItems(new_msgs) => {
for (contact, text) in new_msgs.chat_items.iter().filter_map(|msg| {
let ChatInfo::Direct { ref contact, .. } = msg.chat_info else {
return None;
};
let CIContent::RcvMsgContent {
msg_content: MsgContent::Text { ref text, .. },
..
} = msg.chat_item.content
else {
return None;
};
Some((contact, text))
}) {
if text.trim() == "/die" {
break 'reactor;
}
if let Ok(num) = text.trim().parse::<i64>() {
send_reply(
contact.contact_id,
format!("Squared: {}", num.wrapping_mul(num)),
)
.await?;
} else {
send_reply(
contact.contact_id,
"Me understands only numbers!".to_owned(),
)
.await?;
}
}
}
Event::ReceivedContactRequest(req) => {
client
.api_accept_contact(req.contact_request.contact_request_id)
.await?;
println!(
"Accepted user: {} ({})",
req.contact_request.profile.display_name, req.contact_request.profile.full_name
);
}
_ => (),
}
}
Ok(())
}