1use std::convert::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::Receipt;
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 // TODO: always use an id.
71 id: None,
72 bodies: {
73 let mut bodies = BTreeMap::new();
74 bodies.insert(String::new(), String::from(body));
75 bodies
76 },
77 subjects: BTreeMap::new(),
78 thread: None,
79 payloads: vec!(),
80 };
81 self.proxy.send(message.into());
82 Ok(())
83 }
84
85 fn handle_message(&self, message: &Message) -> Propagation {
86 let from = message.from.clone().unwrap();
87 for payload in message.payloads.clone() {
88 let payload = match MessagePayload::try_from(payload) {
89 Ok(payload) => payload,
90 Err(err) => {
91 println!("MessagePayload: {:?}", err);
92 continue;
93 }
94 };
95 match payload {
96 // XEP-0085
97 MessagePayload::ChatState(chat_state) => self.proxy.dispatch(ChatStateEvent {
98 from: from.clone(),
99 chat_state: chat_state,
100 }),
101 // XEP-0184
102 MessagePayload::Receipt(Receipt::Request) => self.proxy.dispatch(ReceiptRequestEvent {
103 from: from.clone(),
104 }),
105 // XEP-0184
106 MessagePayload::Receipt(Receipt::Received(id)) => self.proxy.dispatch(ReceiptReceivedEvent {
107 from: from.clone(),
108 id: id.unwrap(),
109 }),
110 // XEP-0359
111 MessagePayload::StanzaId(stanza_id) => self.proxy.dispatch(StanzaIdEvent {
112 from: from.clone(),
113 stanza_id: stanza_id,
114 message: message.clone(),
115 }),
116 payload => println!("Unhandled payload: {:?}", payload),
117 }
118 }
119 if message.bodies.contains_key("") {
120 self.proxy.dispatch(MessageEvent {
121 from: from,
122 body: message.bodies[""].clone(),
123 subject: if message.subjects.contains_key("") { Some(message.subjects[""].clone()) } else { None },
124 thread: message.thread.clone(),
125 });
126 }
127 Propagation::Stop
128 }
129}
130
131impl_plugin!(MessagingPlugin, proxy, [
132 (Message, Priority::Default) => handle_message,
133]);