Niazpardaz SMS SDK for Rust
Official Rust SDK for Niazpardaz SMS API | کتابخانه رسمی Rust برای API پیامکی نیازپرداز

Features | امکانات
- Async & Blocking — هم async با tokio و هم blocking (سنکرون)
- Rust 1.75+ — حداقل نسخه پشتیبانی
- Builder Pattern — ساخت کلاینت با تنظیمات سفارشی
- Type-safe — تمام کدهای نتیجه با newtype pattern و description فارسی
- Error handling — خطاهای strongly typed با
thiserror
- TLS — پشتیبانی از
rustls (بدون نیاز به OpenSSL)
- Thread-safe —
Send + Sync برای استفاده در چند thread
نصب | Installation
[dependencies]
niazpardaz-sms = "1.0"
tokio = { version = "1", features = ["full"] }
برای نسخه blocking (بدون async):
[dependencies]
niazpardaz-sms = { version = "1.0", features = ["blocking"] }
شروع سریع | Quick Start
Async (پیشفرض)
use niazpardaz_sms::NiazpardazClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = NiazpardazClient::new("YOUR_API_KEY");
let result = client.send("10001234", "09123456789", "سلام از نیازپرداز!").await?;
if result.is_successful() {
println!("BatchSmsId: {}", result.batch_sms_id);
} else {
println!("Error: {}", result.result_code.description());
}
Ok(())
}
Blocking (سنکرون)
use niazpardaz_sms::BlockingClient;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = BlockingClient::new("YOUR_API_KEY");
let result = client.send("10001234", "09123456789", "سلام!")?;
println!("BatchSmsId: {}", result.batch_sms_id);
Ok(())
}
تنظیمات | Configuration
use niazpardaz_sms::NiazpardazClient;
use std::time::Duration;
let client = NiazpardazClient::builder("YOUR_API_KEY")
.timeout(Duration::from_secs(60))
.base_url("https://custom.api.com")
.build();
let http_client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.proxy(reqwest::Proxy::all("http://proxy:8080")?)
.build()?;
let client = NiazpardazClient::builder("YOUR_API_KEY")
.http_client(http_client)
.build();
استفاده در فریمورکها | Framework Integration
Actix Web
use actix_web::{web, App, HttpServer, HttpResponse};
use niazpardaz_sms::NiazpardazClient;
use std::sync::Arc;
struct AppState {
sms_client: NiazpardazClient,
}
async fn send_sms(
data: web::Data<Arc<AppState>>,
form: web::Form<SmsForm>,
) -> HttpResponse {
match data.sms_client.send("10001234", &form.to, &form.message).await {
Ok(result) => HttpResponse::Ok().json(result),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
}
}
#[derive(serde::Deserialize)]
struct SmsForm { to: String, message: String }
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let state = Arc::new(AppState {
sms_client: NiazpardazClient::new("YOUR_API_KEY"),
});
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(state.clone()))
.route("/send", web::post().to(send_sms))
})
.bind("0.0.0.0:8080")?
.run()
.await
}
Axum
use axum::{routing::post, Router, Json, Extension};
use niazpardaz_sms::NiazpardazClient;
use std::sync::Arc;
#[derive(serde::Deserialize)]
struct SmsRequest { to: String, message: String }
async fn send_sms(
Extension(client): Extension<Arc<NiazpardazClient>>,
Json(req): Json<SmsRequest>,
) -> Json<serde_json::Value> {
match client.send("10001234", &req.to, &req.message).await {
Ok(result) => Json(serde_json::json!({
"batch_sms_id": result.batch_sms_id,
"success": result.is_successful()
})),
Err(e) => Json(serde_json::json!({ "error": e.to_string() })),
}
}
#[tokio::main]
async fn main() {
let client = Arc::new(NiazpardazClient::new("YOUR_API_KEY"));
let app = Router::new()
.route("/send", post(send_sms))
.layer(Extension(client));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Rocket
#[macro_use] extern crate rocket;
use niazpardaz_sms::NiazpardazClient;
use rocket::State;
use rocket::serde::json::Json;
#[derive(serde::Deserialize)]
struct SmsForm<'r> { to: &'r str, message: &'r str }
#[post("/send", data = "<form>")]
async fn send(
client: &State<NiazpardazClient>,
form: Json<SmsForm<'_>>,
) -> String {
match client.send("10001234", form.to, form.message).await {
Ok(r) => format!("BatchSmsId: {}", r.batch_sms_id),
Err(e) => format!("Error: {}", e),
}
}
#[launch]
fn rocket() -> _ {
rocket::build()
.manage(NiazpardazClient::new("YOUR_API_KEY"))
.mount("/", routes![send])
}
Warp
use warp::Filter;
use niazpardaz_sms::NiazpardazClient;
use std::sync::Arc;
#[tokio::main]
async fn main() {
let client = Arc::new(NiazpardazClient::new("YOUR_API_KEY"));
let send = warp::path("send")
.and(warp::post())
.and(warp::body::json())
.and(warp::any().map(move || client.clone()))
.and_then(|body: serde_json::Value, client: Arc<NiazpardazClient>| async move {
let to = body["to"].as_str().unwrap_or("");
let msg = body["message"].as_str().unwrap_or("");
match client.send("10001234", to, msg).await {
Ok(r) => Ok::<_, warp::Rejection>(warp::reply::json(&r)),
Err(_) => Ok(warp::reply::json(&serde_json::json!({"error": "failed"}))),
}
});
warp::serve(send).run(([0, 0, 0, 0], 8080)).await;
}
Tide
use tide::Request;
use niazpardaz_sms::NiazpardazClient;
#[derive(Clone)]
struct State { sms: NiazpardazClient }
#[derive(serde::Deserialize)]
struct SmsBody { to: String, message: String }
#[async_std::main]
async fn main() -> tide::Result<()> {
let state = State { sms: NiazpardazClient::new("YOUR_API_KEY") };
let mut app = tide::with_state(state);
app.at("/send").post(|mut req: Request<State>| async move {
let body: SmsBody = req.body_json().await?;
let result = req.state().sms.send("10001234", &body.to, &body.message).await?;
Ok(tide::Response::builder(200).body(tide::Body::from_json(&result)?).build())
});
app.listen("0.0.0.0:8080").await?;
Ok(())
}
CLI Application
use niazpardaz_sms::NiazpardazClient;
#[tokio::main]
async fn main() {
let api_key = std::env::var("NIAZPARDAZ_API_KEY")
.expect("NIAZPARDAZ_API_KEY not set");
let client = NiazpardazClient::new(api_key);
let args: Vec<String> = std::env::args().collect();
if args.len() < 4 {
eprintln!("Usage: sms-cli <from> <to> <message>");
std::process::exit(1);
}
match client.send(&args[1], &args[2], &args[3]).await {
Ok(result) => {
if result.is_successful() {
println!("Sent! ID: {}", result.batch_sms_id);
} else {
eprintln!("Failed: {}", result.result_code);
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
تمام متدها | API Reference
| متد |
توضیحات |
send(from, to, message) |
ارسال پیامک تکی |
send_bulk(from, to_list, message) |
ارسال گروهی |
send_bulk_full(from, to_list, message, flash, delay) |
ارسال گروهی با تنظیمات کامل |
send_sms_like_to_like(from, to_list, message_list) |
ارسال نظیر به نظیر |
send_voice_otp(from, to, otp) |
ارسال OTP صوتی |
get_batch_delivery(batch_sms_id, page, size) |
گزارش تحویل گروهی |
get_delivery_like_to_like(sms_id) |
گزارش تحویل نظیر به نظیر |
get_credit() |
اعتبار باقیمانده |
get_sender_numbers() |
شمارههای فرستنده |
get_inbox_count(is_read) |
تعداد پیامهای دریافتی |
get_messages(type, from, page, size) |
لیست پیامکها |
get_messages_by_date_range(type, from, from_date, to_date) |
پیامکها بر اساس بازه |
extract_telecom_blacklist_numbers(numbers) |
استخراج شمارههای لیست سیاه |
number_is_in_telecom_blacklist(number) |
بررسی لیست سیاه |
check_sms_content(message) |
بررسی محتوای پیامک |
تمام متدها هم در NiazpardazClient (async) و هم در BlockingClient (sync) موجودند.
مدیریت خطا | Error Handling
use niazpardaz_sms::{NiazpardazClient, NiazpardazError};
async fn example(client: &NiazpardazClient) {
match client.send("10001234", "09123456789", "تست").await {
Ok(result) => println!("Success: {}", result.batch_sms_id),
Err(NiazpardazError::Api { code, message }) => {
eprintln!("API Error (code {}): {}", code, message);
}
Err(NiazpardazError::Network(e)) => {
eprintln!("Network Error: {}", e);
}
Err(NiazpardazError::Json(e)) => {
eprintln!("JSON Error: {}", e);
}
Err(e) => {
eprintln!("Error: {}", e);
}
}
}
نیازمندیها | Requirements
- Rust 1.75 یا بالاتر
- وابستگیها:
reqwest, serde, serde_json, thiserror
انتشار در crates.io
cargo login YOUR_CRATES_IO_TOKEN
cargo publish
مجوز | License
MIT License — LICENSE
پشتیبانی | Support