diff --git a/examples/hello_bot.rs b/examples/hello_bot.rs index db5f4127..e21e1490 100644 --- a/examples/hello_bot.rs +++ b/examples/hello_bot.rs @@ -33,6 +33,7 @@ fn main() { .set_client(ClientType::Bot, "xmpp-rs") .set_website("https://gitlab.com/xmpp-rs/xmpp-rs") .enable_feature(ClientFeature::Avatars) + .enable_feature(ClientFeature::ContactList) .build(value_tx) .unwrap(); @@ -47,6 +48,15 @@ fn main() { println!("Disconnected."); return Err(()); }, + Event::ContactAdded(contact) => { + println!("Contact {:?} added.", contact); + }, + Event::ContactRemoved(contact) => { + println!("Contact {:?} removed.", contact); + }, + Event::ContactChanged(contact) => { + println!("Contact {:?} changed.", contact); + }, Event::RoomJoined(jid) => { println!("Joined room {}.", jid); agent.send_message(jid.into_bare_jid(), MessageType::Groupchat, "en", "Hello world!"); diff --git a/src/lib.rs b/src/lib.rs index 56eda8a4..aca578f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ use xmpp_parsers::{ event::PubSubEvent, pubsub::PubSub, }, + roster::{Roster, Item as RosterItem}, stanza_error::{StanzaError, ErrorType, DefinedCondition}, Jid, JidParseError, TryFrom, }; @@ -59,11 +60,15 @@ impl ToString for ClientType { #[derive(PartialEq)] pub enum ClientFeature { Avatars, + ContactList, } pub enum Event { Online, Disconnected, + ContactAdded(RosterItem), + ContactRemoved(RosterItem), + ContactChanged(RosterItem), AvatarRetrieved(Jid, String), RoomJoined(Jid), } @@ -158,6 +163,9 @@ impl ClientBuilder<'_> { sender_tx.unbounded_send(packet) .unwrap(); app_tx.unbounded_send(Event::Online).unwrap(); + let iq = Iq::from_get("roster", Roster { ver: None, items: vec![] }) + .into(); + sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); } TokioXmppEvent::Disconnected => { app_tx.unbounded_send(Event::Disconnected).unwrap(); @@ -186,7 +194,12 @@ impl ClientBuilder<'_> { send_error(iq.from.unwrap(), iq.id, ErrorType::Cancel, DefinedCondition::ServiceUnavailable, "No handler defined for this kind of iq."); } } else if let IqType::Result(Some(payload)) = iq.payload { - if payload.is("pubsub", ns::PUBSUB) { + if payload.is("query", ns::ROSTER) { + let roster = Roster::try_from(payload).unwrap(); + for item in roster.items.into_iter() { + app_tx.unbounded_send(Event::ContactAdded(item)).unwrap(); + } + } else if payload.is("pubsub", ns::PUBSUB) { let pubsub = PubSub::try_from(payload).unwrap(); let from = iq.from.clone().unwrap_or(Jid::from_str(&jid).unwrap());