d_id/endpoints/video/
talks.rs

1// File: talks.rs
2// Path: src/endpoints/video/talks.rs
3
4
5#[cfg(test)]
6mod tests {
7    use super::*;
8
9    #[test]
10    fn talk_request_body_is_formatting_with_text_script() {
11        let talk_req_bod = TalkRequestBody {
12            source_url: "www.dummyurl.com".to_string(),
13            driver_url: None,
14            script: Script::Text {
15                r#type: "text".to_string(),
16                subtitles: false,
17                provider: Some(TTSProvider::MicrosoftTTS {
18                    r#type: "microsoft".to_string(),
19                    voice_id: "en-US-JennyNeural".to_string(),
20                }),
21                input: "Hello world!".to_string(),
22                ssml: false,
23            },
24            config: None,
25            user_data: "".to_string(),
26            name: "".to_string(),
27            webhook: "".to_string(),
28            result_url: "".to_string(),
29            face: None,
30            persist: false,
31        };
32
33        let talk_req_bod2 = TalkRequestBodyBuilder::with_text_script().unwrap()
34            .source_url("www.dummyurl.com").unwrap()
35            .input("Hello world!").unwrap()
36            .build().unwrap();
37
38        let want = serde_json::to_string(&talk_req_bod).unwrap();
39        let got = serde_json::to_string(&talk_req_bod2).unwrap();
40
41        assert_eq!(want, got);
42
43
44    }
45
46    #[test]
47    fn talk_request_body_is_formatting_with_audio_script() {
48        let talk_req_bod = TalkRequestBody {
49            source_url: "www.dummyurl.com".to_string(),
50            driver_url: None,
51            script: Script::Audio {
52                r#type: "audio".to_string(),
53                subtitles: false,
54                audio_url: "www.dummyaudiourl.com".to_string(),
55                reduce_noise: false,
56            },
57            config: None,
58            user_data: "".to_string(),
59            name: "".to_string(),
60            webhook: "".to_string(),
61            result_url: "".to_string(),
62            face: None,
63            persist: false,
64        };
65
66        let talk_req_bod2 = TalkRequestBodyBuilder::with_audio_script().unwrap()
67            .source_url("www.dummyurl.com").unwrap()
68            .audio_url("www.dummyaudiourl.com").unwrap()
69            .build().unwrap();
70
71        let want = serde_json::to_string(&talk_req_bod).unwrap();
72        let got = serde_json::to_string(&talk_req_bod2).unwrap();
73
74        assert_eq!(want, got);
75    }
76}
77
78
79use super::*;
80
81
82const TALKS_PATH: &str = "/talks";
83
84#[derive(Serialize, Deserialize, Debug)]
85pub struct TalkRequestBody {
86    source_url: String,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    driver_url: Option<Driver>,
89    script: Script,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    config: Option<Config>,
92    #[serde(skip_serializing_if = "String::is_empty")]
93    user_data: String,
94    #[serde(skip_serializing_if = "String::is_empty")]
95    name: String,
96    #[serde(skip_serializing_if = "String::is_empty")]
97    webhook: String,
98    #[serde(skip_serializing_if = "String::is_empty")]
99    result_url: String,
100    #[serde(skip_serializing_if = "Option::is_none")]
101    face: Option<Face>,
102    persist: bool,
103}
104
105impl TalkRequestBody {
106    pub async fn create_talk(&self) -> Result<CreateTalkResponse> {
107        let c = ClientBuilder::new()?
108            .method(POST)?
109            .path(TALKS_PATH)?
110            .header(CONTENT_TYPE, APPLICATION_JSON)?
111            .build()?;
112
113        let resp = c.send_request(Full::<Bytes>::new(serde_json::to_string(&self)?.into())).await?;
114
115        let talk_resp= serde_json::from_slice::<CreateTalkResponse>(&resp.as_ref())?;
116
117        Ok(talk_resp)
118    }
119
120
121}
122pub async fn get_talk(id: &str) -> Result<GetTalkResponse> {
123    let c = ClientBuilder::new()?
124        .method(GET)?
125        .path(&format!("{}/{}", TALKS_PATH, id))?
126        .header(CONTENT_TYPE, APPLICATION_JSON)?
127        .build()?;
128
129    let resp = c.send_request(Empty::<Bytes>::new()).await?;
130
131    let json = serde_json::from_slice::<GetTalkResponse>(&resp.as_ref())?;
132
133    Ok(json)
134}
135
136pub async fn get_talks() -> Result<GetTalksResponse> {
137    let c = ClientBuilder::new()?
138        .method(GET)?
139        .path(TALKS_PATH)?
140        .header(CONTENT_TYPE, APPLICATION_JSON)?
141        .build()?;
142
143    let resp = c.send_request(Empty::<Bytes>::new()).await?;
144
145    let json = serde_json::from_slice::<GetTalksResponse>(&resp.as_ref())?;
146
147    Ok(json)
148}
149
150pub async fn delete_talk(id: &str) -> Result<()> {
151    let c = ClientBuilder::new()?
152        .method(DELETE)?
153        .path(&format!("{}/{}", TALKS_PATH, id))?
154        .header(CONTENT_TYPE, APPLICATION_JSON)?
155        .build()?;
156
157    let _resp = c.send_request(Empty::<Bytes>::new()).await?;
158
159    Ok(())
160}
161
162#[derive(Serialize, Deserialize, Debug)]
163pub struct CreateTalkResponse {
164    pub id: String,
165    pub object: String,
166    pub created_by: String,
167    pub created_at: String,
168    pub status: String,
169}
170
171#[derive(Serialize, Deserialize, Debug)]
172pub struct GetTalkResponse {
173    pub id: String,
174    pub user_id: String,
175    pub source_url: String,
176    pub created_at: String,
177    pub audio_url: String,
178    pub started_at: String,
179    pub modified_at: String,
180    pub status: String,
181    pub result_url: String,
182}
183
184#[derive(Serialize, Deserialize, Debug)]
185pub struct GetTalksResponse {
186    pub talks: Vec<GetTalkResponse>,
187}
188
189
190
191pub struct TalkRequestBodyBuilder {
192    source_url: Option<String>,
193    driver_url: Option<Driver>,
194    script: Option<Script>,
195    config: Option<Config>,
196    user_data: Option<String>,
197    name: Option<String>,
198    webhook: Option<String>,
199    result_url: Option<String>,
200    face: Option<Face>,
201    persist: Option<bool>,
202}
203
204impl TalkRequestBodyBuilder {
205    pub fn with_text_script() -> Self {
206        let script = Script::Text {
207            r#type: "text".to_string(),
208            subtitles: false,
209            provider: Some(TTSProvider::MicrosoftTTS {
210                r#type: "microsoft".to_string(),
211                voice_id: "en-US-JennyNeural".to_string(),
212            }),
213            input: "".to_string(),
214            ssml: false,
215        };
216
217        Self {
218            source_url: None,
219            driver_url: None,
220            script: Some(script),
221            config: None,
222            user_data: None,
223            name: None,
224            webhook: None,
225            result_url: None,
226            face: None,
227            persist: None,
228        }
229    }
230
231    pub fn with_audio_script() -> Self {
232        let script = Script::Audio {
233            r#type: "audio".to_string(),
234            subtitles: false,
235            audio_url: "".to_string(),
236            reduce_noise: false,
237        };
238
239        Self {
240            source_url: None,
241            driver_url: None,
242            script: Some(script),
243            config: None,
244            user_data: None,
245            name: None,
246            webhook: None,
247            result_url: None,
248            face: None,
249            persist: None,
250        }
251    }
252    pub fn source_url(mut self, source_url: &str) -> Result<Self> {
253        self.source_url = Some(source_url.to_string());
254        Ok(self)
255    }
256
257    pub fn audio_url(mut self, audio_url: &str) -> Result<Self> {
258        if let Some(Script::Audio { audio_url: a, .. }) = self.script.as_mut() {
259            *a = audio_url.to_string();
260        }
261        Ok(self)
262    }
263
264    pub fn driver_url(mut self, driver_url: Driver) -> Result<Self> {
265        self.driver_url = Some(driver_url);
266        Ok(self)
267    }
268
269    pub fn script(mut self, script: Script) -> Result<Self> {
270        self.script = Some(script);
271        Ok(self)
272    }
273
274    pub fn user_data(mut self, user_data: &str) -> Result<Self> {
275        self.user_data = Some(user_data.to_string());
276        Ok(self)
277    }
278
279    pub fn name(mut self, name: &str) -> Result<Self> {
280        self.name = Some(name.to_string());
281        Ok(self)
282    }
283
284    pub fn webhook(mut self, webhook: &str) -> Result<Self> {
285        self.webhook = Some(webhook.to_string());
286        Ok(self)
287    }
288
289    pub fn result_url(mut self, result_url: &str) -> Result<Self> {
290        self.result_url = Some(result_url.to_string());
291        Ok(self)
292    }
293
294    pub fn persist(mut self, persist: bool) -> Result<Self> {
295        self.persist = Some(persist);
296        Ok(self)
297    }
298
299    pub fn input (mut self, input: &str) -> Result<Self> {
300        if let Some(Script::Text { input: i, .. }) = self.script.as_mut() {
301            *i = input.to_string();
302        }
303        Ok(self)
304    }
305
306    pub fn ssml(mut self, ssml: bool) -> Result<Self> {
307        if let Some(Script::Text { ssml: s, .. }) = self.script.as_mut() {
308            *s = ssml;
309        }
310        Ok(self)
311    }
312
313    pub fn subtitles(mut self, subtitles: bool) -> Result<Self> {
314        if let Some(Script::Text { subtitles: s, .. }) = self.script.as_mut() {
315            *s = subtitles;
316        }
317        Ok(self)
318    }
319
320    pub fn provider(mut self, provider: TTSProvider) -> Result<Self> {
321        if let Some(Script::Text { provider: p, .. }) = self.script.as_mut() {
322            *p = Some(provider);
323        }
324        Ok(self)
325    }
326
327   pub fn face(mut self, face: Face) -> Result<Self> {
328        self.face = Some(face);
329        Ok(self)
330    }
331
332    pub fn config(mut self, config: Config) -> Result<Self> {
333        self.config = Some(config);
334        Ok(self)
335    }
336
337    pub fn reduce_noise(mut self, reduce_noise: bool) -> Result<Self> {
338        if let Some(Script::Audio { reduce_noise: r, .. }) = self.script.as_mut() {
339            *r = reduce_noise;
340        }
341        Ok(self)
342    }
343
344
345
346    pub fn build(self) -> Result<TalkRequestBody> {
347        let source_url = self.source_url.ok_or(RequestBodyBuildError::SourceUrlNotSet)?;
348
349        let script = self.script.ok_or(Box::new(RequestBodyBuildError::ScriptNotSet))?;
350
351        Ok(
352            TalkRequestBody {
353                source_url,
354                driver_url: self.driver_url,
355                script,
356                config: self.config,
357                user_data: self.user_data.unwrap_or_default(),
358                name: self.name.unwrap_or_default(),
359                webhook: self.webhook.unwrap_or_default(),
360                result_url: self.result_url.unwrap_or_default(),
361                face: self.face,
362                persist: self.persist.unwrap_or(false),
363            }
364        )
365
366    }
367
368
369}
370