تخطَّ إلى المستندات
CLI

النطاقات والعناوين

أضف النطاقات وتحقّق منها، واقرأ سجلات DNS التي تحتاجها، وأدِر العناوين عليها، وافحص ما يمكنك الإرسال باسمه.

نظرة عامة

مساحتا أسماء تغطيان نطاقاتك. يدير openemail domains النطاقات المرتبطة بمساحة العمل: إضافتها وإزالتها، وسجلات DNS التي يحتاجها كل منها، وما إذا كان يستطيع الاستقبال والإرسال، وcatch-all الخاص به، ونطاقَي التتبع والملفات، والعناوين عليه. ويجيب openemail addresses عن سؤال أضيق: ما العناوين التي يجوز للمفتاح أو تسجيل الدخول الذي تستخدمه الإرسال باسمها.

  • يأخذ أمر النطاق معرّف النطاق، وهو UUID من domains list أو domains create. ولا يُقبل اسم المضيف بدلًا منه، لذا فإن openemail domains get acme.com يعطي 404 ويخرج بالرمز 5.
  • يأخذ أمر العنوان معرّف النطاق ثم معرّف العنوان، وهو UUID من domains list-addresses أو domains create-address.
  • يعمل domain وaddress كأسماء لمساحات الأسماء أيضًا. وتستجيب أفعال النطاقات للأسماء البديلة المعتادة، مثل ls وshow وnew وedit وrm، وكذلك addresses list. أما الأفعال الخمسة لعناوين النطاق، مثل create-address، فلا أسماء بديلة لها.
  • يسرد openemail <command> --help كل وسيط وخيار بنوعه، والنطاق الذي يحتاجه الاستدعاء، وطريقته ومساره، وما يعود. أضف --json لتحصل على الصفحة نفسها في صورة بيانات.

كل الأوامر

الأمرما تفعله
openemail domains listاسرد نطاقات مساحة العمل، أبجديًا، مع حالة الاستقبال والإرسال والتتبع والملفات
openemail domains get <id>اقرأ نطاقًا واحدًا مع عناوينه، وكل سجل DNS يستخدمه وما إذا عُثر على كل منها، وقراءة DMARC الخاصة به
openemail domains create --domain <value>أضف نطاقًا. يضم الجواب كل سجل DNS يجب نشره، وقد فُحص مرة بالفعل
openemail domains verify <id>افحص DNS النطاق فورًا وأعِد النطاق كما تركه الفحص
openemail domains update <id>شغّل catch-all أو أوقفه، واضبط نطاق التتبع ونطاق الملفات أو أزلهما
openemail domains delete <id>أزل النطاق وكل عنوان عليه. يطلب منك التأكيد
openemail domains list-addresses <id>اسرد العناوين على نطاق مع معرّفاتها وتسمياتها وحالة تفعيلها ومتى استقبل كل منها بريدًا آخر مرة
openemail domains create-address <id> --local-part <value>أنشئ عنوانًا على النطاق، مفعّلًا، مع --label اختياري
openemail domains get-address <id> <address-id>قراءة عنوان واحد على نطاق
openemail domains update-address <id> <address-id>أعِد تسمية عنوان بـ --label، أو أوقفه وشغّله بـ --no-enabled و--enabled
openemail domains delete-address <id> <address-id>أزل عنوانًا من نطاقه. يطلب منك التأكيد
openemail addresses listاسرد العناوين التي يجوز لك الإرسال باسمها بهذا المفتاح أو تسجيل الدخول، وحالة الاستقبال والإرسال لكل نطاق

كل خيار موجود في مساعدة أمره، مثل openemail domains update --help أو openemail domains create-address --help.

الاستقبال والإرسال

