using System.Net.Http.Headers; using System.Text; using System.Text.Json; namespace Chatbeep.Sdk; public class ChatbeepClient { private readonly HttpClient _httpClient; private readonly string? _token; public ChatbeepClient(string apiBase, string? token = null, HttpClient? httpClient = null) { _token = token; _httpClient = httpClient ?? new HttpClient(); _httpClient.BaseAddress = new Uri(apiBase.TrimEnd('/')); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } public Task HealthAsync() { return SendAsync("/health"); } public Task WidgetConfigAsync(string installationToken) { return SendAsync($"/widget/config/{installationToken}"); } public Task WidgetInstallationHealthAsync(string installationToken, string? currentUrl = null) { return SendAsync($"/widget/installations/{installationToken}/health", query: currentUrl is null ? null : new Dictionary { ["current_url"] = currentUrl }); } public Task WidgetPingAsync(object payload) { return SendAsync("/widget/ping", HttpMethod.Post, payload); } public Task UpsertWidgetVisitorAsync(object payload) { return SendAsync("/widget/visitors", HttpMethod.Post, payload); } public Task CreateWidgetConversationAsync(object payload) { return SendAsync("/widget/conversations", HttpMethod.Post, payload); } public Task GetWidgetConversationMessagesAsync(string conversation, string widgetToken, IDictionary? query = null) { query ??= new Dictionary(); query["token"] = widgetToken; return SendAsync($"/widget/conversations/{conversation}/messages", query: query); } public Task SendWidgetConversationMessageAsync(string conversation, object payload) { return SendAsync($"/widget/conversations/{conversation}/messages", HttpMethod.Post, payload); } public Task StartWidgetVerificationAsync(string conversation, object payload) { return SendAsync($"/widget/conversations/{conversation}/verification/start", HttpMethod.Post, payload); } public Task ConfirmWidgetVerificationAsync(string conversation, object payload) { return SendAsync($"/widget/conversations/{conversation}/verification/confirm", HttpMethod.Post, payload); } public Task MobileLoginAsync(object payload) { return SendAsync("/mobile/login", HttpMethod.Post, payload); } public Task MobileMeAsync() { return SendAsync("/mobile/me", auth: true); } public Task MobileConversationsAsync(IDictionary? query = null) { return SendAsync("/mobile/conversations", query: query, auth: true); } public Task MobileConversationAsync(string conversation) { return SendAsync($"/mobile/conversations/{conversation}", auth: true); } public Task SendMobileConversationMessageAsync(string conversation, object payload) { return SendAsync($"/mobile/conversations/{conversation}/messages", HttpMethod.Post, payload, auth: true); } public Task AssignMobileConversationAsync(string conversation, object payload) { return SendAsync($"/mobile/conversations/{conversation}/assign", HttpMethod.Post, payload, auth: true); } public Task TransferMobileConversationAsync(string conversation, object payload) { return SendAsync($"/mobile/conversations/{conversation}/transfer", HttpMethod.Post, payload, auth: true); } public Task CloseMobileConversationAsync(string conversation, object? payload = null) { return SendAsync($"/mobile/conversations/{conversation}/close", HttpMethod.Post, payload ?? new { }, auth: true); } private async Task SendAsync( string path, HttpMethod? method = null, object? payload = null, IDictionary? query = null, bool auth = false) { method ??= HttpMethod.Get; var uri = path; if (query is { Count: > 0 }) { var suffix = string.Join("&", query .Where(item => !string.IsNullOrWhiteSpace(item.Value)) .Select(item => $"{Uri.EscapeDataString(item.Key)}={Uri.EscapeDataString(item.Value ?? string.Empty)}")); if (!string.IsNullOrWhiteSpace(suffix)) { uri = $"{path}?{suffix}"; } } var request = new HttpRequestMessage(method, uri); if (auth && !string.IsNullOrWhiteSpace(_token)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token); } if (payload is not null) { request.Content = new StringContent( JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"); } var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); return JsonDocument.Parse(await response.Content.ReadAsStringAsync()); } }