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; }
}