Skip to content

Commit 4923c52

Browse files
merge origin/main, resolve conflict in types.rs
Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
2 parents 15aeb57 + e750344 commit 4923c52

File tree

10 files changed

+590
-152
lines changed

10 files changed

+590
-152
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/web/src/routes/_view/product/ai-notetaking.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ function HeroSection() {
103103
<div className="px-6 py-12 lg:py-20">
104104
<header className="mb-12 text-center max-w-4xl mx-auto">
105105
<h1 className="text-4xl sm:text-5xl font-serif tracking-tight text-stone-600 mb-6">
106-
Never Miss a Detail From Your Meetings
106+
AI Notepad for Smarter Meeting Notes
107107
</h1>
108108
<p className="text-lg sm:text-xl text-neutral-600">
109-
Hyprnote captures everything said, combines it with your notes,
110-
<br className="hidden sm:inline" /> and creates a perfect summary.
109+
You focus on the conversation. AI transcribes, summarizes,
110+
<br className="hidden sm:inline" /> and fills in what you missed.
111111
</p>
112112
<div className="mt-8">
113113
<Link

crates/api-integration/src/routes/connect.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,24 @@ pub async fn create_connect_session(
4242
.map_err(|e| IntegrationError::Auth(e.to_string()))?;
4343
let user_id = claims.sub;
4444

45-
let req = hypr_nango::NangoConnectSessionRequest {
46-
end_user: hypr_nango::NangoConnectSessionRequestUser {
45+
let req = hypr_nango::CreateConnectSessionRequest {
46+
end_user: hypr_nango::EndUser {
4747
id: user_id,
4848
display_name: None,
4949
email: None,
50+
tags: None,
5051
},
5152
organization: None,
52-
allowed_integrations: vec![],
53+
allowed_integrations: None,
5354
integrations_config_defaults: None,
5455
};
5556

56-
let res = state.nango.create_connect_session(req).await?;
57+
let session = state.nango.create_connect_session(req).await?;
5758

58-
match res {
59-
hypr_nango::NangoConnectSessionResponse::Ok { token, expires_at } => {
60-
Ok(Json(ConnectSessionResponse { token, expires_at }))
61-
}
62-
hypr_nango::NangoConnectSessionResponse::Error { code } => {
63-
Err(IntegrationError::Nango(code))
64-
}
65-
}
59+
Ok(Json(ConnectSessionResponse {
60+
token: session.token,
61+
expires_at: session.expires_at,
62+
}))
6663
}
6764

6865
fn extract_token(headers: &HeaderMap) -> Result<&str> {

crates/nango/src/client.rs

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
use serde::de::DeserializeOwned;
2+
13
use crate::proxy::NangoProxyBuilder;
2-
use crate::types::*;
4+
use crate::types::NangoIntegration;
5+
6+
pub(crate) fn append_query(url: &mut url::Url, key: &str, value: &str) {
7+
url.query_pairs_mut().append_pair(key, value);
8+
}
39

410
#[derive(Clone, Default)]
511
pub struct NangoClientBuilder {
@@ -48,41 +54,27 @@ impl NangoClientBuilder {
4854
}
4955
}
5056

51-
impl NangoClient {
52-
pub async fn get_connection(
53-
&self,
54-
connection_id: impl std::fmt::Display,
55-
) -> Result<NangoGetConnectionResponseData, crate::Error> {
56-
let mut url = self.api_base.clone();
57-
url.set_path(&format!("/connection/{}", connection_id));
58-
59-
let res: NangoGetConnectionResponse = self.client.get(url).send().await?.json().await?;
60-
match res {
61-
NangoGetConnectionResponse::Ok(data) => Ok(*data),
62-
NangoGetConnectionResponse::Error { message } => Err(crate::Error::NangoError(message)),
63-
}
57+
pub(crate) async fn check_response(
58+
response: reqwest::Response,
59+
) -> Result<reqwest::Response, crate::Error> {
60+
let status = response.status();
61+
if status.is_success() {
62+
Ok(response)
63+
} else {
64+
let status_code = status.as_u16();
65+
let body = response.text().await.unwrap_or_default();
66+
Err(crate::Error::Api(status_code, body))
6467
}
68+
}
6569

66-
pub async fn create_connect_session(
67-
&self,
68-
req: NangoConnectSessionRequest,
69-
) -> Result<NangoConnectSessionResponse, crate::Error> {
70-
let mut url = self.api_base.clone();
71-
url.set_path("/connect/sessions");
72-
73-
let res = self
74-
.client
75-
.post(url)
76-
.header("Content-Type", "application/json")
77-
.json(&req)
78-
.send()
79-
.await?
80-
.json()
81-
.await?;
82-
83-
Ok(res)
84-
}
70+
pub(crate) async fn parse_response<T: DeserializeOwned>(
71+
response: reqwest::Response,
72+
) -> Result<T, crate::Error> {
73+
let response = check_response(response).await?;
74+
Ok(response.json().await?)
75+
}
8576

77+
impl NangoClient {
8678
pub fn for_connection(
8779
&self,
8880
integration: NangoIntegration,
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
use std::collections::HashMap;
2+
3+
use crate::client::NangoClient;
4+
use crate::common_derives;
5+
6+
common_derives! {
7+
pub struct CreateConnectSessionRequest {
8+
pub end_user: EndUser,
9+
#[serde(skip_serializing_if = "Option::is_none")]
10+
pub organization: Option<Organization>,
11+
#[serde(skip_serializing_if = "Option::is_none")]
12+
pub allowed_integrations: Option<Vec<String>>,
13+
#[serde(skip_serializing_if = "Option::is_none")]
14+
pub integrations_config_defaults: Option<HashMap<String, IntegrationConfigDefault>>,
15+
}
16+
}
17+
18+
common_derives! {
19+
pub struct EndUser {
20+
pub id: String,
21+
#[serde(skip_serializing_if = "Option::is_none")]
22+
pub email: Option<String>,
23+
#[serde(skip_serializing_if = "Option::is_none")]
24+
pub display_name: Option<String>,
25+
#[serde(skip_serializing_if = "Option::is_none")]
26+
pub tags: Option<HashMap<String, String>>,
27+
}
28+
}
29+
30+
common_derives! {
31+
pub struct Organization {
32+
pub id: String,
33+
#[serde(skip_serializing_if = "Option::is_none")]
34+
pub display_name: Option<String>,
35+
}
36+
}
37+
38+
common_derives! {
39+
pub struct IntegrationConfigDefault {
40+
#[serde(skip_serializing_if = "Option::is_none")]
41+
pub user_scopes: Option<String>,
42+
#[serde(skip_serializing_if = "Option::is_none")]
43+
pub connection_config: Option<ConnectionConfigOverride>,
44+
}
45+
}
46+
47+
common_derives! {
48+
pub struct ConnectionConfigOverride {
49+
#[serde(skip_serializing_if = "Option::is_none")]
50+
pub oauth_scopes_override: Option<String>,
51+
}
52+
}
53+
54+
common_derives! {
55+
pub struct ConnectSession {
56+
pub token: String,
57+
#[serde(skip_serializing_if = "Option::is_none")]
58+
pub connect_link: Option<String>,
59+
pub expires_at: String,
60+
}
61+
}
62+
63+
common_derives! {
64+
pub struct ReconnectSessionRequest {
65+
pub connection_id: String,
66+
pub integration_id: String,
67+
}
68+
}
69+
70+
#[derive(serde::Deserialize)]
71+
pub(crate) struct DataWrapper<T> {
72+
pub data: T,
73+
}
74+
75+
impl NangoClient {
76+
pub async fn create_connect_session(
77+
&self,
78+
req: CreateConnectSessionRequest,
79+
) -> Result<ConnectSession, crate::Error> {
80+
let mut url = self.api_base.clone();
81+
url.set_path("/connect/sessions");
82+
83+
let response = self.client.post(url).json(&req).send().await?;
84+
let wrapper: DataWrapper<ConnectSession> = crate::client::parse_response(response).await?;
85+
Ok(wrapper.data)
86+
}
87+
88+
pub async fn reconnect_session(
89+
&self,
90+
req: ReconnectSessionRequest,
91+
) -> Result<ConnectSession, crate::Error> {
92+
let mut url = self.api_base.clone();
93+
url.set_path("/connect/sessions/reconnect");
94+
95+
let response = self.client.post(url).json(&req).send().await?;
96+
let wrapper: DataWrapper<ConnectSession> = crate::client::parse_response(response).await?;
97+
Ok(wrapper.data)
98+
}
99+
100+
pub async fn get_connect_session(&self) -> Result<ConnectSession, crate::Error> {
101+
let mut url = self.api_base.clone();
102+
url.set_path("/connect/session");
103+
104+
let response = self.client.get(url).send().await?;
105+
let wrapper: DataWrapper<ConnectSession> = crate::client::parse_response(response).await?;
106+
Ok(wrapper.data)
107+
}
108+
109+
pub async fn delete_connect_session(&self) -> Result<(), crate::Error> {
110+
let mut url = self.api_base.clone();
111+
url.set_path("/connect/session");
112+
113+
let response = self.client.delete(url).send().await?;
114+
crate::client::check_response(response).await?;
115+
Ok(())
116+
}
117+
}

0 commit comments

Comments
 (0)