يبلّغ النطاق عن حقيقتين مستقلتين. تصبح receiving.verified صحيحة حين يجيب DNS العام بسجلات MX وسجل TXT _openemail-challenge الخاصة به، ومن ثم يستقبل البريد. وsending.status هي حالة التوقيع كما رآها الفحص الأخير: verified أو pending أو failed أو no_identity أو unknown. وتبيّن sending.canSend ما إذا كان إرسال من النطاق سيُقبل الآن، والحكم السلبي الأقدم من يوم يُعدّ مجهولًا، لذا ينبغي للسكربت أن يتفرع على canSend لا على status. وما دامت خاطئة، يُرفض الإرسال من النطاق بـ 409 domain_not_sendable.

  • يجري domains create أول فحص DNS أثناء الاستدعاء، لذا تحمل كل مدخلة في records بالفعل status: found أو missing أو null حين لم تُفحص بعد. انشر كل سجل كما هو بالضبط، لأن القيم خاصة بالنطاق.
  • يفحص domains verify فورًا. وخلال 10 ثوانٍ من الفحص الأخير لا يفحص شيئًا جديدًا ويعيد النطاق كما هو. وفي النطاق المتحقَّق منه يفحص سجلات التوقيع من جديد، فتكون sending محدَّثة.
  • يفحص domains get على نطاق غير متحقَّق منه من جديد حين يكون عمر الفحص الأخير أكثر من 20 ثانية، لذا يعمل استطلاع get أيضًا ولا يحتاج إلا إلى domains:read، حيث يحتاج verify إلى domains:write.
  • قد يستغرق السجل المنشور قبل لحظات بضع دقائق ليظهر في DNS العام.

في الطرفية، تطبع get وcreate وverify حقلًا واحدًا في كل سطر، مع الكتل المتداخلة مثل receiving وsending وrecords بصيغة JSON مضغوطة. أضف --json واقرأها بأداة مثل jq، كما تفعل الأمثلة أدناه.

نطاقات catch-all والتتبع والملفات

يغيّر domains update ثلاثة إعدادات لا يعتمد أحدها على الآخر. والخيار الذي تُغفله يُترك كما هو، ودون أي خيارات يعود النطاق دون تغيير.

الخيارما يغيّره
--catch-all, --no-catch-allالتشغيل يقبل البريد إلى أي عنوان على النطاق لم ينشئه أحد، ويظهر العنوان في list-addresses منذ رسالته الأولى. والإيقاف يرفض البريد إلى كل عنوان لم يُنشأ يدويًا، بما فيها العناوين التي التقطها catch-all من قبل. ويبدأ النطاق الجديد وهو مفعّل
--tracking-host <value>نطاق فرعي مثل links.acme.com للروابط المتتبَّعة وبكسل الفتح. وnull يزيله
--storage-host <value>نطاق فرعي مثل files.acme.com لروابط تنزيل الملفات المرسلة من النطاق. وnull يزيله
  • يُحفظ المضيف الجديد ويُفحص في الاستدعاء نفسه. انشر سجل CNAME باسم record.name والقيمة record.value من كتلة tracking أو storage في الجواب، مع إيقاف أي وكالة. وإعداد مضيف من جديد قد يعطيه قيمة مختلفة، لذا انشر القيمة التي يبلّغ عنها أحدث جواب.
  • إلى أن ينجح فحص، يظهر المضيف بالحالة pending ويبقى البريد الجديد على مضيف OpenEmail الافتراضي. وبمجرد نجاح فحص يظهر بالحالة active. ويواصل OpenEmail الفحص من تلقاء نفسه، والمضيف النشط الذي يفشل في ثلاثة فحوص متتالية، أو الذي مضت ساعتان على آخر فحص ناجح له، يظهر بالحالة failed بينما يعود البريد الجديد إلى المضيف الافتراضي.
  • أزل مضيفًا بـ null، كما في --tracking-host null. والقيمة الفارغة مثل --tracking-host= خطأ استخدام في CLI وتخرج بالرمز 2.
  • يحتاج المضيف الجديد إلى نطاق متحقَّق منه، أو على الأقل إلى نشر سجل TXT _openemail-challenge الخاص به. وإلا رُفض الاستدعاء بـ 409 domain_not_verified.
  • تُطبَّق الخيارات بالترتيب: catch-all، ثم نطاق التتبع، ثم نطاق الملفات. والخيار اللاحق الذي يُرفض قد يترك تغييرًا سابقًا محفوظًا، لذا أرسلها في استدعاءات منفصلة حين يجب أن يقوم كل منها بذاته.

العناوين على النطاق

يضم النطاق العناوين المنشأة يدويًا أو عبر API، وتلك التي التقطها catch-all حين وصلها البريد أول مرة. ويعرض list-addresses النوعين، بما فيها المعطّلة. أما catch-all نفسه فليس صفًا: إنه receiving.catchAll على النطاق.

  • يأخذ create-address الخيار --local-part، أي الجزء الذي يسبق @، و--label اختياريًا. ولا يلزم أن يكون النطاق متحقَّقًا منه بعد، لكن العنوان لا يستقبل شيئًا حتى يصبح كذلك. ويُرفض * وحده، لأن هذه هي كتابة catch-all.
  • إنشاء عنوان موجود بالفعل، أو عنوان أُزيل، ليس خطأ. يعود مفعّلًا، بالتسمية التي أرسلتها أو دونها، ويحتفظ بمعرّفه. والعنوان الذي التقطه catch-all يصبح عنوانًا منشأً يدويًا، فيبقى يستقبل بعد إيقاف catch-all.
  • مع تشغيل catch-all، يبدأ العنوان الجديد بإعدادات catch-all الخاصة بكل عنوان، مثل توقيعه وتتبعه، عدا إعدادات الخصوصية. تُنسخ مرة واحدة ولا تُبقى متزامنة.
  • يوقف update-address --no-enabled استقبال العنوان للبريد، فيتلقى المرسلون ارتدادًا، ولا يمكن الإرسال منه. ويحتفظ ببريده وإعداداته والأشخاص الذين يصلون إليه، ويكمل --enabled من حيث توقف. ويعيد --label تسميته، ويزيل --label null الاسم.
  • يذهب delete-address أبعد من ذلك. يُرفض البريد إلى العنوان حتى مع تشغيل catch-all، وتتوقف إعادة توجيهه، وتُحذف إعداداته، ويفقد من مُنحوا الوصول إليه ذلك الوصول، ويُبطَل تسجيل الدخول إليه بكلمة المرور. ويبقى البريد الذي استقبله بالفعل في صندوق البريد. وإنشاؤه من جديد يعيد المعرّف نفسه، دون الإعدادات أو الصلاحيات القديمة.

ما يمكنك الإرسال باسمه

يجيب openemail addresses list عن السؤال الكامن وراء 403 from_address_forbidden: ما العناوين التي يجوز للمفتاح أو تسجيل الدخول الذي تستدعي به وضعها في From. ويحتاج إلى emails:send لا إلى نطاق قراءة، لأنه يصف ما سيقبله الإرسال.

  • في الطرفية يطبع جدولين: العناوين، مع ما إذا كان كل منها مفعّلًا وما إذا كنت تستطيع الإرسال منه، ثم النطاقات، مع ما إذا كان كل منها متحقَّقًا منه للاستقبال وللإرسال، وcatch-all الخاص به.
  • تكون unrestricted صحيحة حين لا يقيّد بيانات الاعتماد شيء. عندها يمكن الإرسال من أي جزء محلي على نطاقات مساحة العمل، بما فيها تلك التي لم ينشئها أحد. وإلا فلا تكون canSend صحيحة إلا لعنوان مفعّل تغطيه بيانات الاعتماد، عبر نطاق كامل تحمله أو عبر قائمة عناوينها الخاصة.
  • تكون canSend خاطئة للعنوان المعطّل، وللعنوان الذي لا تغطيه بيانات الاعتماد، وللعنوان الذي لا يستطيع نطاقه التوقيع بعد.
  • لا تُسرد إلا العناوين المنشأة. وبيانات الاعتماد التي تحمل نطاقًا كاملًا تستطيع الإرسال باسم أي جزء محلي عليه، والعنوان الموجود في قائمتها دون صندوق بريد خلفه يمكن الإرسال منه دون أن يظهر هنا.
  • مع --json يطبع { unrestricted, addresses, domains, hasMore, nextCursor } لصفحة واحدة، و{ unrestricted, addresses, domains } مع --all، بدلًا من مستند { items, hasMore, nextCursor } الذي تطبعه القوائم الأخرى. ومع --all في أنبوب، أو مع --ndjson، يطبع عنوانًا واحدًا في كل سطر.

status وopen ومزوّدو DNS

يقرأ openemail status تسجيل دخولك وaddresses list وdomains list في الوقت نفسه ويطبعها معًا. يعرض جدول عناوين المرسل كل عنوان مع ما إذا كان يستطيع الإرسال وما إذا كان مفعّلًا. ويعرض جدول النطاقات كل نطاق بالحالة verified أو not verified للاستقبال، وحالة إرساله، وcatch-all الخاص به. ويعرض أول 100 من كل منهما ويذكر أمر --all للبقية.

  • الجزء الذي لا يجوز لبيانات اعتمادك قراءته، مثل النطاقات دون domains:read أو العناوين دون emails:send، يقول «غير متاح» مع السبب، ويُطبع الباقي على أي حال.
  • حين لا توجد عناوين بعد، يقترح openemail domains create --domain example.com.
  • يطبع openemail status --json كائنًا واحدًا فيه account وaddresses وdomains وunavailable، حيث تعطي unavailable السبب لكل جزء تعذرت قراءته.

ربط مزوّد DNS، كي تُكتب سجلات النطاق الجديد نيابةً عنك، لا يجري إلا في تطبيق الويب في 0.0.2. يفتح openemail open providers، أو open dns، تلك الصفحة. ويفتح open domains النطاقات وسجلات DNS الخاصة بها، وopen addresses العناوين. وإعادة التوجيه في تطبيق الويب أيضًا، ويفتحها open forwarding <address> لعنوان واحد. ويطبع --print الرابط بدلًا من فتح متصفح.

حيث كتب OpenEmail سجلات DNS للنطاق بنفسه، يستعيد domains delete تلك السجلات ويسرد في leftBehind ما تعذّر عليه استعادته، لتزيله أنت لدى مزوّد DNS. أما السجلات التي نشرتها بنفسك فلا تُمَس أبدًا، لذا أزلها أيضًا بعد ذهاب النطاق.

أمثلة

أضف نطاقًا وانشر سجلاته
openemail domains create --domain acme.com --json > acme.jsonjq -r '.records[] | [.type, .name, .value, (.priority // "")] | @tsv' acme.jsonopenemail domains verify "$(jq -r .id acme.json)"
انتظر حتى يستقبل، ثم افحص الإرسال
id=b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6funtil openemail domains get "$id" --json | jq -e .receiving.verified > /dev/null; do  sleep 30doneopenemail domains get "$id" --json | jq '.sending | {status, canSend, error}'
أوقف catch-all مع الإبقاء على عنوان واحد
openemail domains list-addresses "$id" --allopenemail domains create-address "$id" --local-part invoices --label Invoicesopenemail domains update "$id" --no-catch-all --dry-runopenemail domains update "$id" --no-catch-all

إنشاء invoices يدويًا يُبقيه مستقبِلًا بعد إيقاف catch-all، بينما يُرفض البريد إلى كل عنوان آخر التقطه catch-all. ويطبع التشغيل التجريبي PATCH وجسمه دون إرساله.

اضبط نطاق تتبع، ثم أزله
openemail domains update "$id" --tracking-host links.acme.com --json | jq '.tracking | {status, record, error}'openemail domains update "$id" --tracking-host null
إحالة عنوان إلى التقاعد
address_id=$(openemail domains list-addresses "$id" --all | jq -r 'select(.address == "[email protected]") | .id')openemail domains update-address "$id" "$address_id" --no-enabledopenemail domains delete-address "$id" "$address_id" --yes

إيقاف العنوان أولًا يمكن التراجع عنه بـ --enabled. أما الحذف فلا، ويحتاج في السكربت إلى --yes. ومع تسجيل الدخول عبر المتصفح يطلب أيضًا رمز تحقق، لا يتخطاه --yes أبدًا.

التدقيق من سكربت
openemail domains list --all | jq -r 'select(.sending.canSend | not) | [.domain, .sending.status] | @tsv'openemail addresses list --all --json | jq -r '.addresses[] | select(.canSend) | .address'

النطاقات والتأكيدات والأخطاء

النطاقالأوامر
domains:readdomains list, get, list-addresses, get-address
domains:writedomains create, verify, update, delete, create-address, update-address, delete-address
emails:sendaddresses list
  • تسجيل الدخول أو المفتاح الذي لا يملك النطاق يتوقف برمز الخروج 4، ويسمّي النطاق الناقص ويقول كيف تحصل عليه.
  • يطلب domains delete وdomains delete-address منك التأكيد. والإجابة بلا تخرج بالرمز 10 ولا تغيّر شيئًا. ومن دون إشراف ودون --yes يتوقفان برمز الخروج 2 قبل إرسال أي شيء.
  • مع تسجيل الدخول عبر المتصفح، يطلب هذان الحذفان أيضًا رمز تحقق، كما يفعل تطبيق الويب. ومن دون إشراف لا أحد يستطيع كتابته، فيتوقف الأمر برمز الخروج 4. شغّل openemail verify أولًا فلا تحتاج الدقائق الـ 60 التالية إلى رمز. ولا يُطلب من مفتاح API أبدًا.
  • يطبع --dry-run الطلب الذي كان التغيير سيرسله، مع جسمه، ويخرج بالرمز 0 دون إرساله أو طلب التأكيد منك.
  • تقرأ القائمة صفحة واحدة: يأخذ --limit من 1 إلى 100 ويرسل الخادم 25 حين يُغفل، ويأخذ --cursor قيمة nextCursor من الصفحة السابقة. ويقرأ --all كل صفحة، ويتوقف --max <n> بعد هذا العدد من العناصر، ويطبع --ndjson، أو --all في أنبوب، كائن JSON واحدًا في كل سطر. ومع --json يطبع domains list وlist-addresses مستند { items, hasMore, nextCursor } واحدًا.
  • المفتاح أو تسجيل الدخول المقيّد بنطاقات أو عناوين معيّنة يظل يرى كل نطاق وعنوان. لكنه لا يستطيع إضافة نطاق، وكل تغيير آخر يحتاج إلى أن يكون النطاق كاملًا بين النطاقات التي يحملها، وإلا رُفض الاستدعاء بـ 422 capability_unsupported.
  • يخرج الرفض برمز حالته: 4 لـ 403، مثل domain_allowance_reached حين لا تسمح الخطة بمزيد من النطاقات، و5 لـ 404، و6 لـ 409، مثل domain_already_added أو domain_claimed، و7 لـ 422، مثل invalid_tracking_host أو workspace_limit_reached.
  • لا يمكن إزالة آخر نطاق في مساحة العمل من CLI. ذلك 409 last_domain، لأن إزالته تحذف صندوق البريد كله، وهو ما يطلب تطبيق الويب تأكيده أولًا. والنطاق الذي يضم عناوين حساب محجوزة يعطي 409 domain_holds_reserved_addresses.
  • لا يُعاد domains create والحذفان أبدًا بعد فشل في الشبكة. و409 domain_already_added، أو 404 في محاولتك الثانية بعد ضياع الجواب، يعني أن الأولى نجحت. أما verify وupdate وcreate-address وupdate-address فتُعاد تلقائيًا، لأن إرسال أحدها مرتين يترك النتيجة نفسها.

إلى أين تذهب بعد ذلك

صندوق بريدك،
بشروطك أنت.

بنية بريد إلكتروني للشركات والذكاء الاصطناعي والوكلاء والبريد الشخصي. مبنية للتوسّع والخصوصية والتحكّم. كل ما كان ينبغي للبريد الإلكتروني أن يملكه منذ اليوم الأول.

OpenEmail

بنية بريد إلكتروني للشركات والذكاء الاصطناعي والوكلاء والبريد الشخصي. مبنية للتوسّع والخصوصية والتحكّم. كل ما كان ينبغي للبريد الإلكتروني أن يملكه منذ اليوم الأول.

© 2026 OpenEmail. جميع الحقوق محفوظة.