1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
// Copyright (c) 2023 xmpp-rs contributors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use std::path::{Path, PathBuf};
use std::sync::{Arc, RwLock};
use tokio_xmpp::connect::ServerConnector;
pub use tokio_xmpp::parsers;
use tokio_xmpp::parsers::{disco::DiscoInfoResult, message::MessageType};
pub use tokio_xmpp::{AsyncClient as TokioXmppClient, BareJid, Element, FullJid, Jid};
use crate::{event_loop, message, muc, upload, Error, Event, RoomNick};
pub struct Agent<C: ServerConnector> {
pub(crate) client: TokioXmppClient<C>,
pub(crate) default_nick: Arc<RwLock<String>>,
pub(crate) lang: Arc<Vec<String>>,
pub(crate) disco: DiscoInfoResult,
pub(crate) node: String,
pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
pub(crate) awaiting_disco_bookmarks_type: bool,
}
impl<C: ServerConnector> Agent<C> {
pub async fn disconnect(&mut self) -> Result<(), Error> {
self.client.send_end().await
}
pub async fn join_room(
&mut self,
room: BareJid,
nick: Option<String>,
password: Option<String>,
lang: &str,
status: &str,
) {
muc::room::join_room(self, room, nick, password, lang, status).await
}
/// Send a "leave room" request to the server (specifically, an "unavailable" presence stanza).
///
/// The returned future will resolve when the request has been sent,
/// not when the room has actually been left.
///
/// If successful, a `RoomLeft` event should be received later as a confirmation.
///
/// See: https://xmpp.org/extensions/xep-0045.html#exit
///
/// Note that this method does NOT remove the room from the auto-join list; the latter
/// is more a list of bookmarks that the account knows about and that have a flag set
/// to indicate that they should be joined automatically after connecting (see the JoinRoom event).
///
/// Regarding the latter, see the these minutes about auto-join behavior:
/// https://docs.modernxmpp.org/meetings/2019-01-brussels/#bookmarks
///
/// # Arguments
///
/// * `room_jid`: The JID of the room to leave.
/// * `nickname`: The nickname to use in the room.
/// * `lang`: The language of the status message.
/// * `status`: The status message to send.
pub async fn leave_room(
&mut self,
room_jid: BareJid,
nickname: RoomNick,
lang: impl Into<String>,
status: impl Into<String>,
) {
muc::room::leave_room(self, room_jid, nickname, lang, status).await
}
/// Send a message to a given recipient.
///
/// Returns the generated message ID.
///
/// # Arguments
///
/// * `recipient`: The JID of the recipient.
/// * `type_`: The type of message to send.
/// For a message to a MUC room, this should be `MessageType::Groupchat`.
/// For a private message to a MUC room member or regular contact,
/// this should be `MessageType::Chat`.
/// * `lang`: The language of the message. (See IETF RFC 5646)
/// * `text`: The text of the message.
pub async fn send_message(
&mut self,
recipient: Jid,
type_: MessageType,
lang: &str,
text: &str,
) -> Result<String, tokio_xmpp::Error> {
message::send::send_message(self, recipient, type_, lang, text).await
}
/// Send a private message to a given MUC room member.
///
/// Returns the generated message ID.
///
/// # Arguments
///
/// * `room`: The JID of the room.
/// * `recipient`: The nickname of the recipient within the room.
/// * `type_`: The type of message to send.
/// For a message to a MUC room, this should be `MessageType::Groupchat`.
/// For a private message to a MUC room member or regular contact,
/// this should be `MessageType::Chat`.
/// * `lang`: The language of the message. (See IETF RFC 5646)
/// * `text`: The text of the message.
///
/// Returns the generated message ID, or an error if the message could not be sent.
pub async fn send_room_private_message(
&mut self,
room: BareJid,
recipient: RoomNick,
lang: &str,
text: &str,
) -> Result<String, tokio_xmpp::Error> {
muc::private_message::send_room_private_message(self, room, recipient, lang, text).await
}
/// Wait for new events.
///
/// # Returns
///
/// - `Some(events)` if there are new events; multiple may be returned at once.
/// - `None` if the underlying stream is closed.
pub async fn wait_for_events(&mut self) -> Option<Vec<Event>> {
event_loop::wait_for_events(self).await
}
pub async fn upload_file_with(&mut self, service: &str, path: &Path) {
upload::send::upload_file_with(self, service, path).await
}
/// Get the bound jid of the client.
///
/// If the client is not connected, this will be None.
pub fn bound_jid(&self) -> Option<&Jid> {
self.client.bound_jid()
}
}