افتح صندوق بريد

الأتمتة وAPI

واجهة برمجة بريد مؤقت: أتمتة صندوق البريد بسكربت

ثلاث نقاط طرفية، بلا مفتاح وبلا حساب: يكفي ذلك سكربتًا ليفتح عنوانًا، ويقرأ ما يصل إليه، ويرتّب خلفه. إليك الحلقة كاملة — الحصتان اللتان تُحدِّدان السرعة المسموحة، والموعد النهائي الوحيد الذي لا يمكنك تحريكه.

  • متوسط
  • 22 دقيقةً للقراءة
سير ناقل رمادي يُحرّكه ترس أزرق، يحمل مغلفين أزرقين نحو صينية رمادية مفتوحة

ثلاثة استدعاءات، ولا شيء يُجهَّز

الواجهة كلها ثلاث نقاط طرفية تحت https://grabmail.io/api/v1، بالإضافة إلى عنوان واحد للمرفقات تسلّمه لك الاستدعاءات الأخرى جاهزًا. لا يوجد استدعاء لإنشاء صندوق بريد، وغيابه ليس إغفالاً: يبدأ وجود العنوان لحظة وصول بريد إليه، فلا شيء يبقى لمثل هذا الاستدعاء ليفعله.

الاستدعاءبمَ يُجيبما تُمرّره
GET /mailboxكل ما ينتظر عند عنوان، الأحدث أولاً.address، وlimit وbefore اختياريًا
GET /message/{id}رسالة واحدة كاملة: الجزء النصي، وجزء HTML، وكل مرفق برابط جاهز مسبقًا.mailbox
DELETE /message/{id}يزيلها الآن بدل انتظار انتهاء مدة الاحتفاظ.mailbox
GET /attachment/{id}بايتات ملف واحد، تمامًا كما وصلت.mailbox

كل استجابة هي JSON، بما في ذلك كل خطأ. وكل وقت بتوقيت UTC بصيغة RFC 3339. معرّفات الرسائل معتمة: أعدها كما تلقّيتها، ولا تحاول تفكيكها أبدًا.

الاستدعاء الأول، وبم يُجيب عنوان فارغ

اختر اسمًا، وضع أحد النطاقات العامة خلفه، ثم اقرأه. لا شيء يحتاج إلى الوجود مسبقًا، ولا شيء يُنشأ بمجرد السؤال.

shell
$ curl -sG https://grabmail.io/api/v1/mailbox \
  --data-urlencode "address=k7fq2m@grabmail.io"
الاستجابة
{
  "address": "k7fq2m@grabmail.io",
  "alias": "q4v8n2mt7xkd@example.net",
  "count": 1,
  "next": null,
  "messages": [
    {
      "id": "3QK7ZB5M9WVXR2HD4TNFJ0PC6A",
      "from": "no-reply@example.com",
      "from_name": "Example",
      "subject": "Your verification code",
      "preview": "Your code is 481920. It expires in 10 minutes.",
      "has_html": false,
      "date": "2026-08-29T09:14:02Z",
      "seen": false,
      "attachments": 0,
      "expires_at": "2026-09-03T09:14:02Z"
    }
  ]
}

خمسة حقول، اثنان منها أهم مما يبدوان:

count
عدد الرسائل في هذه الإجابة — لا عدد ما يحمله الصندوق كله. فبمجرد أن تمرّر limit، يصبح هذان رقمين مختلفين.
next
مؤشر الصفحة التي تلي هذه، أو null حين لا يوجد شيء بعدها. إنه معرّف آخر رسالة أُعطيتها للتو، ولهذا لا يكلّف التصفح استدعاءً إضافيًا لاكتشافه.
messages
القائمة نفسها، الأحدث أولاً. كل عنصر فيها يحمل مسبقًا subject وfrom وdate وseen، وpreview قصيرًا للنص، وما إذا كان هناك جزء HTML، وعدد المرفقات.
alias
عنوان ثانٍ يوصل الرسائل إلى هنا ولا يكشف شيئًا عن هذا العنوان. أعطه لنموذج بدل العنوان الحقيقي؛ فمن ينتهي به الأمر يكتبه في هذه الخدمة يجد صندوق بريد فارغًا.
address
العنوان كما فُهم، بأحرف صغيرة وبلا فراغات زائدة. قارنه بما أرسلته إن كنت تبني العنوان من أجزاء.

القراءة بعد الخمسين الأولى

يُجيب الاستدعاء الواحد بخمسين رسالة كحد افتراضي، ومئتين عند أقصى الحدود. وعنوان جامع نشط يتجاوز الاثنين في عصر واحد، والجزء الذي يخطئ القراء فهمه هو ما يأتي بعده — لأنه ليس رقم صفحة.

limit
عدد ما يُعاد في هذا الاستدعاء، من 1 إلى 200. القيم الخارجة عن النطاق تُضبط عند أقرب حد بدل أن تُرفض، فـlimit=5000 تمنحك 200 بصمت.
before
معرّف أقدم رسالة لديك بالفعل. تحصل على ما يليها. مرّر ما وضعته الإجابة السابقة في next.
next
null يعني أنك بلغت نهاية الصندوق. إنها الإشارة الموثوقة الوحيدة على نهاية القائمة: فالصفحة القصيرة ليست كذلك، لأن الصفحة لا تقصر إلا حين يقرر الخادم ذلك.
ما أعاده استدعاء واحدما يُعيده before=nextالأحدثالأقدمليس رقم صفحة — بل موضع في قائمة مرتّبة.
limit يحدّ سقف إجابة واحدة، وnext يسمّي حيث توقفت تلك الإجابة، وbefore يطلب ما يقع بعدها.
تصفّح صندوق بريد كاملاً، وانتهِ بأقدم صفحة
ADDR="k7fq2m@grabmail.io"
CURSOR=""

while :; do
  PAGE=$(curl -fsG https://grabmail.io/api/v1/mailbox \
           --data-urlencode "address=$ADDR" \
           --data-urlencode "limit=200" \
           ${CURSOR:+--data-urlencode "before=$CURSOR"})

  printf '%s' "$PAGE" | jq -c '.messages[]'

  CURSOR=$(printf '%s' "$PAGE" | jq -r '.next // empty')
  [ -n "$CURSOR" ] || break
  sleep 1
done

كرّر طالما أن next ليست null، وستحصل على الصندوق كاملاً، مهما كبر حجمه. كل استدعاء هو قراءة نطاق فوق فهرس لا إزاحة رقمية، فتكلفة الصفحة الألف هي تكلفة الصفحة الأولى نفسها.

مؤشر من صندوق بريد آخر، أو مؤشر انتهت صلاحيته منذ ذلك الحين، ليس خطأً: تحصل على صفحة فارغة وnext: null. وهذه هي الإجابة الصحيحة — فتكرار أحدث صفحة بدلاً من ذلك كان سيمنح السكربت بريدًا سبق أن عالجه — لكن معنى ذلك أن المؤشر المنتهي يبدو تمامًا كنهاية القائمة.

فتح رسالة واحدة، ومتى لا تحتاج إلى ذلك

المعرّف من القائمة مع صندوق البريد الذي وصلت إليه الرسالة يمنحانك الرسالة نفسها. كلاهما مطلوب: فمعرّف تسرّب من صندوق بريد لا يمكن استخدامه لقراءة صندوق آخر، لأن كل عملية بحث محصورة بالعنوان أيضًا.

shell
$ curl -sG https://grabmail.io/api/v1/message/3QK7ZB5M9WVXR2HD4TNFJ0PC6A \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"
الاستجابة
{
  "id": "3QK7ZB5M9WVXR2HD4TNFJ0PC6A",
  "from": "no-reply@example.com",
  "to": "k7fq2m@grabmail.io",
  "subject": "Your verification code",
  "date": "2026-08-29T09:14:02Z",
  "expires_at": "2026-09-03T09:14:02Z",
  "text": "Your code is 481920. It expires in 10 minutes.",
  "html": null,
  "attachments": []
}
text
الجزء النصي الصرف. حلّل هذا الجزء حين يكون موجودًا: فهو ثابت، لا يحمل أي وسم، والرمز المكوّن من ستة أرقام فيه هو رمز من ستة أرقام فعلاً.
html
جزء HTML، أو null حين لا يرسل المرسل واحدًا. غالبًا ما توجد روابط التأكيد هنا فقط.
attachments
عنصر واحد لكل ملف، ولكل منها رابط جلب جاهز مسبقًا. قائمة فارغة، لا null، حين لا يوجد أي منها.
expires_at
متى تُحذف هذه الرسالة، بصيغة RFC 3339 نفسها التي يستخدمها date. اقرأه بدل حسابه — فمدة الاحتفاظ ليست إعدادًا يمكنك التأكد منه من الخارج.

