مزودو الرسائل القصيرة
يدعم FORGE إرسال رسائل SMS والتحقق من OTP عبر drivers مزودين متعددة. يُستخدم نظام SMS للتحقق من رقم الهاتف والمصادقة الثنائية والإشعارات التعاملية.
سمة SmsProvider
جميع drivers SMS تُنفّذ سمة SmsProvider:
#[async_trait]
pub trait SmsProvider: Send + Sync {
/// Send a plain text SMS message
async fn send(&self, to: &str, message: &str) -> Result<(), SmsError>;
/// Send a one-time password via the provider's verification service
async fn send_otp(&self, to: &str, code: &str) -> Result<(), SmsError>;
/// Verify an OTP code entered by the user
async fn verify_otp(&self, to: &str, code: &str) -> Result<bool, SmsError>;
}تكامل Slack (التطوير/الاختبار)
عندما يكون SMS_SLACK_ENABLED=true، يتم اعتراض جميع رسائل SMS وإرسالها إلى قناة Slack بدلاً من المزود الفعلي. هذا مفيد لـ:
- التطوير: رؤية أكواد OTP بدون الحاجة لهاتف حقيقي
- الاختبار: التحقق من محتوى SMS في مساحة عمل Slack
- المراقبة: تتبع كل حركة SMS في قناة مخصصة
SMS_SLACK_ENABLED=true
┌─────────┐ ┌───────────────┐ ┌─────────────┐
│ التطبيق │───▶│ SlackSmsProxy │───▶│ قناة │
│ يرسل │ │ (يعترض) │ │ Slack │
│ SMS │ └───────────────┘ └─────────────┘
└─────────┘
SMS_SLACK_ENABLED=false (افتراضي)
┌─────────┐ ┌─────────────────┐ ┌───────────────┐
│ التطبيق │───▶│ Twilio/Unifonic │───▶│ SMS حقيقية │
│ يرسل │ │ المزود │ │ للهاتف │
│ SMS │ └─────────────────┘ └───────────────┘
└─────────┘الإعدادات:
| المتغير | النوع | الافتراضي | مطلوب | الوصف |
|---|---|---|---|---|
SMS_SLACK_ENABLED | boolean | false | لا | إرسال SMS إلى Slack بدلاً من المزود |
SMS_SLACK_WEBHOOK_URL | string | - | نعم* | رابط Webhook الوارد لـ Slack |
SMS_SLACK_CHANNEL | string | - | لا | تجاوز القناة اختيارياً |
*مطلوب عندما يكون SMS_SLACK_ENABLED=true. سيفشل التطبيق عند البدء إذا كان مفقوداً.
الإعداد:
- أنشئ Incoming Webhook في مساحة عمل Slack
- عيّن متغيرات البيئة:
SMS_SLACK_ENABLED=true
SMS_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX
SMS_SLACK_CHANNEL=#sms-logs # اختياري- ستظهر رسائل SMS الآن في Slack:
*SMS Message*
:iphone: To: `+1234567890`
:envelope: Message:
رمز التحقق الخاص بك هو: 123456
:id: ID: `uuid-here`تحذير
وكيل Slack لا يمكنه التحقق من OTPs - يجب إجراء التحقق عبر قاعدة البيانات الخاصة بك. هذا نفس سلوك driver الـ log.
الـ Drivers المتاحة
Slack (للتطوير)
إرسال رسائل SMS/OTP إلى قناة Slack بدلاً من الهواتف الحقيقية. مثالي للتطوير والاختبار بدون تكاليف SMS.
التثبيت:
forge new --interactive
# اختر "Slack (development)" عند السؤال عن مزود SMSأو عبر CLI:
forge new myapp --sms slackالإعدادات:
| المتغير | النوع | مطلوب | الوصف |
|---|---|---|---|
SMS_DRIVER | string | نعم | اضبطه على slack |
SMS_SLACK_WEBHOOK_URL | string | نعم | رابط Webhook الوارد لـ Slack |
SMS_SLACK_CHANNEL | string | لا | تجاوز القناة اختيارياً |
الإعداد:
- أنشئ Incoming Webhook في مساحة عمل Slack
- اضبط ملف
.env:
SMS_DRIVER=slack
SMS_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX
SMS_SLACK_CHANNEL=#otp-codes # اختياري- ستظهر أكواد OTP في Slack:
*OTP Verification*
📱 *To:* `+1234567890`
🔑 *Code:* `123456`
🆔 *ID:* `uuid-here`نصيحة
استخدم Slack للتطوير لتجنب تكاليف SMS ورؤية أكواد OTP فوراً في قناة فريقك.
تحذير
مزود Slack لا يمكنه التحقق من OTPs من جانب الخادم - يتم التحقق عبر قاعدة البيانات (مثل driver الـ Log).
Twilio
مزود SMS و OTP كامل الميزات باستخدام REST API و Verify service الخاصين بـ Twilio.
التثبيت:
forge provider:add sms:twilioالإعدادات:
| الإعداد | النوع | الوصف |
|---|---|---|
twilio_account_sid | string | Twilio Account SID |
twilio_auth_token | encrypted | Twilio Auth Token |
twilio_from_number | string | رقم هاتف المُرسل (بتنسيق E.164) |
twilio_verify_sid | string | Twilio Verify Service SID |
نصيحة
twilio_verify_sid مطلوب لوظيفة OTP. أنشئ Verify Service في وحدة تحكم Twilio للحصول على هذه القيمة.
كيف يعمل OTP مع Twilio:
1. send_otp() → يستدعي Twilio Verify API لإرسال الرمز
2. المستخدم يُدخل الرمز في تطبيقك
3. verify_otp() → يستدعي Twilio Verify API للتحقق من الرمز
4. يُرجع true/falseUnifonic
مزود SMS شائع في منطقة الشرق الأوسط وشمال أفريقيا.
التثبيت:
forge provider:add sms:unifonicالإعدادات:
| الإعداد | النوع | الوصف |
|---|---|---|
unifonic_app_sid | encrypted | Unifonic Application SID |
unifonic_sender_id | string | معرّف المُرسل (أبجدي رقمي أو رقم) |
نصيحة
معرّفات المُرسل في Unifonic قد تتطلب تسجيلاً لدى هيئات الاتصالات المحلية حسب بلد الوجهة.
Vonage
مزود SMS عالمي (كان يُعرف سابقاً بـ Nexmo).
التثبيت:
forge provider:add sms:vonageالإعدادات:
| الإعداد | النوع | الوصف |
|---|---|---|
vonage_api_key | string | Vonage API Key |
vonage_api_secret | encrypted | Vonage API Secret |
vonage_from | string | معرّف المُرسل أو الرقم |
الاستخدام
إنشاء المزود
يُنشئ المصنع الـ driver الصحيح بناءً على إعداداتك:
use crate::services::sms::SmsFactory;
let sms = SmsFactory::create(&settings).await?;إرسال رسالة
// إرسال SMS نصية عادية
sms.send("+1234567890", "تم شحن طلبك!").await?;التحقق من OTP
// Step 1: Send OTP to user's phone
sms.send_otp("+1234567890", "123456").await?;
// Step 2: User enters the code in your app
// Step 3: Verify the code
let is_valid = sms.verify_otp("+1234567890", "123456").await?;
if is_valid {
// Phone number verified
} else {
// Invalid code
}تحذير
يجب أن تكون أرقام الهاتف بتنسيق E.164 (مثل +1234567890). الإرسال لأرقام بدون بادئة رمز البلد سيفشل مع معظم المزودين.
الإعدادات عبر الإدارة
جميع إعدادات SMS تُدار من خلال صفحة الإعدادات في الإدارة تحت مجموعة SMS. تُخزّن بيانات الاعتماد كإعدادات مُشفّرة وتُخفى في واجهة الإدارة.
الإعدادات > SMS
┌──────────────────────────────────────────────────┐
│ المزود: [Twilio ▼] │
│ Account SID: [ACxxxxxxxxxx ] │
│ Auth Token: [•••••••••••••••• ] │
│ رقم المُرسل: [+15551234567 ] │
│ Verify SID: [VAxxxxxxxxxx ] │
└──────────────────────────────────────────────────┘معالجة الأخطاء
جميع عمليات SMS تُرجع Result<(), SmsError> مع أنواع أخطاء منظمة:
match sms.send("+1234567890", "مرحباً").await {
Ok(()) => println!("تم إرسال الرسالة"),
Err(SmsError::InvalidNumber) => println!("تنسيق رقم هاتف خاطئ"),
Err(SmsError::ProviderError(msg)) => println!("خطأ المزود: {}", msg),
Err(SmsError::RateLimited) => println!("طلبات كثيرة جداً"),
Err(e) => println!("خطأ غير متوقع: {}", e),
}