"""ترجمهٔ کدهای بازگشتی سامانهٔ 0098SMS به متن فارسی و رده‌بندی وضعیت. دو جدول مستقل در راهنمای vendor آمده است: * **کدهای ارسال/خطا** (لینک ارتباطی و وب‌سرویس): عدد کوتاه یا رشته‌ای مانند ``Hang``/``Wrong time``. صفر (یا شناسهٔ ۹رقمی در ``SendSMSWithID``) یعنی موفق. * **کدهای وضعیت دلیوری** (خروجی ``smsdeliveryState``): ۵=رسیده به گوشی، ۶=نرسیده، ۷=منقضی، ۸=نامشخص. این ماژول تنها منبع حقیقت این کدهاست تا provider و پنل هر دو از یک ترجمه استفاده کنند. """ from dataclasses import dataclass # --------------------------------------------------------------------------- # کدهای خطای ارسال (ترکیب جدول لینک ارتباطی و وب‌سرویس راهنما). # --------------------------------------------------------------------------- SEND_ERROR_CODES = { "1": "شماره گیرنده اشتباه است.", "2": "گیرنده تعریف نشده است.", "3": "فرستنده تعریف نشده است.", "4": "مخاطب دریافت پیام‌های تبلیغاتی خود را بسته است (بلک‌لیست).", "5": "متن تنظیم نشده است.", "6": "نام کاربری تنظیم نشده است.", "7": "کلمه عبور تنظیم نشده است.", "8": "نام دامین تنظیم نشده است.", "9": "مجوز شما باطل شده است.", "10": "اعتبار پیامک شما کافی نیست.", "11": "برای این شماره لینک تعریف نشده است.", "12": "عدم مجوز برای اتصال لینک.", "13": "نام کاربری و کلمه عبور اشتباه است.", "14": "کاراکتر غیرمجاز در متن وجود دارد.", "15": "سقف ارسال روزانه پر شده است.", "16": "عدم مجوز شماره برای ارسال از لینک.", "17": "خطا در شماره پنل؛ لطفاً با پشتیبانی تماس بگیرید.", "18": "اتمام تاریخ اعتبار شماره پنل؛ برای استفاده تمدید شود.", "19": "تنظیمات کد opt انجام نشده است.", "20": "فرمت کد opt صحیح نیست.", "21": "تنظیمات کد opt توسط ادمین تأیید نشده است.", "22": "اطلاعات مالک شماره ثبت و تأیید نشده است.", "23": "هنوز اجازهٔ ارسال به این شماره پنل داده نشده است.", "24": "ارسال از IP غیرمجاز انجام شده است.", "66": "شارژ پنل شما برای ارسال کافی نیست؛ لطفاً شارژ نمایید.", "1111": "شماره موبایل صحیح نیست.", "-22": "خطای شارژ؛ لطفاً با پشتیبانی تماس بگیرید.", "-23": "حساب کاربری شما مسدود است؛ لطفاً با پشتیبانی تماس بگیرید.", "-24": "مرحلهٔ دوم ثبت‌نام شما انجام نگرفته است؛ ثبت‌نام را کامل نمایید.", "-25": "عدم مجوز شماره برای ارسال از لینک.", "-26": "خطا در شماره پنل؛ لطفاً با پشتیبانی تماس بگیرید.", "-27": "اتمام تاریخ اعتبار شماره پنل؛ برای استفاده تمدید شود.", "-28": "تنظیمات کد opt انجام نشده است.", "-29": "فرمت کد opt صحیح نیست.", "-31": "شناسهٔ پیامک (smsid) یافت نشد.", "-32": "شناسهٔ پیامک (smsid) مطابقت ندارد.", "hang": "عدم تطابق نام کاربری و کلمه عبور؛ لطفاً با پشتیبانی تماس بگیرید.", "no doc": "کاراکتر غیرمجاز در متن وجود دارد.", "wrong timestamp": "تایم‌استمپ ارسال‌شده صحیح نیست.", "wrong time": "زمان در بازهٔ صحیح نیست (از همان روز تا یک سال بعد مجاز است).", } def describe_send_code(code): """متن فارسی کد خطای ارسال؛ اگر کد ناشناخته باشد ``None``.""" return SEND_ERROR_CODES.get(str(code).strip().casefold()) # --------------------------------------------------------------------------- # کدهای وضعیت دلیوری (``smsdeliveryState``). # --------------------------------------------------------------------------- @dataclass(frozen=True, slots=True) class DeliveryCode: status: str # مطابق SMSQueue.DeliveryStatus description: str is_final: bool # True = دیگر نیازی به استعلام مجدد نیست _DELIVERY_CODES = { "5": DeliveryCode("delivered", "رسیده به گوشی.", True), "6": DeliveryCode("not_delivered", "نرسیده به گوشی.", True), "7": DeliveryCode("expired", "وضعیت دریافت پیامک منقضی شده است.", True), "8": DeliveryCode("unknown", "وضعیت پیامک نامشخص است.", False), } def classify_delivery(raw_code): """کد دلیوری خام را به :class:`DeliveryCode` تبدیل می‌کند. عدد ۲ یا هر مقدار منفی/غیرشناخته‌شده ⇒ «نامشخص» و غیرنهایی، تا استعلام بعدی دوباره تلاش کند (وضعیت ممکن است هنوز از سمت اپراتور برنگشته باشد). """ code = str(raw_code).strip() return _DELIVERY_CODES.get(code, DeliveryCode("unknown", f"کد وضعیت ناشناخته: {code}", False))