غالبًا ما تستطيع تجاوز هذا الاستدعاء كليًا. فالقائمة تعيد أصلاً الموضوع والمرسِل والتاريخ ومعاينة قصيرة للنص، وهذا يكفي لتقرر أن رسالة ما ليست ما تنتظره. وجلب كل رسالة في صندوق بريد لتكتشف أنك لم ترغب في أي منها هو أكثر طريقة شائعة يبطئ بها السكربت.

استخراج ملف

يحمل كل مرفق url خاصًا به، والتفصيل الذي يستحق معرفته قبل كتابة الحلقة هو أنه مسار على هذا المصدر لا عنوان مطلق — ومعامل mailbox موجود فيه مسبقًا. ضع المصدر في المقدمة، واجلبه، ولا شيء آخر يلزم تمريره ولا شيء يستوجب تفويضًا.

shell
ADDR="k7fq2m@grabmail.io"
ID="3QK7ZB5M9WVXR2HD4TNFJ0PC6A"

curl -fsG https://grabmail.io/api/v1/message/$ID \
  --data-urlencode "mailbox=$ADDR" \
| jq -r '.attachments[] | "\(.url)\t\(.filename)"' \
| while IFS=$'\t' read -r path name; do
    curl -fs "https://grabmail.io$path" -o "$name"
  done

يُجيب دائمًا بـapplication/octet-stream مع Content-Disposition: attachment، أيًا كان ما وسم به المرسل الملف. وهذا مقصود — فإعادة text/html الذي وضعه غريب كانت ستسمح لمرفق بالعمل كصفحة على هذا المصدر — لذا فإن السكربت الذي يهتم بالنوع يقرؤه من JSON الرسالة، حيث يكون بيانات لا تعليمة.

الرسالة كاملة، بملفاتها جميعًا، سقفها 5 MB. أما ماذا يعنيه ذلك السقف فعليًا بعد أن يُضخّم base64 ملفًا ثنائيًا فموضوع قائم بذاته، وله دليل عن المرفقات.

حصتان لمعدل الطلبات، لا حصة واحدة

هذا هو الجزء الذي يستحق معرفته ويسهل إغفاله: عرض قائمة عنوان وقراءة منه يُقاسان بشكل منفصل، لأنهما ليسا الخطر نفسه. أي شخص يعرف عنوانًا يستطيع استطلاع قائمته؛ أما قراءة رسالة فتتطلب معرّفًا، ولا شيء فيه للتخمين.

ما الذي تستدعيهالحصةماذا يعني ذلك عمليًا
GET /mailboxطلب واحد في الثانية، لكل عنوانهذه هي وتيرة الاستطلاع المقصودة، ولا تُكبَح أبدًا عند هذه السرعة. الأسرع من ذلك يُرفض، ولم يكن ليفيد أصلاً.
GET /message/{id}، GET /attachment/{id}، DELETEأسخى بكثير، لكل عنوانأفرغ صفحة رسائل دفعة واحدة دون توقف بينها. ولهذا تستطيع الواجهة فتح رسالة في الثانية نفسها التي جرى فيها استطلاع.
كل شيء، مجتمعًا1200 طلب في الدقيقة، لكل عميلعشرون عنوانًا يُستطلَع كل واحد منها مرة في الثانية — رقم يتجاوز بارتياح أي أتمتة حقيقية، وهو ما يوقف مضيفًا واحدًا يجول على عشرة آلاف عنوان.

تجاوز أيٍّ منها يمنحك 429 مع مدة الانتظار، بالثواني، في ترويسة Retry-After. التزم بها بدل التراجع بعدد اخترعته أنت: فهي الخادم يخبرك بالضبط متى سيقول نعم.

انتظر المدة التي طُلبت منك فقط، ولا أطول
read_box() {
  local wait
  while :; do
    BODY=$(curl -s -D /tmp/gm.h -G https://grabmail.io/api/v1/mailbox \
             --data-urlencode "address=$1")
    grep -qi '^HTTP/[0-9.]* 429' /tmp/gm.h || { printf '%s' "$BODY"; return 0; }
    wait=$(awk 'tolower($1) == "retry-after:" { print $2 + 0 }' /tmp/gm.h)
    sleep "${wait:-1}"
  done
}

أما كيف تنتظر رسالة لم تصل بعد — بموعد نهائي لا بعدد محاولات، وماذا تفعل حين يفوت ذلك الموعد — فهو موضوع دليل اختبار تدفقات التحقق. والحلقة هناك هي الحلقة نفسها التي تحتاجها مهمة مجدولة.

الحذف، والقاع الذي يقوم عليه كل شيء

يمكن التخلص من رسالة انتهيت منها فورًا بدل تركها تنتظر انتهاء مدة الاحتفاظ بها. أثر الاستدعاء لا يتغيّر بتكراره: حذف المعرّف نفسه مرتين يُجيب بـ200 في الحالتين، فلا يبدو طلب أُعيد إرساله فشلاً أبدًا.

shell
$ curl -s -X DELETE -G https://grabmail.io/api/v1/message/3QK7ZB5M9WVXR2HD4TNFJ0PC6A \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"
احذف حين تحصل على ما جئت من أجله
السكربت الذي يعالج رسالة ويتركها في مكانها سيعالجها مرة أخرى في التشغيل التالي، ما لم يحتفظ بقائمته الخاصة لما رآه. والحذف هو المحاسبة الأرخص.
لا تعتمد عليه من أجل الخصوصية
بين الوصول والحذف، كان بإمكان أي شخص يعرف العنوان أن يقرأها. الحذف يُغلق النافذة؛ ولا يُلغي ما حدث خلالها.
كل شيء يزول عند 5 يومًا مهما حدث
مقروءة أو غير مقروءة، محذوفة أو لا، تختفي الرسالة بعد 5 يومًا من وصولها. إنه حد صارم لا إعداد، ولا معامل يمدّده.

المعرّفات التي تتفرّع عندها، والحقل الذي لا تقرأه أبدًا

كل فشل هو JSON بالحقلين نفسيهما. error معرّف ثابت مقروء آليًا؛ أما message فللبشر وقد تُعاد صياغته في أي وقت. والتفرّع بناءً على الثاني هو كيف ينكسر سكربت في يوم لم يتغيّر فيه شيء.

الحالة والمعرّفما الذي حدثما الذي ينبغي أن يفعله السكربت
400 invalid_addressالعنوان مفقود، أو لا يشبه عنوانًا أصلاً.توقف فورًا. لا عدد من المحاولات يُصلح خطأ إملائيًا.
400 bad_cursorbefore ليس معرّف رسالة.توقف فورًا، وتحقق من أنك تُعيد next لا شيئًا بنيته بنفسك.
404 unknown_domainذلك النطاق غير مستضاف هنا.توقف فورًا. على نطاقك الخاص، هذا يعني سجل MX — انظر توصيل نطاق.
404 not_foundلا رسالة كهذه في ذلك الصندوق، أو أنها تجاوزت مدة الاحتفاظ بها.عاملها كأنها زالت. وهذا أيضًا ما تحصل عليه عند قراءة معرّف صالح مقابل صندوق بريد خاطئ.
429 rate_limitedإحدى الحصتين أعلاه.انتظر عدد الثواني المذكور في Retry-After ثم تابع. لا تعدّها أبدًا تشغيلاً فاشلاً.

مهمة تُفرغ عنوانًا كل ساعة

اجمع القطع معًا وستكون المهمة المجدولة قصيرة. هذه تأخذ كل رسالة تنتظر عند عنوان، وتكتبها على القرص بصيغة JSON، وتحذفها — فيبدأ التشغيل التالي من صندوق بريد فارغ، ولا يمكنه أبدًا معالجة الرسالة نفسها مرتين.

drain.sh
#!/usr/bin/env bash
set -euo pipefail

ADDR="orders@example.com"
OUT="/var/lib/mailsink"
API="https://grabmail.io/api/v1"

mkdir -p "$OUT"

while :; do
  page=$(curl -fsG "$API/mailbox" \
           --data-urlencode "address=$ADDR" \
           --data-urlencode "limit=200")

  ids=$(printf '%s' "$page" | jq -r '.messages[].id')
  [ -n "$ids" ] || break

  for id in $ids; do
    curl -fsG "$API/message/$id" \
      --data-urlencode "mailbox=$ADDR" > "$OUT/$id.json"
    curl -fs -X DELETE -G "$API/message/$id" \
      --data-urlencode "mailbox=$ADDR" > /dev/null
  done

  sleep 1
