نودجی‌اس (Node.js) به دلیل معماری رویدادمحور و غیرهمگام (Non-blocking I/O) یکی از محبوب‌ترین بسترهای ساخت بک‌اند برنامه‌های مدرن و اپلیکیشن‌های بلادرنگ است. در این آموزش، ساخت یک کلاینت تمیز، بهینه و ضد خطا با Axios و TypeScript برای ارسال پیامک‌های متنی و کدهای احراز هویت (OTP) را پیاده‌سازی می‌کنیم.

نصب پیش‌نیازها

در پوشه پروژه خود کتابخانه‌های axios و dotenv را نصب کنید:

npm install axios dotenv

پیاده‌سازی کلاس کلاینت پیامک (FreeSmsClient.ts)

بهترین الگو، ساخت یک سرویس ماژولار است که کلید API و تنظیمات پایه را در هدر نگه داشته و متدهای مورد نیاز را در قالب توابع خوانا اکسپورت کند:

import axios, { AxiosInstance } from 'axios'; export class FreeSmsClient { private http: AxiosInstance; constructor(apiKey: string) { this.http = axios.create({ baseURL: 'https://api.free-sms.ir/v1', timeout: 5000, headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); } // ارسال کد تایید یکبار مصرف (تحویل زیر ۲ ثانیه با خط خدماتی) async sendOtp(to: string, patternCode: string, params: Record<string, string | number>) { const res = await this.http.post('/otp', { to, pattern_code: patternCode, params }); return res.data; } // ارسال پیامک متنی تکی یا گروهی async sendSms(line: string, to: string[], text: string) { const res = await this.http.post('/send', { line, to, text }); return res.data; } // دریافت مانده اعتبار ریالی پنل async getCredit() { const res = await this.http.get('/credit'); return res.data; } }

نحوه استفاده در کنترلر Express.js

در فایل authController.js می‌توانید هنگام ثبت نام کاربر یا درخواست ورود با شماره موبایل، کد احراز هویت را در کمتر از ۳ ثانیه ارسال کنید:

import express from 'express'; import { FreeSmsClient } from './FreeSmsClient'; const router = express.Router(); const sms = new FreeSmsClient(process.env.FREE_SMS_API_KEY!); router.post('/request-otp', async (req, res) => { const { mobile } = req.body; const otpCode = Math.floor(10000 + Math.random() * 90000); try { const result = await sms.sendOtp(mobile, 'login_verify_v1', { code: otpCode }); // ذخیره در Redis با انقضای ۱۲۰ ثانیه res.json({ success: true, message: 'کد ارسال گردید', data: result }); } catch (err: any) { res.status(500).json({ success: false, error: err.response?.data || err.message }); } });

دریافت گزارش وضعیت تحویل پیامک با Webhook

به جای پولینگ و درخواست‌های مکرر GET برای بررسی وضعیت پیامک، وب‌هوک تحویل را روی سرور Express تنظیم کنید:

router.post('/webhooks/sms-delivery', (req, res) => { const { message_id, status, recipient, delivered_at } = req.body; console.log(`SMS ${message_id} to ${recipient} status: ${status}`); // به‌روزرسانی رکورد در دیتابیس res.status(200).send('OK'); });
بهترین روش مدیریت خطاها (Retry Pattern): در ارتباطات شبکه ممکن است قطعی‌های لحظه‌ای رخ دهد. با کتابخانه axios-retry در صورت بروز خطای 503 یا تایم‌اوت، درخواست را با فاصله تصادفی تا ۲ بار تکرار کنید.

سوالات متداول

آیا امکان استفاده در فریمورک NestJS وجود دارد؟+

بله، می‌توانید کلاس FreeSmsClient را به عنوان یک Provider تزریق‌شونده در ماژول AuthModule یا NotificationModule خود تعریف و Inject نمایید.

تایم‌اوت بهینه برای ارسال OTP با Axios چقدر است؟+

به دلیل پاسخ‌دهی بلادرنگ وب‌سرویس پترن فری اس ام اس، تایم‌اوت ۵۰۰۰ میلی‌ثانیه (۵ ثانیه) انتخابی استاندارد و ایده‌آل است.

آیا کلاینت Node.js از TypeScript به صورت کامل پشتیبانی می‌کند؟+

بله، کدهای ارائه شده دارای Type Definition کامل برای پارامترهای درخواست و ساختار پاسخ بازگشتی هستند و به راحتی در پروژه‌های NestJS و Next.js قابل استفاده‌اند.

چگونه وضعیت تحویل پیامک‌ها (Delivery Report) را در Express دریافت کنیم؟+

یک روت POST به عنوان Webhook در سرور خود تعریف کرده و آدرس آن را در پنل فری اس ام اس ثبت کنید. به محض تغییر وضعیت پیامک، وب‌هوک فراخوانی شده و دیتای تحویل در بادی درخواست قرار می‌گیرد.