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::with_account(
24 selected.desktop_port,
25 selected.desktop_account,
26 )?))),
27 }
28 }
29
30 fn graph(&self) -> Result<&GraphClient, AppError> {
31 match self {
32 Self::Graph(client) => Ok(client),
33 Self::Desktop(_) => Err(desktop::messaging_unsupported()),
34 }
35 }
36
37 pub async fn me(&self) -> Result<Value, AppError> {
38 self.graph()?.me().await
39 }
40 pub async fn teams(&self, limit: u16, offset: usize) -> Result<Page, AppError> {
41 self.graph()?.teams(limit, offset).await
42 }
43 pub async fn teams_available(&self) -> Result<(), AppError> {
44 self.graph()?.teams_available().await
45 }
46 pub async fn channels(&self, team: &str, limit: u16, offset: usize) -> Result<Page, AppError> {
47 self.graph()?.channels(team, limit, offset).await
48 }
49 pub async fn chats(&self, limit: u16, cursor: Option<&str>) -> Result<Page, AppError> {
50 match self {
51 Self::Graph(client) => client.chats(limit, cursor).await,
52 Self::Desktop(client) => client.chats(limit, cursor).await,
53 }
54 }
55 pub async fn messages(
56 &self,
57 chat: Option<&str>,
58 team: Option<&str>,
59 channel: Option<&str>,
60 limit: u16,
61 cursor: Option<&str>,
62 ) -> Result<Page, AppError> {
63 match (self, chat, team, channel) {
64 (Self::Graph(client), ..) => client.messages(chat, team, channel, limit, cursor).await,
65 (Self::Desktop(client), Some(chat), None, None) => {
66 client.messages(chat, limit, cursor).await
67 }
68 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
69 }
70 }
71 pub async fn send(
72 &self,
73 chat: Option<&str>,
74 team: Option<&str>,
75 channel: Option<&str>,
76 body: &str,
77 ) -> Result<Value, AppError> {
78 match (self, chat, team, channel) {
79 (Self::Graph(client), ..) => client.send(chat, team, channel, body).await,
80 (Self::Desktop(client), Some(chat), None, None) => client.send(chat, body).await,
81 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
82 }
83 }
84}
85
86impl TeamsBackend {
87 pub async fn send_with_id(&self, chat: &str, body: &str, id: &str) -> Result<Value, AppError> {
88 match self {
89 Self::Desktop(client) => client.send_with_id(chat, body, id).await,
90 Self::Graph(client) => client.send(Some(chat), None, None, body).await,
91 }
92 }
93 pub async fn delivery(&self, chat: &str, id: &str) -> Result<Value, AppError> {
94 match self {
95 Self::Desktop(client) => client.delivery(chat, id).await,
96 Self::Graph(_) => Err(AppError::Unsupported("delivery reconciliation by client message ID is available on desktop profiles only; check the conversation before resending".into())),
97 }
98 }
99}