1use crate::{
3 auth,
4 config::{self, BackendKind},
5 desktop::{self, DesktopClient},
6 error::AppError,
7 graph::{GraphClient, Page},
8};
9use serde_json::Value;
10
11pub enum TeamsBackend {
12 Graph(GraphClient),
13 Desktop(Box<DesktopClient>),
14}
15
16impl TeamsBackend {
17 pub async fn connect(profile: Option<&str>) -> Result<Self, AppError> {
18 let (name, selected) = config::load(profile)?;
19 match selected.backend {
20 BackendKind::Graph => Ok(Self::Graph(GraphClient::new(
21 auth::access_token(&name, &selected).await?,
22 ))),
23 BackendKind::Desktop => Ok(Self::Desktop(Box::new(DesktopClient::from_profile(
24 &selected,
25 )?))),
26 }
27 }
28
29 fn graph(&self) -> Result<&GraphClient, AppError> {
30 match self {
31 Self::Graph(client) => Ok(client),
32 Self::Desktop(_) => Err(desktop::messaging_unsupported()),
33 }
34 }
35
36 pub async fn me(&self) -> Result<Value, AppError> {
37 self.graph()?.me().await
38 }
39 pub async fn teams(&self, limit: u16, offset: usize) -> Result<Page, AppError> {
40 self.graph()?.teams(limit, offset).await
41 }
42 pub async fn teams_available(&self) -> Result<(), AppError> {
43 self.graph()?.teams_available().await
44 }
45 pub async fn channels(&self, team: &str, limit: u16, offset: usize) -> Result<Page, AppError> {
46 self.graph()?.channels(team, limit, offset).await
47 }
48 pub async fn chats(&self, limit: u16, cursor: Option<&str>) -> Result<Page, AppError> {
49 match self {
50 Self::Graph(client) => client.chats(limit, cursor).await,
51 Self::Desktop(client) => client.chats(limit, cursor).await,
52 }
53 }
54 pub async fn messages(
55 &self,
56 chat: Option<&str>,
57 team: Option<&str>,
58 channel: Option<&str>,
59 limit: u16,
60 cursor: Option<&str>,
61 ) -> Result<Page, AppError> {
62 match (self, chat, team, channel) {
63 (Self::Graph(client), ..) => client.messages(chat, team, channel, limit, cursor).await,
64 (Self::Desktop(client), Some(chat), None, None) => {
65 client.messages(chat, limit, cursor).await
66 }
67 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
68 }
69 }
70 pub async fn send(
71 &self,
72 chat: Option<&str>,
73 team: Option<&str>,
74 channel: Option<&str>,
75 body: &str,
76 ) -> Result<Value, AppError> {
77 match (self, chat, team, channel) {
78 (Self::Graph(client), ..) => client.send(chat, team, channel, body).await,
79 (Self::Desktop(client), Some(chat), None, None) => client.send(chat, body).await,
80 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
81 }
82 }
83}
84
85impl TeamsBackend {
86 pub async fn send_with_id(&self, chat: &str, body: &str, id: &str) -> Result<Value, AppError> {
87 match self {
88 Self::Desktop(client) => client.send_with_id(chat, body, id).await,
89 Self::Graph(client) => client.send(Some(chat), None, None, body).await,
90 }
91 }
92 pub async fn delivery(&self, chat: &str, id: &str) -> Result<Value, AppError> {
93 match self {
94 Self::Desktop(client) => client.delivery(chat, id).await,
95 Self::Graph(_) => Err(AppError::Unsupported("delivery reconciliation by client message ID is available on desktop profiles only; check the conversation before resending".into())),
96 }
97 }
98}