livekit_api/services/
agent_dispatch.rs1use super::{twirp_client::TwirpClient, ServiceBase, ServiceResult, LIVEKIT_PACKAGE};
16use crate::{
17 access_token::{AccessTokenError, VideoGrants},
18 get_env_keys,
19};
20use http::header::HeaderMap;
21use livekit_protocol as proto;
22
23const SVC: &str = "AgentDispatchService";
24
25#[derive(Debug)]
26pub struct AgentDispatchClient {
27 base: ServiceBase,
28 client: TwirpClient,
29}
30
31impl AgentDispatchClient {
32 pub fn with_api_key(host: &str, api_key: &str, api_secret: &str) -> Self {
34 Self::build(
35 host,
36 ServiceBase::with_api_key(api_key, api_secret),
37 crate::http_client::Client::new(),
38 )
39 }
40
41 pub fn with_token(host: &str, token: &str) -> Self {
43 Self::build(host, ServiceBase::with_token(token), crate::http_client::Client::new())
44 }
45
46 pub(crate) fn build(host: &str, base: ServiceBase, client: crate::http_client::Client) -> Self {
49 Self { base, client: TwirpClient::with_client(host, LIVEKIT_PACKAGE, None, client) }
50 }
51
52 #[cfg(test)]
53 pub(crate) fn with_default_headers(mut self, headers: http::HeaderMap) -> Self {
54 self.client = self.client.with_default_headers(headers);
55 self
56 }
57
58 pub fn new(host: &str) -> ServiceResult<Self> {
61 let (api_key, api_secret) = get_env_keys()?;
62 Ok(Self::with_api_key(host, &api_key, &api_secret))
63 }
64
65 pub fn with_failover(mut self, enabled: bool) -> Self {
68 self.client = self.client.with_failover(enabled);
69 self
70 }
71
72 pub fn with_request_timeout(mut self, timeout: std::time::Duration) -> Self {
74 self.client = self.client.with_request_timeout(timeout);
75 self
76 }
77
78 pub async fn create_dispatch(
91 &self,
92 req: proto::CreateAgentDispatchRequest,
93 ) -> ServiceResult<proto::AgentDispatch> {
94 const METHOD: &str = "CreateDispatch";
95 let headers = self.auth_headers(req.room.to_string())?;
96 Ok(self.client.request(SVC, METHOD, req, headers).await?)
97 }
98
99 pub async fn delete_dispatch(
109 &self,
110 dispatch_id: impl Into<String>,
111 room_name: impl Into<String>,
112 ) -> ServiceResult<proto::AgentDispatch> {
113 const METHOD: &str = "DeleteDispatch";
114 let req = proto::DeleteAgentDispatchRequest {
115 dispatch_id: dispatch_id.into(),
116 room: room_name.into(),
117 };
118 let headers = self.auth_headers(req.room.to_string())?;
119 Ok(self.client.request(SVC, METHOD, req, headers).await?)
120 }
121
122 pub async fn list_dispatch(
131 &self,
132 room_name: impl Into<String>,
133 ) -> ServiceResult<Vec<proto::AgentDispatch>> {
134 const METHOD: &str = "ListDispatch";
135 let req = proto::ListAgentDispatchRequest { room: room_name.into(), ..Default::default() };
136 let headers = self.auth_headers(req.room.to_string())?;
137 let res: proto::ListAgentDispatchResponse =
138 self.client.request(SVC, METHOD, req, headers).await?;
139 Ok(res.agent_dispatches)
140 }
141
142 pub async fn get_dispatch(
152 &self,
153 dispatch_id: impl Into<String>,
154 room_name: impl Into<String>,
155 ) -> ServiceResult<Option<proto::AgentDispatch>> {
156 const METHOD: &str = "ListDispatch";
157 let req = proto::ListAgentDispatchRequest {
158 room: room_name.into(),
159 dispatch_id: dispatch_id.into(),
160 };
161 let headers = self.auth_headers(req.room.to_string())?;
162 let mut res: proto::ListAgentDispatchResponse =
163 self.client.request(SVC, METHOD, req, headers).await?;
164 Ok(res.agent_dispatches.pop())
165 }
166}
167
168impl AgentDispatchClient {
169 fn auth_headers(&self, room: String) -> Result<HeaderMap, AccessTokenError> {
171 self.base.auth_header(VideoGrants { room, room_admin: true, ..Default::default() }, None)
172 }
173}