1use try_from::TryFrom;
2use std::collections::BTreeMap;
3
4use plugin::PluginProxy;
5use event::{Event, Priority, Propagation};
6use error::Error;
7use jid::Jid;
8
9use plugins::stanza::Message;
10use xmpp_parsers::message::{MessagePayload, MessageType};
11use xmpp_parsers::chatstates::ChatState;
12use xmpp_parsers::receipts::{Request, Received};
13use xmpp_parsers::stanza_id::StanzaId;
14
15// TODO: use the id (maybe even stanza-id) to identify every message.
16#[derive(Debug)]
17pub struct MessageEvent {
18 pub from: Jid,
19 pub body: String,
20 pub subject: Option<String>,
21 pub thread: Option<String>,
22}
23
24#[derive(Debug)]
25pub struct ChatStateEvent {
26 pub from: Jid,
27 pub chat_state: ChatState,
28}
29
30#[derive(Debug)]
31pub struct ReceiptRequestEvent {
32 pub from: Jid,
33}
34
35#[derive(Debug)]
36pub struct ReceiptReceivedEvent {
37 pub from: Jid,
38 pub id: String,
39}
40
41#[derive(Debug)]
42pub struct StanzaIdEvent {
43 pub from: Jid,
44 pub stanza_id: StanzaId,
45 pub message: Message,
46}
47
48impl Event for MessageEvent {}
49impl Event for ChatStateEvent {}
50impl Event for ReceiptRequestEvent {}
51impl Event for ReceiptReceivedEvent {}
52impl Event for StanzaIdEvent {}
53
54pub struct MessagingPlugin {
55 proxy: PluginProxy,
56}
57
58impl MessagingPlugin {
59 pub fn new() -> MessagingPlugin {
60 MessagingPlugin {
61 proxy: PluginProxy::new(),
62 }
63 }
64
65 pub fn send_message(&self, to: &Jid, body: &str) -> Result<(), Error> {
66 let message = Message {
67 from: None,
68 to: Some(to.clone()),
69 type_: MessageType::Chat,
70 id: Some(self.proxy.gen_id()),
71 bodies: {
72 let mut bodies = BTreeMap::new();
73 bodies.insert(String::new(), String::from(body));
74 bodies
75 },
76 subjects: BTreeMap::new(),
77 thread: None,
78 payloads: vec!(),
79 };
80 self.proxy.send(message.into());
81 Ok(())
82 }
83
84 fn handle_message(&self, message: &Message) -> Propagation {
85 let from = message.from.clone().unwrap_or(self.proxy.get_own_jid());
86 for payload in message.payloads.clone() {
87 let payload = match MessagePayload::try_from(payload) {
88 Ok(payload) => payload,
89 Err(err) => {
90 println!("MessagePayload: {:?}", err);
91 continue;
92 }
93 };
94 match payload {
95 // XEP-0085
96 MessagePayload::ChatState(chat_state) => self.proxy.dispatch(ChatStateEvent {
97 from: from.clone(),
98 chat_state: chat_state,
99 }),
100 // XEP-0184
101 MessagePayload::ReceiptRequest(Request) => self.proxy.dispatch(ReceiptRequestEvent {
102 from: from.clone(),
103 }),
104 // XEP-0184
105 MessagePayload::ReceiptReceived(Received {id}) => self.proxy.dispatch(ReceiptReceivedEvent {
106 from: from.clone(),
107 id: id.unwrap(),
108 }),
109 // XEP-0359
110 MessagePayload::StanzaId(stanza_id) => self.proxy.dispatch(StanzaIdEvent {
111 from: from.clone(),
112 stanza_id: stanza_id,
113 message: message.clone(),
114 }),
115 payload => println!("Unhandled payload: {:?}", payload),
116 }
117 }
118 if message.bodies.contains_key("") {
119 self.proxy.dispatch(MessageEvent {
120 from: from,
121 body: message.bodies[""].clone(),
122 subject: if message.subjects.contains_key("") { Some(message.subjects[""].clone()) } else { None },
123 thread: message.thread.clone(),
124 });
125 }
126 Propagation::Stop
127 }
128}
129
130impl_plugin!(MessagingPlugin, proxy, [
131 (Message, Priority::Default) => handle_message,
132]);