feat: implement Chatika account activation job for new club members

This commit is contained in:
masoodafar-web
2025-12-23 22:52:49 +03:30
parent 30144a07c8
commit 288b85a59b
10 changed files with 908 additions and 2 deletions
@@ -0,0 +1,156 @@
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using CMSMicroservice.Application.Common.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Infrastructure.Services;
/// <summary>
/// پیاده‌سازی سرویس چتیکا با HttpClient
/// API: POST /api/v1/organizations/register-user
/// </summary>
public class ChatikaApiService : IChatikaApiService
{
private readonly HttpClient _httpClient;
private readonly ILogger<ChatikaApiService> _logger;
private readonly string _baseUrl;
private readonly string _apiKey;
public ChatikaApiService(
HttpClient httpClient,
ILogger<ChatikaApiService> logger,
IConfiguration configuration)
{
_httpClient = httpClient;
_logger = logger;
// تنظیمات از appsettings.json
_baseUrl = configuration["Chatika:BaseUrl"] ?? "https://api.chatika.ir";
_apiKey = configuration["Chatika:ApiKey"] ?? "";
// تنظیم HttpClient
_httpClient.BaseAddress = new Uri(_baseUrl);
if (!string.IsNullOrEmpty(_apiKey))
{
_httpClient.DefaultRequestHeaders.Add("X-API-Key", _apiKey);
}
}
/// <inheritdoc />
public async Task<ChatikaAccountResult> CreateAccountAsync(
string mobileNumber,
string fullName,
CancellationToken cancellationToken = default)
{
try
{
_logger.LogInformation(
"🤖 Creating Chatika account for mobile: {Mobile}",
mobileNumber.Substring(0, 4) + "***");
var request = new ChatikaRegisterRequest
{
MobileNumber = mobileNumber
};
var response = await _httpClient.PostAsJsonAsync(
"/api/v1/organizations/register-user",
request,
cancellationToken);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<ChatikaRegisterResponse>(
cancellationToken: cancellationToken);
_logger.LogInformation(
"✅ Chatika account created successfully. UserId: {UserId}, IsNewUser: {IsNew}, Credit: {Credit}",
result?.Id,
result?.IsNewUser,
result?.CreditCharged);
return ChatikaAccountResult.Success(
chatikaUserId: result?.Id.ToString(),
accessUrl: "https://chatika.ir"
);
}
var errorContent = await response.Content.ReadAsStringAsync(cancellationToken);
var errorResponse = JsonSerializer.Deserialize<ChatikaErrorResponse>(errorContent);
_logger.LogWarning(
"⚠️ Chatika API returned error. Status: {Status}, Code: {ErrorCode}, Message: {Message}",
response.StatusCode,
errorResponse?.ErrorCode,
errorResponse?.Message);
return ChatikaAccountResult.Failure($"{errorResponse?.ErrorCode}: {errorResponse?.Message}");
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "❌ Network error calling Chatika API");
return ChatikaAccountResult.Failure($"خطای شبکه: {ex.Message}");
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
_logger.LogError(ex, "❌ Timeout calling Chatika API");
return ChatikaAccountResult.Failure("تایم‌اوت در ارتباط با سرویس چتیکا");
}
catch (Exception ex)
{
_logger.LogError(ex, "❌ Unexpected error calling Chatika API");
return ChatikaAccountResult.Failure($"خطای غیرمنتظره: {ex.Message}");
}
}
/// <summary>
/// Request model برای ثبت کاربر در چتیکا
/// </summary>
private class ChatikaRegisterRequest
{
[JsonPropertyName("mobile_number")]
public string MobileNumber { get; set; } = string.Empty;
}
/// <summary>
/// Response model موفق از چتیکا
/// </summary>
private class ChatikaRegisterResponse
{
[JsonPropertyName("id")]
public long Id { get; set; }
[JsonPropertyName("mobile_number")]
public string MobileNumber { get; set; } = string.Empty;
[JsonPropertyName("organization_id")]
public long OrganizationId { get; set; }
[JsonPropertyName("organization_title")]
public string OrganizationTitle { get; set; } = string.Empty;
[JsonPropertyName("wallet_balance")]
public decimal WalletBalance { get; set; }
[JsonPropertyName("is_new_user")]
public bool IsNewUser { get; set; }
[JsonPropertyName("credit_charged")]
public decimal CreditCharged { get; set; }
}
/// <summary>
/// Response model خطا از چتیکا
/// </summary>
private class ChatikaErrorResponse
{
[JsonPropertyName("error_code")]
public string ErrorCode { get; set; } = string.Empty;
[JsonPropertyName("message")]
public string Message { get; set; } = string.Empty;
}
}