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 search_people(&self, query: &str, limit: u16) -> Result<Page, AppError> {
55 crate::graph::validate_people_query(query, usize::from(limit))?;
56 match self {
57 Self::Graph(client) => client.search_people(query, usize::from(limit)).await,
58 Self::Desktop(client) => client.search_people(query, limit).await,
59 }
60 }
61 pub async fn create_chat(&self, recipient: &str) -> Result<Value, AppError> {
62 match self {
63 Self::Graph(client) => client.create_chat(recipient).await,
64 Self::Desktop(client) => client.create_chat(recipient).await,
65 }
66 }
67 pub async fn messages(
68 &self,
69 chat: Option<&str>,
70 team: Option<&str>,
71 channel: Option<&str>,
72 limit: u16,
73 cursor: Option<&str>,
74 ) -> Result<Page, AppError> {
75 match (self, chat, team, channel) {
76 (Self::Graph(client), ..) => client.messages(chat, team, channel, limit, cursor).await,
77 (Self::Desktop(client), Some(chat), None, None) => {
78 client.messages(chat, limit, cursor).await
79 }
80 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
81 }
82 }
83 pub async fn send(
84 &self,
85 chat: Option<&str>,
86 team: Option<&str>,
87 channel: Option<&str>,
88 body: &str,
89 ) -> Result<Value, AppError> {
90 match (self, chat, team, channel) {
91 (Self::Graph(client), ..) => client.send(chat, team, channel, body).await,
92 (Self::Desktop(client), Some(chat), None, None) => client.send(chat, body).await,
93 (Self::Desktop(_), ..) => Err(desktop::messaging_unsupported()),
94 }
95 }
96}
97
98impl TeamsBackend {
99 pub async fn send_with_id(&self, chat: &str, body: &str, id: &str) -> Result<Value, AppError> {
100 match self {
101 Self::Desktop(client) => client.send_with_id(chat, body, id).await,
102 Self::Graph(client) => client.send(Some(chat), None, None, body).await,
103 }
104 }
105 pub async fn delivery(&self, chat: &str, id: &str) -> Result<Value, AppError> {
106 match self {
107 Self::Desktop(client) => client.delivery(chat, id).await,
108 Self::Graph(_) => Err(AppError::Unsupported("delivery reconciliation by client message ID is available on desktop profiles only; check the conversation before resending".into())),
109 }
110 }
111}