Appflowy ai purchase (#1205)
* chore: api endpoint * chore: clippy * chore: add new api endpoint * chore: add auth * chore: add error code
This commit is contained in:
parent
950563dbef
commit
fe6d11eb25
|
|
@ -431,6 +431,8 @@ pub enum ErrorCode {
|
|||
ApplyUpdateError = 1056,
|
||||
ActionTimeout = 1057,
|
||||
AIImageResponseLimitExceeded = 1058,
|
||||
MailerError = 1059,
|
||||
LicenseError = 1060,
|
||||
}
|
||||
|
||||
impl ErrorCode {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ use client_api_entity::billing_dto::{
|
|||
SubscriptionPlanDetail, WorkspaceUsageAndLimit,
|
||||
};
|
||||
use reqwest::Method;
|
||||
use shared_entity::dto::billing_dto::{
|
||||
LicenseProductSubscriptionLinkQuery, LicensedProductDetail, LicensedProductType,
|
||||
SubscribeProductLicense, UserSubscribeProduct,
|
||||
};
|
||||
use shared_entity::{
|
||||
dto::billing_dto::{RecurringInterval, SubscriptionPlan, WorkspaceSubscriptionStatus},
|
||||
response::{AppResponse, AppResponseError},
|
||||
|
|
@ -222,4 +226,96 @@ impl Client {
|
|||
.await?
|
||||
.into_data()
|
||||
}
|
||||
|
||||
/// Return all licensed products.
|
||||
pub async fn get_license_product_subscriptions(
|
||||
&self,
|
||||
) -> Result<Vec<LicensedProductDetail>, AppResponseError> {
|
||||
let url = format!(
|
||||
"{}/billing/api/v1/license/products",
|
||||
self.base_billing_url(),
|
||||
);
|
||||
let resp = self
|
||||
.http_client_with_auth(Method::GET, &url)
|
||||
.await?
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
AppResponse::<Vec<LicensedProductDetail>>::from_response(resp)
|
||||
.await?
|
||||
.into_data()
|
||||
}
|
||||
|
||||
/// Returns products that user already subscribed to
|
||||
pub async fn get_user_license_products(&self) -> Result<UserSubscribeProduct, AppResponseError> {
|
||||
let url = format!(
|
||||
"{}/billing/api/v1/license/user/products",
|
||||
self.base_billing_url(),
|
||||
);
|
||||
let resp = self
|
||||
.http_client_with_auth(Method::GET, &url)
|
||||
.await?
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
AppResponse::<UserSubscribeProduct>::from_response(resp)
|
||||
.await?
|
||||
.into_data()
|
||||
}
|
||||
|
||||
pub async fn get_license_product_detail(
|
||||
&self,
|
||||
product_id: &str,
|
||||
) -> Result<Vec<SubscribeProductLicense>, AppResponseError> {
|
||||
let url = format!(
|
||||
"{}/billing/api/v1/license/user/product/{}",
|
||||
self.base_billing_url(),
|
||||
product_id
|
||||
);
|
||||
let resp = self
|
||||
.http_client_with_auth(Method::GET, &url)
|
||||
.await?
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
AppResponse::<Vec<SubscribeProductLicense>>::from_response(resp)
|
||||
.await?
|
||||
.into_data()
|
||||
}
|
||||
|
||||
pub async fn active_license_product(&self, product_id: &str) -> Result<(), AppResponseError> {
|
||||
let url = format!(
|
||||
"{}/billing/api/v1/license/user/product/{}/active",
|
||||
self.base_billing_url(),
|
||||
product_id
|
||||
);
|
||||
let resp = self
|
||||
.http_client_without_auth(Method::POST, &url)
|
||||
.await?
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
AppResponse::<()>::from_response(resp).await?.into_data()
|
||||
}
|
||||
|
||||
pub async fn get_license_product_subscription_link(
|
||||
&self,
|
||||
product_type: LicensedProductType,
|
||||
) -> Result<String, AppResponseError> {
|
||||
let query = LicenseProductSubscriptionLinkQuery { product_type };
|
||||
let url = format!(
|
||||
"{}/billing/api/v1/license/subscription-link",
|
||||
self.base_billing_url(),
|
||||
);
|
||||
let resp = self
|
||||
.http_client_without_auth(Method::GET, &url)
|
||||
.await?
|
||||
.query(&query)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
AppResponse::<String>::from_response(resp)
|
||||
.await?
|
||||
.into_data()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
|
|
@ -171,3 +173,58 @@ pub struct SubscriptionTrialRequest {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub period_days: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LicensedProductDetail {
|
||||
pub name: String,
|
||||
pub currency: Currency,
|
||||
pub price_cents: i64,
|
||||
pub recurring_interval: RecurringInterval,
|
||||
pub product_type: LicensedProductType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct UserSubscribeProduct {
|
||||
pub email: String,
|
||||
pub product_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SubscribeProductLicense {
|
||||
pub product_id: String,
|
||||
pub policy_id: String,
|
||||
pub license_id: String,
|
||||
pub metadata: serde_json::Value,
|
||||
pub max_machines: i32,
|
||||
pub unlimited_devices: bool,
|
||||
pub expires_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde_repr::Serialize_repr, serde_repr::Deserialize_repr)]
|
||||
#[repr(u8)]
|
||||
pub enum LicensedProductType {
|
||||
Unknown = 0,
|
||||
AppFlowyAI = 1,
|
||||
}
|
||||
|
||||
impl Display for LicensedProductType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", (self.clone() as u8))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for LicensedProductType {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
"1" => Ok(LicensedProductType::AppFlowyAI),
|
||||
_ => Err(format!("Invalid LicensedProductType value: {}", value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct LicenseProductSubscriptionLinkQuery {
|
||||
pub product_type: LicensedProductType,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue