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 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use std::collections::*;
  2. use std::path::PathBuf;
  3. use std::sync::Arc;
  4. use tokio::io::{AsyncRead, AsyncReadExt};
  5. use tokio::sync::mpsc;
  6. use futures::prelude::*;
  7. //use ruma_client::Client;
  8. //use ruma_client_api::r0::message as rumamessage;
  9. //use ruma_events::{self, room::message::*};
  10. use matrix_sdk::events::{
  11. room::message::{MessageEventContent, TextMessageEventContent},
  12. AnyMessageEventContent,
  13. };
  14. use matrix_sdk::identifiers::RoomId;
  15. use matrix_sdk::uuid::Uuid;
  16. use crate::config::*;
  17. #[derive(Debug)]
  18. pub enum Error {
  19. BadUrl,
  20. UnknownRoom(RoomId),
  21. Matrix(matrix_sdk::Error),
  22. }
  23. pub struct Message {
  24. dest_room: RoomId,
  25. text: String,
  26. delay_secs: u32,
  27. }
  28. pub type MatrixClient = matrix_sdk::Client;
  29. impl Message {
  30. pub fn new(dest_room: RoomId, msg: String) -> Self {
  31. Self::new_delay(dest_room, msg, 0)
  32. }
  33. pub fn new_delay(dest_room: RoomId, text: String, delay_secs: u32) -> Self {
  34. Self {
  35. dest_room,
  36. text,
  37. delay_secs,
  38. }
  39. }
  40. }
  41. pub async fn create_and_auth_client(acct: Account) -> Result<Arc<MatrixClient>, Error> {
  42. let hs_url = url::Url::parse(&acct.homeserver).map_err(|_| Error::BadUrl)?;
  43. let cc = matrix_sdk::ClientConfig::new()
  44. .user_agent("mtxspooler")
  45. .unwrap();
  46. let c = matrix_sdk::Client::new_with_config(hs_url, cc).map_err(Error::Matrix)?;
  47. // Now log in.
  48. match acct.auth {
  49. Auth::UsernamePass(un, pw) => {
  50. let didref = acct.device_id.as_deref();
  51. c.login(&un, &pw, didref, didref)
  52. .map_err(Error::Matrix)
  53. .await?;
  54. }
  55. }
  56. Ok(Arc::new(c))
  57. }
  58. pub async fn submit_messages(cli: Arc<MatrixClient>, mut recv: mpsc::Receiver<Message>) {
  59. while let Some(msg) = recv.recv().await {
  60. if let Err(e) = do_submit_msg(&msg, &cli).await {
  61. panic!("[client] error handling message submission: {:?}", e);
  62. }
  63. }
  64. }
  65. async fn do_submit_msg(msg: &Message, cli: &Arc<MatrixClient>) -> Result<(), Error> {
  66. let jroom = get_room_try_join(cli, &msg.dest_room).await?;
  67. let mec = MessageEventContent::text_plain(&msg.text);
  68. let ec = AnyMessageEventContent::RoomMessage(mec);
  69. jroom.send(ec, None).map_err(Error::Matrix).await?;
  70. Ok(())
  71. }
  72. pub async fn get_room_try_join(
  73. cli: &Arc<MatrixClient>,
  74. rid: &RoomId,
  75. ) -> Result<matrix_sdk::room::Joined, Error> {
  76. use matrix_sdk::room::*;
  77. match cli
  78. .get_room(rid)
  79. .ok_or_else(|| Error::UnknownRoom(rid.clone()))?
  80. {
  81. Room::Joined(j) => Ok(j),
  82. Room::Invited(i) => {
  83. i.accept_invitation().map_err(Error::Matrix).await?;
  84. Ok(cli.get_joined_room(rid).expect("client: get invited room"))
  85. }
  86. Room::Left(l) => {
  87. l.join().map_err(Error::Matrix).await?;
  88. Ok(cli.get_joined_room(rid).expect("client: get room joined"))
  89. }
  90. }
  91. }
  92. fn gen_device_id(un: &str, pw: &str) -> String {
  93. use sha2::Digest;
  94. let mut hasher = sha2::Sha256::new();
  95. hasher.update(un.as_bytes());
  96. hasher.update("\0");
  97. hasher.update(pw.as_bytes());
  98. hasher.update("\0_mtxspooler_salt");
  99. let h: [u8; 32] = hasher.finalize().into();
  100. hex::encode(h)
  101. }