37OMJ4CKEJIHMGWDGILSULMALWUTXSIL2DK2SBEHLKECFZUG2P5QC
EXWBVL3ZHAOACZCEIJOE6AFXPAYJRNTWJQDKYSQBEP57OWP2MG2AC
FV6BJ5K64QG63YI2PTII44ZEBAYNJBQZ5FSBHW65EPHGBKFGUW4AC
J7VX56FW5BPM77MEFTKK6HP2ZOWRXP6GFUTBTQKBO52EBGFTVXMQC
2VZBEEXAPKTQTRCAODELRMBZLTMS6PMMOGPJ6I7VLWJQAQAKJXDQC
OB3HA2MD7TDBGGURKXNQKLLLC5FAAD5OX5BENF3M2XNU7OTJ5HHAC
VS6AHRWIPIMQNQAFX7INQGSUB72OW2K6HM6NGOV76RBRF6COQFRQC
5IKA4GO7DIMBBYB7OUF5S7N2LUWIZ5MKCCCTZCAYPZI2357MVFHAC
FVVPKFTLD5VOGVDF7MOSSKQ3KPCT4HDGTNTTC6I6B4TWXOTPCJ7AC
HEGER5WDSFJTGZAA323THS5ETRXWMCGI3MNTUREPOEK7A7IG4OHAC
MAC6WCSXB5GJ4IQ3OC4NLS74CGERPXMKKLZPIGDFTXKINYTIZK2AC
OFRX6SW6VXQDCZ3OHJMU7MYGJBTTFS3X45VLLXIE3UIBZOVDVI4QC
pub fn make_muc_message(to: xmpp_parsers::Jid, text: String) -> Element {
let mut message = Message::new(Some(to.into_bare_jid()));
message.bodies.insert(String::new(), Body(text));
message.type_ = MessageType::Groupchat;
message.into()
}
let sub_from = match rdata.0 {
xmpp_parsers::roster::Subscription::From => true,
xmpp_parsers::roster::Subscription::Both => true,
_ => false,
};
if !sub_from {
info!("Not subscription from {}", xmpp_to);
self.state
.data
.send_queue
.push_back(stanzas::make_allow_subscribe(xmpp_to.clone()));
}
stream::iter_ok(
account
.chatrooms
.values()
.map(std::clone::Clone::clone)
.collect::<Vec<_>>(),
)
.fold(state, move |XmppState { client, mut data }, muc_jid| {
data.counter += 1;
let id_muc_presence = format!("id_muc_presence{}", data.counter);
let muc_presence =
stanzas::make_muc_presence(&id_muc_presence, account2.jid.clone(), muc_jid);
stream::iter_ok(account.chatrooms.clone())
.fold(state, move |XmppState { client, mut data }, muc_jid| {
data.counter += 1;
let id_muc_presence = format!("id_muc_presence{}", data.counter);
let muc_presence = stanzas::make_muc_presence(
&id_muc_presence,
account2.jid.clone(),
muc_jid.1.clone(),
);
use tokio::prelude::Sink;
client
.send(Packet::Stanza(muc_presence))
.map_err(|e| {
error!("Error on send muc presence: {}", e);
account4
})
.and_then(|client| future::ok(XmppState { client, data }))
})
.map(|state| XmppConnection {
account: account3,
state,
})
use tokio::prelude::Sink;
client
.send(Packet::Stanza(muc_presence))
.map_err(|e| {
error!("Error on send muc presence: {}", e);
account4
})
.and_then(|client| {
data.mucs.insert(muc_jid.0, muc_jid.1);
future::ok(XmppState { client, data })
})
})
.map(|state| XmppConnection {
account: account3,
state,
})
Box::new(
req.into_body()
.map_err(|e| e.into())
.fold(String::new(), |mut acc, ch| {
std::str::from_utf8(&*ch).map(|s| {
acc.push_str(s);
acc
})
})
.and_then(move |message: String| {
if !message.is_empty() {
Box::new(
cmd_send
.clone()
.send(XmppCommand::Chat { xmpp_to, message })
.then(|r| match r {
Ok(_) => tokio::prelude::future::ok(Response::new(
Body::from("Accepted"),
)),
Err(e) => {
error!("Command sent error: {}", e);
tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from(format!(
"Command sent error: {}",
e
))),
)
}
})
.map_err(|e| e.into()),
)
} else {
warn!("Empty message");
Box::new(tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from("Empty message"))
.map_err(|e| e.into()),
))
as Box<dyn Future<Item = _, Error = _> + Send + 'static>
}
}),
) as Box<dyn Future<Item = _, Error = _> + Send + 'static>
Box::new(body_to_string(req).and_then(move |message: String| {
if !message.is_empty() {
Box::new(
cmd_send
.clone()
.send(XmppCommand::Chat { xmpp_to, message })
.then(|r| match r {
Ok(_) => tokio::prelude::future::ok(Response::new(Body::from(
"Accepted",
))),
Err(e) => {
error!("Command sent error: {}", e);
tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from(format!(
"Command sent error: {}",
e
))),
)
}
})
.map_err(|e| e.into()),
)
} else {
warn!("Empty message");
Box::new(tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from("Empty message"))
.map_err(|e| e.into()),
))
as Box<dyn Future<Item = _, Error = _> + Send + 'static>
}
})) as Box<dyn Future<Item = _, Error = _> + Send + 'static>
(Some(Ok(muc_id)), _) => {
info!("Got MUC request. Reading body...");
let cmd_send = self.cmd_send.clone();
Box::new(body_to_string(req).and_then(move |message: String| {
if !message.is_empty() {
Box::new(
cmd_send
.clone()
.send(XmppCommand::Chatroom { muc_id, message })
.then(|r| match r {
Ok(_) => tokio::prelude::future::ok(Response::new(Body::from(
"Accepted",
))),
Err(e) => {
error!("Command sent error: {}", e);
tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from(format!(
"Command sent error: {}",
e
))),
)
}
})
.map_err(|e| e.into()),
)
} else {
warn!("Empty message");
Box::new(tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from("Empty message"))
.map_err(|e| e.into()),
))
as Box<dyn Future<Item = _, Error = _> + Send + 'static>
}
})) as Box<dyn Future<Item = _, Error = _> + Send + 'static>
}
(Some(Err(err)), _) => {
warn!("Unknown MUC destination: {}", err);
Box::new(tokio::prelude::future::result(
Response::builder()
.status(hyper::StatusCode::BAD_REQUEST)
.body(Body::from(format!("Unknown MUC destination: {}", err)))
.map_err(|e| e.into()),
)) as Box<dyn Future<Item = _, Error = _> + Send + 'static>
}
### XMPP client daemon
#### Sending messages
```
curl http://localhost:8083/ -H "X-XMPP-To: some@domain.org" -d "Test"
```
#### Sending messages to MUC
```
curl http://localhost:8083/ -H "X-XMPP-Muc: smac" -d "Test"
```