SDK رسمی .NET
پروژه SMSDaily.Client کلاینت رسمی سبک برای Public API است و روی .NET 8 ساخته شده است. این Client به کتابخانه خارجی وابسته نیست و از HttpClient، System.Net.Http.Json و System.Text.Json استفاده میکند.
نسخه فعلی SDK داخل Repository منتشر شده است و هنوز ادعا نمیکنیم Package عمومی NuGet منتشر شده باشد. تا زمان انتشار Package رسمی، پروژه را با
ProjectReferenceیا سورس کنترلشده خود استفاده کنید.
افزودن ProjectReference
اگر Repository یا پروژه SDK در کنار Solution شما قرار دارد:
<ItemGroup>
<ProjectReference Include="..\SMSDaily.Client\SmsDaily.Client.csproj" />
</ItemGroup>
یا از CLI:
dotnet add reference ../SMSDaily.Client/SmsDaily.Client.csproj
ساخت Client
بهتر است HttpClient را از IHttpClientFactory دریافت کنید و API Key را جداگانه از Secret Store بخوانید:
using SmsDaily.Client;
builder.Services.AddHttpClient("SMSDaily", http =>
{
http.BaseAddress = new Uri("https://service.smsdaily.ir");
});
builder.Services.AddScoped<SmsDailyClient>(services =>
{
var factory = services.GetRequiredService<IHttpClientFactory>();
var configuration = services.GetRequiredService<IConfiguration>();
return new SmsDailyClient(
factory.CreateClient("SMSDaily"),
configuration["SMSDaily:ApiKey"]!);
});
API Key را در appsettings.json عمومی یا Repository قرار ندهید. از Secret Store، Environment Variable، Azure Key Vault یا ابزار مشابه استفاده کنید.
نمونه Environment Variable:
SMSDaily__ApiKey=YOUR_API_KEY
ارسال پیامک
var result = await smsDaily.SendMessageAsync(
new SendMessageRequest(
Sender: "300099000121",
Recipient: "09121234567",
Message: "سفارش شما آماده تحویل است.",
ClientReference: "order-781"),
idempotencyKey: "order-781-ready");
Console.WriteLine(result.TrackingCode);
idempotencyKey عمداً ورودی صریح متد است تا Retry همان عملیات با همان کلید انجام شود و SDK بهصورت پنهان کلید جدید تولید نکند.
رهگیری پیام
var message = await smsDaily.GetMessageAsync(result.TrackingCode);
if (message.Status == "delivered")
{
// تحویل ثبت شده است.
}
ارسال Pattern
var result = await smsDaily.SendPatternAsync(
new PatternMessageRequest(
PatternCode: "order-ready",
Recipient: "09121234567",
Variables: new Dictionary<string, string>
{
["name"] = "علیرضا",
["orderNo"] = "781"
},
ClientReference: "order-781"),
idempotencyKey: "order-781-pattern");
OTP با تایید سمت SMSDaily
var challenge = await smsDaily.StartServerOtpAsync(
new OtpStartRequest(
Mobile: "09121234567",
PatternCode: "login-otp",
ClientReference: "login-992"),
idempotencyKey: "login-992-start");
var verification = await smsDaily.VerifyOtpAsync(
challenge.TrackingCode,
codeEnteredByUser);
if (verification.Valid)
{
// ورود یا عملیات حساس را تایید کنید.
}
دریافت پیامهای ورودی
var page = await smsDaily.ListInboundMessagesAsync(page: 1, pageSize: 50);
foreach (var incoming in page.Items)
{
Console.WriteLine($"{incoming.Sender}: {incoming.Message}");
}
برای سامانههای رویدادمحور، Webhook گزینه بهتری از Polling مداوم است.
ایجاد Webhook
var webhook = await smsDaily.CreateWebhookAsync(
new CreateWebhookRequest(
"https://example.com/integrations/smsdaily/webhook",
new[] { "message.status", "inbound.received" }));
// فقط همین بار در Secret Store ذخیره کنید.
var signingSecret = webhook.SigningSecret;
مدیریت بعدی:
var all = await smsDaily.ListWebhooksAsync();
await smsDaily.UpdateWebhookAsync(
webhook.Id,
new UpdateWebhookRequest(IsActive: false));
await smsDaily.TestWebhookAsync(webhook.Id);
await smsDaily.DeleteWebhookAsync(webhook.Id);
بررسی امضای Callback
SDK Helper مستقل برای HMAC دارد:
var isValid = WebhookSignature.Verify(
signingSecret,
timestampHeader,
signatureHeader,
rawRequestBody,
tolerance: TimeSpan.FromMinutes(5));
این Helper:
- Timestamp یونیکس را بررسی میکند.
- بازه زمانی قابل قبول را کنترل میکند.
- HMAC-SHA256 را روی
timestamp.rawBodyمحاسبه میکند. - مقایسه امضا را با
CryptographicOperations.FixedTimeEqualsانجام میدهد.
مدیریت خطا
برای پاسخهای غیرموفق، SDK خطای SmsDailyApiException ایجاد میکند:
try
{
await smsDaily.GetMessageAsync("SMS-...");
}
catch (SmsDailyApiException ex)
{
logger.LogWarning(
"SMSDaily error {Status} {Code}; correlation={CorrelationId}",
(int)ex.StatusCode,
ex.ErrorCode,
ex.CorrelationId);
}
خصوصیات مهم Exception:
| خصوصیت | کاربرد |
|---|---|
StatusCode |
HTTP Status Code |
ErrorCode |
کد عمومی خطا مانند validation_error |
CorrelationId |
شناسه پیگیری برای Log و پشتیبانی |
Errors |
خطاهای اعتبارسنجی فیلدها |
ResponseBody |
پاسخ خام برای عیبیابی کنترلشده |
از ثبت API Key، OTP و Signing Secret در Log خودداری کنید.