You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

client.rs 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. use std::collections::*;
  2. use std::path::PathBuf;
  3. use std::sync::Arc;
  4. use futures::compat::Stream01CompatExt;
  5. use futures::prelude::*;
  6. use hyper::client::connect::dns::GaiResolver;
  7. use hyper::client::connect::HttpConnector;
  8. use hyper_tls::HttpsConnector;
  9. use inotify::ffi::*;
  10. use tokio::fs as tokiofs;
  11. use tokio::prelude::*;
  12. use tokio::sync::mpsc;
  13. use tokio_inotify;
  14. use url::Url;
  15. use ruma_client::Client;
  16. use ruma_client_api::r0::message as rumamessage;
  17. use ruma_events::{self, room::message::*};
  18. use ruma_identifiers::RoomId;
  19. use crate::config::*;
  20. #[derive(Debug)]
  21. pub enum Error {
  22. BadUrl,
  23. MtxClient(ruma_client::Error),
  24. }
  25. impl From<ruma_client::Error> for Error {
  26. fn from(f: ruma_client::Error) -> Self {
  27. Self::MtxClient(f)
  28. }
  29. }
  30. type MatrixClient = Client<HttpsConnector<HttpConnector<GaiResolver>>>;
  31. type MessageRequest = rumamessage::create_message_event::Request;
  32. pub struct Message {
  33. dest_room: RoomId,
  34. msg: String,
  35. delay_secs: u32,
  36. }
  37. impl Message {
  38. pub fn new(dest_room: RoomId, msg: String) -> Self {
  39. Self::new_delay(dest_room, msg, 0)
  40. }
  41. pub fn new_delay(dest_room: RoomId, msg: String, delay_secs: u32) -> Self {
  42. Self {
  43. dest_room,
  44. msg,
  45. delay_secs,
  46. }
  47. }
  48. }
  49. pub async fn create_and_auth_client(acct: Account) -> Result<Arc<MatrixClient>, Error> {
  50. let hs_url = Url::parse(&acct.homeserver).map_err(|_| Error::BadUrl)?;
  51. let c = MatrixClient::https(hs_url, None);
  52. match acct.auth {
  53. Auth::UsernamePass(un, pw) => c.log_in(un, pw, acct.device_id, acct.display).await?,
  54. };
  55. Ok(Arc::new(c))
  56. }
  57. pub async fn submit_messages(cli: Arc<MatrixClient>, mut recv: mpsc::Receiver<Message>) {
  58. let mut rng = rand::thread_rng();
  59. while let Some(msg) = recv.recv().await {
  60. let req = make_text_request(msg.dest_room.clone(), &msg.msg, &mut rng);
  61. if let Err(e) = cli.request(req).await {
  62. panic!("[client] error sending request: {:?}", e);
  63. }
  64. }
  65. }
  66. fn make_text_request<R: rand::Rng>(room_id: RoomId, msg: &str, rng: &mut R) -> MessageRequest {
  67. let inner = TextMessageEventContent {
  68. body: String::from(msg),
  69. format: None,
  70. formatted_body: None,
  71. relates_to: None,
  72. };
  73. let mec = MessageEventContent::Text(inner);
  74. MessageRequest {
  75. room_id: room_id,
  76. event_type: ruma_events::EventType::RoomMessage,
  77. txn_id: make_txn_id(rng),
  78. data: mec,
  79. }
  80. }
  81. const TXN_ID_LEN: usize = 20;
  82. fn make_txn_id<R: rand::Rng>(rng: &mut R) -> String {
  83. let mut buf = String::with_capacity(TXN_ID_LEN);
  84. for _ in 0..TXN_ID_LEN {
  85. buf.push((rng.gen_range(0, 26) + ('a' as u8)) as char);
  86. }
  87. buf
  88. }