done
crontab
17 * * * * /usr/local/bin/drain.sh

أربع خصائص تستحق أن تُسمّى، لأنها ما يفصل مهمة تستطيع تركها تعمل عن أخرى عليك مراقبتها:

  1. آمنة عند تشغيلها مرتين. نسختان بدأتا معًا تؤديان العمل نفسه بترتيب مختلف وتحذفان الرسائل نفسها؛ والثانية تجد صندوق بريد فارغًا فتتوقف.
  2. تكتب قبل أن تحذف. فإن كان القرص ممتلئًا أو أُنهيت العملية، تبقى الرسالة في الصندوق عند التشغيل التالي. أما الترتيب المعاكس فيُفقِد بريدًا في اليوم الذي يهم فيه ذلك فعلاً.
  3. تُفرغ لا تقرأ فقط. ولأن كل رسالة تزول بمجرد أن تصبح آمنة على القرص، تعيد القائمة التالية المئتين اللاحقتين — فصندوق بريد استقبل أربعمئة رسالة بين تشغيلين يُفرَّغ كليًا، لا حتى أحدث خمسين منها فقط.
  4. تفشل بصوت مرتفع. الخروج برمز غير صفري هو ما يجعل cron يرسل لك المخرجات. والمهمة التي تبتلع أخطاءها الخاصة هي مهمة ظلت معطوبة طوال شهر.

ما لن تفعله واجهة برمجة التطبيقات هذه من أجلك

أربعة أشياء لا تفعلها، كل واحد منها عن قصد، ولن يُضاف أي منها لاحقًا. من الأفضل أن تصمم حول هذه الحدود الآن بدل اكتشافها من سكربت ظل يعمل جزئيًا بصمت:

لا ترسل أبدًا
استقبال فقط. لا توجد نقطة طرفية تضع رسالة على السلك، ولهذا لا يمكن استخدام أي شيء هنا للإرسال من عنوان لا تملكه.
لا تدفع أبدًا
لا webhooks ولا callbacks: أنت تسأل، وهي تُجيب. أما وكيل ذكاء اصطناعي يفضّل الانتظار الحاجب حتى يصل البريد فله بدلاً من ذلك wait_for_message عبر MCP — انظر دليل الوكلاء.
لا تبحث أبدًا
لا معامل استعلام لمرسِل أو لموضوع. يجري الترشيح من جهتك، فوق القائمة — وهذا أحد أسباب حمل القائمة معاينةً.
لا تُصادِق أبدًا، على نطاق عام
أي شخص يعرف العنوان يقرأ الصندوق. العنوان هو السر كله، فعامله كسرّ: لا تشتقه أبدًا من اسم عميل، ولا تُوجّه إلى نطاق مشترك أي شيء يزعجك أن يُقرأ بصوت عالٍ.

الحل للأخيرة هو نطاق تملكه أنت. وجّه سجل MX الخاص به إلى smtp.grabmail.io ليجيب كل عنوان عليه على النقاط الطرفية الثلاث نفسها، بلا واجهة برمجة تطبيقات ثانية تتعلمها ولا مفتاح تُدَوِّره — وعند الطلب، يُغلَق بحيث لا يفتحه إلا مفتاح Bearer. وتوصيل نطاق لا يتطلب أكثر من سجل DNS واحد.

10 smtp.grabmail.io

قبل أن تتركها تعمل

ستة أمور تستحق التحقق منها في مهمة ستعمل دون أن تراقبها:

  1. لا تستطلع أسرع من مرة في الثانية لكل عنوان، والتزم بـRetry-After حين يُطلب منك الانتظار.
  2. اتبع next حتى النهاية، بدل افتراض أن استدعاءً واحدًا هو الصندوق كله.
  3. تفرّع بناءً على رمز الحالة وerror، لا على message أبدًا.
  4. اكتب كل ما تحتاج إلى الاحتفاظ به قبل أن تحذفه، وتذكّر أن 5 يومًا قاع لا يمكنك تحريكه.
  5. اربط كل ما تستخرجه بقالبك الخاص. فنمط مكوّن من ستة أرقام مجردة سيطابق بارتياح سنةً، أو سعرًا، أو رقم طلب وصل أولاً.
  6. افترض أن العنوان عام ما لم يكن على نطاق تتحكم فيه، وضع كل ما يهم على نطاق كهذا.

