xmpp: Allow MUC join to be configured

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-02-26 23:58:02 +01:00
parent 216d9c4a8d
commit 1404a9801c
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
2 changed files with 52 additions and 21 deletions

View file

@ -6,7 +6,7 @@
use env_logger; use env_logger;
use std::env::args; use std::env::args;
use xmpp::{ClientBuilder, ClientFeature, ClientType, Event}; use xmpp::{ClientBuilder, ClientFeature, ClientType, Event, RoomJoinConfig};
use xmpp_parsers::{message::MessageType, Jid}; use xmpp_parsers::{message::MessageType, Jid};
#[tokio::main] #[tokio::main]
@ -56,15 +56,14 @@ async fn main() -> Result<(), Option<()>> {
} }
Event::JoinRoom(jid, conference) => { Event::JoinRoom(jid, conference) => {
println!("Joining room {} ({:?})…", jid, conference.name); println!("Joining room {} ({:?})…", jid, conference.name);
client let config = RoomJoinConfig {
.join_room( nick: conference.nick,
jid, password: conference.password,
conference.nick, lang: "en",
conference.password, status: "Yet another bot!",
"en", ..RoomJoinConfig::default()
"Yet another bot!", };
) client.join_room(jid, config).await;
.await;
} }
Event::LeaveRoom(jid) => { Event::LeaveRoom(jid) => {
println!("Leaving room {}", jid); println!("Leaving room {}", jid);

View file

@ -20,12 +20,14 @@ use tokio_xmpp::{AsyncClient as TokioXmppClient, Event as TokioXmppEvent};
use xmpp_parsers::{ use xmpp_parsers::{
bookmarks2::Conference, bookmarks2::Conference,
caps::{compute_disco, hash_caps, Caps}, caps::{compute_disco, hash_caps, Caps},
date::DateTime,
disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}, disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity},
hashes::Algo, hashes::Algo,
http_upload::{Header as HttpUploadHeader, SlotRequest, SlotResult}, http_upload::{Header as HttpUploadHeader, SlotRequest, SlotResult},
iq::{Iq, IqType}, iq::{Iq, IqType},
message::{Body, Message, MessageType}, message::{Body, Message, MessageType},
muc::{ muc::{
muc::History as MucHistory,
user::{MucUser, Status}, user::{MucUser, Status},
Muc, Muc,
}, },
@ -192,6 +194,33 @@ impl ClientBuilder<'_> {
} }
} }
pub enum RoomJoinHistory {
MaxChars(u32),
MaxStanzas(u32),
MaxSeconds(u32),
Since(DateTime),
}
pub struct RoomJoinConfig<'a> {
pub nick: Option<String>,
pub password: Option<String>,
pub history: Option<RoomJoinHistory>,
pub lang: &'a str,
pub status: &'a str,
}
impl<'a> Default for RoomJoinConfig<'a> {
fn default() -> Self {
Self {
nick: None,
password: None,
history: None,
lang: "en",
status: "",
}
}
}
pub struct Agent { pub struct Agent {
client: TokioXmppClient, client: TokioXmppClient,
default_nick: Rc<RefCell<String>>, default_nick: Rc<RefCell<String>>,
@ -206,24 +235,27 @@ impl Agent {
self.client.send_end().await self.client.send_end().await
} }
pub async fn join_room( pub async fn join_room(&mut self, room: BareJid, config: RoomJoinConfig<'_>) {
&mut self,
room: BareJid,
nick: Option<String>,
password: Option<String>,
lang: &str,
status: &str,
) {
let mut muc = Muc::new(); let mut muc = Muc::new();
if let Some(password) = password { if let Some(password) = config.password {
muc = muc.with_password(password); muc = muc.with_password(password);
} }
if let Some(history) = config.history {
muc.history = Some(match history {
RoomJoinHistory::MaxChars(max) => MucHistory::new().with_maxchars(max),
RoomJoinHistory::MaxStanzas(max) => MucHistory::new().with_maxstanzas(max),
RoomJoinHistory::MaxSeconds(max) => MucHistory::new().with_seconds(max),
RoomJoinHistory::Since(since) => MucHistory::new().with_since(since),
});
};
let nick = nick.unwrap_or_else(|| self.default_nick.borrow().clone()); let nick = config
.nick
.unwrap_or_else(|| self.default_nick.borrow().clone());
let room_jid = room.with_resource(nick); let room_jid = room.with_resource(nick);
let mut presence = Presence::new(PresenceType::None).with_to(Jid::Full(room_jid)); let mut presence = Presence::new(PresenceType::None).with_to(Jid::Full(room_jid));
presence.add_payload(muc); presence.add_payload(muc);
presence.set_status(String::from(lang), String::from(status)); presence.set_status(String::from(config.lang), String::from(config.status));
let _ = self.client.send_stanza(presence.into()).await; let _ = self.client.send_stanza(presence.into()).await;
} }