feat: add EbayAspectsService with Taxonomy API aspect fetching
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
74
EbayListingTool/Services/EbayAspectsService.cs
Normal file
74
EbayListingTool/Services/EbayAspectsService.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System.Net.Http.Headers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace EbayListingTool.Services;
|
||||
|
||||
public class CategoryAspect
|
||||
{
|
||||
public string Name { get; set; } = "";
|
||||
public bool IsRequired { get; set; }
|
||||
public bool IsFreeText { get; set; } = true;
|
||||
public List<string> AllowedValues { get; set; } = new();
|
||||
}
|
||||
|
||||
public class EbayAspectsService
|
||||
{
|
||||
private readonly EbayAuthService _auth;
|
||||
private static readonly HttpClient _http = new();
|
||||
private readonly Dictionary<string, List<CategoryAspect>> _cache = new();
|
||||
|
||||
public EbayAspectsService(EbayAuthService auth) => _auth = auth;
|
||||
|
||||
public async Task<List<CategoryAspect>> GetAspectsAsync(string categoryId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(categoryId)) return new();
|
||||
if (_cache.TryGetValue(categoryId, out var cached)) return cached;
|
||||
|
||||
var token = await _auth.GetAppTokenAsync();
|
||||
var url = $"{_auth.BaseUrl}/commerce/taxonomy/v1/category_tree/3" +
|
||||
$"/get_item_aspects_for_category?category_id={Uri.EscapeDataString(categoryId)}";
|
||||
|
||||
using var req = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
req.Headers.Add("X-EBAY-C-MARKETPLACE-ID", "EBAY_GB");
|
||||
|
||||
var res = await _http.SendAsync(req);
|
||||
var json = await res.Content.ReadAsStringAsync();
|
||||
if (!res.IsSuccessStatusCode) return new();
|
||||
|
||||
var aspects = new List<CategoryAspect>();
|
||||
var arr = JObject.Parse(json)["aspects"] as JArray;
|
||||
if (arr == null) { _cache[categoryId] = aspects; return aspects; }
|
||||
|
||||
foreach (var item in arr)
|
||||
{
|
||||
var constraint = item["aspectConstraint"];
|
||||
if (constraint == null) continue;
|
||||
|
||||
var required = constraint["aspectRequired"]?.Value<bool>() ?? false;
|
||||
var usage = constraint["aspectUsage"]?.ToString() ?? "";
|
||||
if (!required && usage != "RECOMMENDED") continue;
|
||||
|
||||
var aspect = new CategoryAspect
|
||||
{
|
||||
Name = item["localizedAspectName"]?.ToString() ?? "",
|
||||
IsRequired = required,
|
||||
IsFreeText = constraint["aspectMode"]?.ToString() != "SELECTION_ONLY"
|
||||
};
|
||||
|
||||
var values = item["aspectValues"] as JArray;
|
||||
if (values != null)
|
||||
aspect.AllowedValues = values
|
||||
.Select(v => v["localizedValue"]?.ToString() ?? "")
|
||||
.Where(v => !string.IsNullOrEmpty(v))
|
||||
.Take(50)
|
||||
.ToList();
|
||||
|
||||
if (!string.IsNullOrEmpty(aspect.Name))
|
||||
aspects.Add(aspect);
|
||||
}
|
||||
|
||||
_cache[categoryId] = aspects;
|
||||
return aspects;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user