لا شيء من هذا يحتاج إلى حساب. وإن تجاوزت النطاقات العامة احتياجك، فما يتغيّر هو النطاق في العنوان — أما الاستدعاءات الثلاثة أعلاه فتبقى كما هي تمامًا.

أسئلة

هل أحتاج إلى مفتاح API؟

لا. لا حساب على النطاقات العامة، ولا رمز، ولا شيء يستوجب التسجيل، والنطاق الذي تُوجّهه إلى هنا يُجيب على النقاط الطرفية نفسها بلا مفتاح أيضًا. الاستثناء الوحيد نطاق أغلقناه بناءً على طلب، ويُقرأ بترويسة Authorization: Bearer.

ما أسرع وتيرة يمكنني الاستطلاع بها؟

مرة في الثانية لكل عنوان بالنسبة لعرض القائمة، وهذه هي الوتيرة المقصودة ولا تُكبَح أبدًا. أما قراءة رسالة أو مرفق فتُقاس بشكل منفصل وأسخى بكثير، فتستطيع إفراغ صفحة رسائل دفعة واحدة. وكل شيء مجتمعًا سقفه 1200 طلب في الدقيقة لكل عميل.

كيف أعرف أنني قرأت الصندوق كاملاً؟

حين يعود next بقيمة null. لا تستنتج ذلك من صفحة قصيرة: فالخادم هو من يقرر ماهية الصفحة، وصفحة أقصر من limit ليست نهاية بحد ذاتها.

هل يمكنني استدعاء هذا من متصفح؟

نعم. تحمل الاستجابات Access-Control-Allow-Origin: *، فتستطيع صفحة من أي مصدر استدعاء النقاط الطرفية مباشرة دون وسيط خاص بك في المنتصف. التفويض هنا ليس cookie أبدًا، فالانفتاح إلى هذا الحد لا يكلّف شيئًا.

ماذا يحدث إن طلبت رسالة انتهت صلاحيتها؟

404 مع not_found، تمامًا كما مع معرّف لم يوجد قط. يُحذف كل شيء بعد 5 يومًا من وصوله، قُرئ أم لا، ولا معامل يمدّد ذلك.

هل يمكنني الحصول على webhook حين يصل بريد؟

لا — REST API تسأل فتُجاب، بلا callbacks. وإن كان ما تريده كودًا ينتظر انتظارًا حاجبًا حتى تصل الرسالة، فخادم MCP لديه wait_for_message، الذي يفعل ذلك بالضبط ومُخصَّص للوكلاء.

هل استخدام عنوان عام في بيئة الإنتاج آمن؟

فقط لأشياء لا تمانع أن يقرأها غريب. أي شخص يعرف العنوان يستطيع قراءة صندوقه، عبر واجهة برمجة التطبيقات تمامًا كما عبر الموقع. أما أي شيء آخر، فوجّه إلى هنا نطاقًا تملكه — فالاستدعاءات لا تتغيّر.

لماذا تظهر رسالة لم أفتحها قط كمقروءة؟

لأن شيئًا ما فتحها. قراءة رسالة عبر واجهة برمجة التطبيقات تضبط علامة seen فيها، وهذه العلامة مشتركة مع كل من ينظر إلى ذلك العنوان. سيستمر سكربت وشخص يراقبان الصندوق نفسه في مفاجأة أحدهما الآخر، لذا رشِّح حسب معرّفات عالجتها بدل seen.

هل يجب عليّ حذف الرسائل؟

لا — كل شيء تنتهي صلاحيته من تلقاء نفسه بعد 5 يومًا. لكن الحذف يستحق فعله على أي حال في مهمة مجدولة، لأن صندوق البريد المُفرَّغ هو أبسط سجل ممكن لما سبق أن عالجته.

تابع القراءة

جرّبه وهو جديد

عنوان واحد يستغرق نقرة واحدة، بلا حساب وبلا بطاقة. كل ما في هذا الدليل يعمل عليه فورًا.

أهلًا بعودتك

صناديقك ونطاقاتك في مكان واحد.