Send MUC message

[?]
Feb 18, 2019, 7:02 PM
37OMJ4CKEJIHMGWDGILSULMALWUTXSIL2DK2SBEHLKECFZUG2P5QC

Dependencies

  • [2] EXWBVL3Z Allow subscription
  • [3] 5IKA4GO7 Rename xmpp client field from "inner" to "client"
  • [4] 6E5IC33Z Try to test 2018 edition
  • [5] 5Y6YJ6UH Add shutdown function to make actions before offline
  • [6] OB3HA2MD Use Client::new_with_jid to parse jid only once
  • [7] TNMTIVGQ Move rustfmt to stable check
  • [8] 2VZBEEXA Messages fixed
  • [9] J7VX56FW ToDo
  • [10] HEGER5WD Add Pipelines
  • [11] MAC6WCSX Fix pipelines
  • [12] AA2ZWGRL Enter to MUC
  • [*] FV6BJ5K6 Send self-presence and store account info in Rc so it willbe used in some future in parallel
  • [*] VS6AHRWI Move XMPP to separate dir
  • [*] FVVPKFTL Initial commit
  • [*] OFRX6SW6 Fix Pipelines

Change contents

  • edit in src/xmpp/stanzas.rs at line 46
    [2.52][2.52:181](),[2.181][3.309:361](),[3.309][3.309:361]()
    pub fn make_allow_subscribe(jid: xmpp_parsers::Jid) -> Element {
    let mut presence = Presence::new(PresenceType::Subscribed);
    presence.to = Some(jid);
    presence.into()
    }
  • edit in src/xmpp/stanzas.rs at line 61
    [3.931]
    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()
    }
  • edit in src/xmpp/mod.rs at line 30
    [3.378]
    [3.1786]
    /// muc id to muc jid
    mucs: HashMap<String, xmpp_parsers::Jid>,
  • edit in src/xmpp/mod.rs at line 574
    [2.204][2.204:762](),[2.762][3.2916:2938](),[3.2916][3.2916:2938]()
    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()));
    }
  • edit in src/xmpp/mod.rs at line 604
    [3.12358]
    [3.23186]
    XmppCommand::Chatroom { muc_id, message } => {
    if let Some(muc) = self.state.data.mucs.get(&muc_id) {
    self.state
    .data
    .send_queue
    .push_back(stanzas::make_muc_message(muc.clone(), message));
    } else {
    error!("Not found MUC {}", muc_id);
    }
    }
  • replacement in src/xmpp/mod.rs at line 630
    [3.12737][3.12737:13233]()
    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);
    [3.12737]
    [3.13233]
    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(),
    );
  • replacement in src/xmpp/mod.rs at line 640
    [3.13234][3.13234:13299]()
    info!("Sending muc presence... {:?}", muc_presence);
    [3.13234]
    [3.13299]
    info!("Sending muc presence... {:?}", muc_presence);
  • replacement in src/xmpp/mod.rs at line 642
    [3.13300][3.13300:13345]()
    let account4 = account2.clone();
    [3.13300]
    [3.13345]
    let account4 = account2.clone();
  • replacement in src/xmpp/mod.rs at line 644
    [3.13346][3.13346:13784]()
    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,
    })
    [3.13346]
    [3.12130]
    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,
    })
  • edit in src/xmpp/mod.rs at line 669
    [3.4005]
    [3.13871]
    Chatroom {
    muc_id: String,
    message: String,
    },
  • edit in src/main.rs at line 38
    [3.13950]
    [3.13950]
    fn body_to_string(req: Request<Body>) -> impl Future<Item = String, Error = failure::Error> {
    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
    })
    })
    }
  • replacement in src/main.rs at line 74
    [3.14894][3.14894:14948]()
    match xmpp_to_res {
    Err(err) => {
    [3.14894]
    [3.14948]
    let xmpp_muc_opt = req
    .headers()
    .get("X-XMPP-Muc")
    .map(|h| h.to_str().map(|s| s.to_string()));
    match (xmpp_muc_opt, xmpp_to_res) {
    (None, Err(err)) => {
  • replacement in src/main.rs at line 89
    [3.15385][3.15385:15414]()
    Ok(xmpp_to) => {
    [3.15385]
    [3.15414]
    (None, Ok(xmpp_to)) => {
  • replacement in src/main.rs at line 92
    [3.15523][3.15523:16148](),[3.16148][3.4006:4092](),[3.4092][3.16228:18122](),[3.16228][3.16228:18122]()
    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>
    [3.15523]
    [3.18122]
    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>
  • edit in src/main.rs at line 128
    [3.18136]
    [3.18136]
    (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>
    }
  • edit in bitbucket-pipelines.yml at line 21
    [3.703][3.32:155]()
    - rustup component add rustfmt-preview
    - cargo fmt -- --version
    - cargo fmt --all -- --check
  • edit in bitbucket-pipelines.yml at line 29
    [3.919]
    [3.988]
    - rustup component add rustfmt-preview --toolchain nightly
  • edit in bitbucket-pipelines.yml at line 36
    [17.62]
    [3.1321]
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    - cargo fmt -- --version
    - cargo fmt --all -- --check
    ================================
    - cargo fix --edition
    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  • edit in README.md at line 0
    [16.76]
    ### 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"
    ```