using System.Text.Json; using System.Text.Json.Serialization; namespace OASystem.API.OAMethodLib.SnovioAPI; /// /// Snov.io OAuth access_token 请求体。 /// public sealed class SnovioAccessTokenRequest { /// /// OAuth 授权类型,固定为 client_credentials。 /// [JsonPropertyName("grant_type")] public string GrantType { get; set; } = "client_credentials"; /// /// Snov.io Client ID。 /// [JsonPropertyName("client_id")] public string ClientId { get; set; } = string.Empty; /// /// Snov.io Client Secret。 /// [JsonPropertyName("client_secret")] public string ClientSecret { get; set; } = string.Empty; } /// /// Snov.io OAuth access_token 响应体。 /// public sealed class SnovioAccessTokenResponse { /// /// 访问令牌。 /// [JsonPropertyName("access_token")] public string AccessToken { get; set; } = string.Empty; /// /// 令牌类型,通常为 Bearer。 /// [JsonPropertyName("token_type")] public string TokenType { get; set; } = string.Empty; /// /// 令牌有效期,单位为秒。 /// [JsonPropertyName("expires_in")] public int ExpiresIn { get; set; } } /// /// Snov.io 公司数据库搜索请求体。 /// public sealed class SnovioCompanySearchRequest { /// /// 结果页码,默认从第 1 页开始。 /// [JsonPropertyName("page")] public int Page { get; set; } = 1; /// /// 可选的异步结果回调地址。 /// [JsonPropertyName("webhook_url")] public string? WebhookUrl { get; set; } /// /// 公司搜索筛选条件。 /// [JsonPropertyName("filters")] public SnovioCompanySearchFilters Filters { get; set; } = new(); } /// /// Snov.io 公司数据库搜索筛选条件。 /// public sealed class SnovioCompanySearchFilters { /// /// 公司名称、行业、规模、营收和成立年份等筛选条件。 /// [JsonPropertyName("company")] public SnovioCompanyFilter Company { get; set; } = new(); /// /// 公司所在地区的包含和排除条件。 /// [JsonPropertyName("locations")] public SnovioLocationFilter Locations { get; set; } = new(); } /// /// 公司筛选条件。 /// public sealed class SnovioCompanyFilter { /// /// 公司名称包含或排除列表。 /// [JsonPropertyName("name")] public SnovioStringListFilter? Name { get; set; } /// /// 公司行业包含或排除列表。 /// [JsonPropertyName("industries")] public SnovioStringListFilter? Industries { get; set; } /// /// 公司规模,例如 1-10、51-200、10001+。 /// [JsonPropertyName("size")] public string? Size { get; set; } /// /// 公司营收最小值和最大值,单位由 Snov.io 数据源定义。 /// [JsonPropertyName("revenue")] public SnovioRevenueFilter? Revenue { get; set; } /// /// 公司专长或业务领域列表。 /// [JsonPropertyName("specialities")] public List Specialities { get; set; } = new(); /// /// 公司成立年份范围。 /// [JsonPropertyName("founded")] public SnovioFoundedFilter? Founded { get; set; } } /// /// 字符串列表包含/排除条件。 /// public sealed class SnovioStringListFilter { /// /// 需要匹配的字符串列表。 /// [JsonPropertyName("include")] public List Include { get; set; } = new(); /// /// 需要排除的字符串列表。 /// [JsonPropertyName("exclude")] public List Exclude { get; set; } = new(); } /// /// 地区包含/排除条件。 /// public sealed class SnovioLocationFilter { /// /// 需要包含的地区条件。 /// [JsonPropertyName("include")] public SnovioLocationFilterItem? Include { get; set; } /// /// 需要排除的地区条件。 /// [JsonPropertyName("exclude")] public SnovioLocationFilterItem? Exclude { get; set; } } /// /// 地区条件明细。 /// public sealed class SnovioLocationFilterItem { /// /// 地区名称,例如 London 或 Atlanta。 /// [JsonPropertyName("locality")] public string? Locality { get; set; } /// /// 地区类型,例如 city、state、country、region、subregion。 /// [JsonPropertyName("location_type")] public string? LocationType { get; set; } } /// /// 公司营收范围。 /// public sealed class SnovioRevenueFilter { /// /// 营收下限。 /// [JsonPropertyName("min")] public long? Min { get; set; } /// /// 营收上限。 /// [JsonPropertyName("max")] public long? Max { get; set; } } /// /// 公司成立年份范围。 /// public sealed class SnovioFoundedFilter { /// /// 成立年份下限。 /// [JsonPropertyName("from")] public int? From { get; set; } /// /// 成立年份上限。 /// [JsonPropertyName("till")] public int? Till { get; set; } } /// /// Snov.io 公司搜索创建任务响应体。 /// public sealed class SnovioCompanySearchStartResponse { /// /// 创建任务时通常为空数组。 /// [JsonPropertyName("data")] public List Data { get; set; } = new(); /// /// 创建任务的元数据,包含 task_hash 和页码。 /// [JsonPropertyName("meta")] public SnovioCompanySearchStartMeta Meta { get; set; } = new(); /// /// Snov.io 返回的结果查询地址。 /// [JsonPropertyName("links")] public SnovioApiLinks Links { get; set; } = new(); /// /// 创建任务响应状态。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// Snov.io 公司搜索创建任务元数据。 /// public sealed class SnovioCompanySearchStartMeta { /// /// 异步公司搜索任务唯一标识,用于查询结果。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } /// /// 本次搜索请求的结果页码。 /// [JsonPropertyName("page")] public int Page { get; set; } } /// /// Snov.io 公司搜索结果响应体。 /// public sealed class SnovioCompanySearchResultResponse { /// /// 公司搜索结果数据。 /// [JsonPropertyName("data")] public SnovioCompanySearchResultData Data { get; set; } = new(); /// /// 公司搜索任务元数据。 /// [JsonPropertyName("meta")] public SnovioCompanySearchResultMeta Meta { get; set; } = new(); /// /// 文档示例中该字段为空数组。 /// [JsonPropertyName("links")] public List Links { get; set; } = new(); /// /// 任务处理状态,例如 completed 或 in_progress。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// 公司搜索结果数据。 /// public sealed class SnovioCompanySearchResultData { /// /// 符合筛选条件的公司总数。 /// [JsonPropertyName("total")] public long Total { get; set; } /// /// 当前结果页码。 /// [JsonPropertyName("page")] public int Page { get; set; } /// /// 结果总页数。 /// [JsonPropertyName("total_pages")] public int TotalPages { get; set; } /// /// 当前页的公司列表。 /// [JsonPropertyName("companies")] public List Companies { get; set; } = new(); } /// /// Snov.io 公司搜索结果中的公司信息。 /// public sealed class SnovioCompanySearchCompany { /// /// 公司名称。 /// [JsonPropertyName("name")] public string? Name { get; set; } /// /// 公司域名。 /// [JsonPropertyName("domain")] public string? Domain { get; set; } /// /// 公司所在地区。 /// [JsonPropertyName("location")] public string? Location { get; set; } /// /// 公司所属行业。 /// [JsonPropertyName("industry")] public string? Industry { get; set; } /// /// 公司规模。 /// [JsonPropertyName("size")] public string? Size { get; set; } /// /// 公司营收信息。 /// [JsonPropertyName("revenue")] public SnovioCompanyRevenue? Revenue { get; set; } /// /// 公司 Logo 地址。 /// [JsonPropertyName("logo_url")] public string? LogoUrl { get; set; } } /// /// 公司搜索结果中的公司营收信息。 /// public sealed class SnovioCompanyRevenue { /// /// 营收区间下限。 /// [JsonPropertyName("min")] public long? Min { get; set; } /// /// 营收区间上限。 /// [JsonPropertyName("max")] public long? Max { get; set; } /// /// Snov.io 返回的营收值。 /// [JsonPropertyName("reported")] public long? Reported { get; set; } } /// /// 公司搜索结果元数据。 /// public sealed class SnovioCompanySearchResultMeta { /// /// 异步公司搜索任务唯一标识。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } /// /// 当前结果页码。 /// [JsonPropertyName("page")] public int Page { get; set; } } /// /// Snov.io 域名潜在客户搜索请求体。 /// public sealed class SnovioDomainProspectsSearchRequest { /// /// 要搜索的公司域名,例如 snov.io。 /// [JsonPropertyName("domain")] public string Domain { get; set; } = string.Empty; /// /// 结果页码,默认从第 1 页开始。 /// [JsonPropertyName("page")] public int Page { get; set; } = 1; /// /// 潜在客户职位列表,最多 10 个。 /// [JsonPropertyName("positions")] public List Positions { get; set; } = new(); /// /// 可选的异步结果回调地址。 /// [JsonPropertyName("webhook_url")] public string? WebhookUrl { get; set; } } /// /// Snov.io 域名潜在客户搜索创建任务响应体。 /// public sealed class SnovioDomainProspectsSearchStartResponse { /// /// 创建任务时通常为空数组。 /// [JsonPropertyName("data")] public List Data { get; set; } = new(); /// /// 创建任务的元数据,包含域名、页码、职位和 task_hash。 /// [JsonPropertyName("meta")] public SnovioDomainProspectsSearchStartMeta Meta { get; set; } = new(); /// /// Snov.io 返回的结果查询地址。 /// [JsonPropertyName("links")] public SnovioApiLinks Links { get; set; } = new(); /// /// 创建任务响应状态。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// Snov.io 域名潜在客户搜索创建任务元数据。 /// public sealed class SnovioDomainProspectsSearchStartMeta { /// /// 本次搜索的公司域名。 /// [JsonPropertyName("domain")] public string? Domain { get; set; } /// /// 结果类型,潜客搜索通常为 prospects。 /// [JsonPropertyName("tab")] public string? Tab { get; set; } /// /// 异步域名潜客搜索任务唯一标识。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } /// /// 本次搜索请求的结果页码。 /// [JsonPropertyName("page")] public int Page { get; set; } /// /// 用于筛选潜客的职位列表。 /// [JsonPropertyName("positions")] public List Positions { get; set; } = new(); } /// /// Snov.io 域名潜在客户搜索结果响应体。 /// public sealed class SnovioDomainProspectsSearchResultResponse { /// /// 当前页的潜在客户列表。 /// [JsonPropertyName("data")] public List Data { get; set; } = new(); /// /// 域名潜在客户搜索结果元数据。 /// [JsonPropertyName("meta")] public SnovioDomainProspectsSearchResultMeta Meta { get; set; } = new(); /// /// 下一页结果链接信息。 /// [JsonPropertyName("links")] public SnovioApiLinks Links { get; set; } = new(); /// /// 任务处理状态,例如 completed 或 in_progress。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// Snov.io 域名潜在客户搜索结果中的潜客信息。 /// public sealed class SnovioDomainProspect { /// /// 潜客名。 /// [JsonPropertyName("first_name")] public string? FirstName { get; set; } /// /// 潜客姓。 /// [JsonPropertyName("last_name")] public string? LastName { get; set; } /// /// 潜客职位。 /// [JsonPropertyName("position")] public string? Position { get; set; } /// /// Snov.io 获取该潜客信息的来源页面。 /// [JsonPropertyName("source_page")] public string? SourcePage { get; set; } /// /// 启动该潜客邮箱检索任务的地址,地址末段包含 prospect_hash。 /// [JsonPropertyName("search_emails_start")] public string? SearchEmailsStart { get; set; } } /// /// Snov.io 域名潜在客户搜索结果元数据。 /// public sealed class SnovioDomainProspectsSearchResultMeta { /// /// 本次搜索的公司域名。 /// [JsonPropertyName("domain")] public string? Domain { get; set; } /// /// 结果类型,潜客搜索通常为 prospects。 /// [JsonPropertyName("tab")] public string? Tab { get; set; } /// /// 异步域名潜客搜索任务唯一标识。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } /// /// 当前结果页码。 /// [JsonPropertyName("page")] public int Page { get; set; } /// /// 本次搜索使用的职位筛选列表。 /// [JsonPropertyName("positions")] public List Positions { get; set; } = new(); /// /// 符合条件的潜客总数。 /// [JsonPropertyName("total_count")] public int TotalCount { get; set; } } /// /// Snov.io 潜客邮箱检索请求体。 /// public sealed class SnovioProspectEmailSearchRequest { /// /// 可选的异步任务回调地址。 /// [JsonPropertyName("webhook_url")] public string? WebhookUrl { get; set; } } /// /// Snov.io 潜客邮箱检索创建任务响应体。 /// public sealed class SnovioProspectEmailSearchStartResponse { /// /// 创建任务时通常为空数组。 /// [JsonPropertyName("data")] public List Data { get; set; } = new(); /// /// 创建任务的元数据,包含邮箱检索 task_hash。 /// [JsonPropertyName("meta")] public SnovioProspectEmailSearchStartMeta Meta { get; set; } = new(); /// /// Snov.io 返回的邮箱结果查询地址。 /// [JsonPropertyName("links")] public SnovioApiLinks Links { get; set; } = new(); /// /// 创建任务响应状态。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// Snov.io 潜客邮箱检索创建任务元数据。 /// public sealed class SnovioProspectEmailSearchStartMeta { /// /// 异步邮箱检索任务唯一标识,用于查询邮箱结果。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } } /// /// Snov.io 潜客邮箱检索结果响应体。 /// public sealed class SnovioProspectEmailSearchResultResponse { /// /// 潜客邮箱检索结果数据。 /// [JsonPropertyName("data")] public SnovioProspectEmailSearchResultData Data { get; set; } = new(); /// /// 邮箱检索任务元数据。 /// [JsonPropertyName("meta")] public SnovioProspectEmailSearchResultMeta Meta { get; set; } = new(); // 文档示例中该字段返回空数组,因此使用 JsonElement 列表兼容实际响应。 [JsonPropertyName("links")] public List Links { get; set; } = new(); /// /// 任务处理状态,例如 completed 或 in_progress。 /// [JsonPropertyName("status")] public string? Status { get; set; } } /// /// Snov.io 潜客邮箱检索结果数据。 /// [System.Text.Json.Serialization.JsonConverter(typeof(SnovioProspectEmailSearchResultDataConverter))] public sealed class SnovioProspectEmailSearchResultData { /// /// 邮箱检索任务开始时间。 /// [JsonPropertyName("searching_date")] public string? SearchingDate { get; set; } /// /// 当前潜客检索到的邮箱列表。 /// [JsonPropertyName("emails")] public List Emails { get; set; } = new(); } /// /// 兼容 Snov.io 潜客邮箱结果中 data 为对象或空数组的响应转换器。 /// internal sealed class SnovioProspectEmailSearchResultDataConverter : System.Text.Json.Serialization.JsonConverter { public override SnovioProspectEmailSearchResultData Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Null) return new SnovioProspectEmailSearchResultData(); if (reader.TokenType == JsonTokenType.StartObject) { using var document = JsonDocument.ParseValue(ref reader); var root = document.RootElement; var result = new SnovioProspectEmailSearchResultData(); if (root.TryGetProperty("searching_date", out var searchingDate) && searchingDate.ValueKind == JsonValueKind.String) { result.SearchingDate = searchingDate.GetString(); } if (root.TryGetProperty("emails", out var emailsElement) && emailsElement.ValueKind == JsonValueKind.Array) { result.Emails = emailsElement.Deserialize>(options) ?? new List(); } return result; } if (reader.TokenType == JsonTokenType.StartArray) { using var document = JsonDocument.ParseValue(ref reader); var emails = document.RootElement.Deserialize>(options); return new SnovioProspectEmailSearchResultData { Emails = emails ?? new List() }; } throw new System.Text.Json.JsonException( "Snov.io 潜客邮箱检索响应中的 data 必须是对象、数组或 null。"); } public override void Write( Utf8JsonWriter writer, SnovioProspectEmailSearchResultData value, JsonSerializerOptions options) { writer.WriteStartObject(); if (value.SearchingDate != null) writer.WriteString("searching_date", value.SearchingDate); writer.WritePropertyName("emails"); System.Text.Json.JsonSerializer.Serialize(writer, value.Emails, options); writer.WriteEndObject(); } } /// /// Snov.io 潜客邮箱信息。 /// public sealed class SnovioProspectEmail { /// /// 潜客邮箱地址。 /// [JsonPropertyName("email")] public string? Email { get; set; } /// /// SMTP 校验状态,例如 valid 或 unknown。 /// [JsonPropertyName("smtp_status")] public string? SmtpStatus { get; set; } } /// /// Snov.io 潜客邮箱检索结果元数据。 /// public sealed class SnovioProspectEmailSearchResultMeta { /// /// 异步邮箱检索任务唯一标识。 /// [JsonPropertyName("task_hash")] public string? TaskHash { get; set; } } /// /// Snov.io 异步任务结果链接。 /// public sealed class SnovioApiLinks { /// /// 当前异步任务的结果查询地址。 /// [JsonPropertyName("result")] public string? Result { get; set; } /// /// 下一页结果地址;没有下一页时通常为空字符串或 null。 /// [JsonPropertyName("next")] public string? Next { get; set; } }