edge_gpt/
conversation_meta.rs1use std::sync::Arc;
2
3use crate::{util::new_reqwest_client, CookieInFile};
4use reqwest::{
5 cookie::Jar,
6 header::{HeaderMap, HeaderValue},
7};
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10use thiserror::Error;
11
12fn create_conversation_headers() -> HeaderMap {
13 let mut headers = HeaderMap::new();
14 headers.insert(
15 "authority",
16 HeaderValue::from_static("edgeservices.bing.com"),
17 );
18 headers.insert("accept", HeaderValue::from_static("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"));
19 headers.insert(
20 "accept-language",
21 HeaderValue::from_static("en-US,en;q=0.9"),
22 );
23 headers.insert("cache-control", HeaderValue::from_static("max-age=0"));
24 headers.insert(
25 "sec-ch-ua",
26 HeaderValue::from_static(
27 "\"Chromium\";v=\"110\", \"Not A(Brand\";v=\"24\", \"Microsoft Edge\";v=\"110\"",
28 ),
29 );
30 headers.insert("sec-ch-ua-arch", HeaderValue::from_static("\"x86\""));
31 headers.insert("sec-ch-ua-bitness", HeaderValue::from_static("\"64\""));
32 headers.insert(
33 "sec-ch-ua-full-version",
34 HeaderValue::from_static("\"110.0.1587.69\""),
35 );
36 headers.insert("sec-ch-ua-full-version-list", HeaderValue::from_static("\"Chromium\";v=\"110.0.5481.192\", \"Not A(Brand\";v=\"24.0.0.0\", \"Microsoft Edge\";v=\"110.0.1587.69\""));
37 headers.insert("sec-ch-ua-mobile", HeaderValue::from_static("?0"));
38 headers.insert("sec-ch-ua-model", HeaderValue::from_static("\"\""));
39 headers.insert(
40 "sec-ch-ua-platform",
41 HeaderValue::from_static("\"Windows\""),
42 );
43 headers.insert(
44 "sec-ch-ua-platform-version",
45 HeaderValue::from_static("\"15.0.0\""),
46 );
47 headers.insert("sec-fetch-dest", HeaderValue::from_static("document"));
48 headers.insert("sec-fetch-mode", HeaderValue::from_static("navigate"));
49 headers.insert("sec-fetch-site", HeaderValue::from_static("none"));
50 headers.insert("sec-fetch-user", HeaderValue::from_static("?1"));
51 headers.insert("upgrade-insecure-requests", HeaderValue::from_static("1"));
52 headers.insert("x-edge-shopping-flag", HeaderValue::from_static("1"));
53 headers.insert("x-forwarded-for", HeaderValue::from_static("1.1.1.1"));
54 headers
55}
56
57#[derive(Serialize, Deserialize, Debug, Clone)]
59#[serde(rename_all = "camelCase")]
60pub struct ConversationMeta {
61 pub conversation_signature: String,
63 pub client_id: String,
65 pub conversation_id: String,
67 result: ConversationMetaResult,
68}
69#[derive(Serialize, Deserialize, Debug, Clone)]
70struct ConversationMetaResult {
71 value: String,
72 message: Option<String>,
73}
74
75impl ConversationMeta {
76 pub async fn create(cookies: &[CookieInFile]) -> Result<ConversationMeta> {
78 let uri = "https://edgeservices.bing.com/edgesvc/turing/conversation/create"
79 .parse()
80 .unwrap();
81 let cookie_jar: Jar = Jar::default();
82 for CookieInFile { name, value } in cookies {
83 cookie_jar.add_cookie_str(&format!("{name}={value}; Domain=bing.com"), &uri)
84 }
85 let response = new_reqwest_client()
86 .cookie_provider(Arc::new(cookie_jar))
87 .build()?
88 .get(uri)
89 .headers(create_conversation_headers())
90 .send()
91 .await?
92 .text()
93 .await?;
94 let value: Value = serde_json::from_str(&response)?;
95 let result = value["result"]["value"].as_str();
96 match result {
97 Some("Success") => {}
98 _ => return Err(ConversationMetaCreatingError::Network),
99 }
100 let meta: ConversationMeta = serde_json::from_value(value)?;
101 Ok(meta)
102 }
103}
104
105#[derive(Error, Debug)]
106pub enum ConversationMetaCreatingError {
107 #[error("Failed to send conversation meta creating request")]
108 Network,
109 #[error("Failed to parse conversation meta creating result")]
110 ParseRespond(#[from] serde_json::Error),
111}
112
113impl From<reqwest::Error> for ConversationMetaCreatingError {
114 fn from(_value: reqwest::Error) -> Self {
115 Self::Network
116 }
117}
118
119pub type Result<T> = std::result::Result<T, ConversationMetaCreatingError>;