المفاتيح والأعضاء والأدوار
أدِر مفاتيح API واقرأ ما فعلته، وادعُ الأعضاء وأدِرهم، واكتب الأدوار، وافحص بيانات الاعتماد التي تستخدمها، وأنشئ صناديق وارد مؤقتة.
نظرة عامة
تقرر هذه الأوامر من وما الذي يستطيع الوصول إلى مساحة العمل. يدير openemail keys مفاتيح API ويقرأ ما فعله كل منها، ويدير openemail members الأشخاص في مساحة العمل ودعواتهم، ويحدد openemail roles ما يجوز للعضو أو المفتاح فعله. ويصف openemail me المفتاح أو تسجيل الدخول الذي تستدعي به، ويسرد openemail languages اللغات التي يقبلها الإرسال المترجَم. ولا تحتاج صناديق الوارد المؤقتة إلى تسجيل دخول إطلاقًا: openemail temp هو الطريقة اليومية لاستخدام أحدها، وopenemail temp-mail هو كل استدعاء في API التي تقف وراءه. ويصل openemail api إلى أي نقطة نهاية لا تصل إليها الأوامر الأخرى.
- يأخذ أمر المفتاح معرّف المفتاح، أي الأحرف الست عشرية الـ 24 بعد
oe_live_، كما يعرضهاkeys list. ويأخذ أمر العضو معرّف الحساب،userIdفيmembers list، لا عنوان بريد أبدًا. ويأخذ أمر الدور معرّفrole_منroles list، لأن الأدوار لا يُبحث عنها بالاسم. - تستجيب مساحات الأسماء أيضًا لـ
keyوmemberوroleوlanguageوtempMail. وتعمل الأسماء البديلة المعتادة للأفعال، مثلlsوshowوnewوeditوrm. وفيmembers، التي أفعالهاaddوremove، يقودnewوcreateإلىadd، ويقودrmوdelوdeleteإلىremove. - يسرد
openemail <command> --helpكل وسيط وخيار بنوعه، والنطاق الذي يحتاجه الاستدعاء، وطريقته ومساره، وما يعود. أضف--jsonلتحصل على الصفحة نفسها في صورة بيانات.
كل الأوامر
| الأمر | ما تفعله |
|---|---|
| openemail me get | صِف مفتاح API أو تسجيل الدخول عبر المتصفح الذي تستدعي به: نطاقاته، والدور الذي يحدّه، ومساحة عمله، ومن يجوز له الإرسال باسمه. لا يحتاج إلى نطاق |
| openemail me ping | تحقّق من أن بيانات الاعتماد تستوثق، لفحص الصحة. لا يحتاج إلى نطاق |
| openemail me rotate | امنح مفتاح API الذي تستدعي به سرًّا جديدًا، يُعرض مرة واحدة. يطلب منك التأكيد |
| openemail keys list | اسرد مفاتيح API في مساحة العمل، الأحدث أولًا، مع الحالة والنطاقات والدور ونطاق الإرسال وآخر استخدام. لا سرّ أبدًا |
| openemail keys get <id> | اقرأ مفتاحًا واحدًا، دون سرّه |
| openemail keys create --name <value> | أنشئ مفتاحًا واستلم سرّه مرة واحدة، في token |
| openemail keys update <id> | أعِد تسمية مفتاح، أو استبدل نطاقاته أو نطاق إرساله، أو أوقفه وشغّله بـ --no-enabled و--enabled |
| openemail keys delete <id> | أزل مفتاحًا مبطَلًا من القائمة، مع الاحتفاظ بتاريخه. يطلب منك التأكيد |
| openemail keys rotate <id> | امنح مفتاحًا سرًّا جديدًا، يُعرض مرة واحدة، وأوقف القديم فورًا. يطلب منك التأكيد |
| openemail keys revoke <id> | أبطل مفتاحًا نهائيًا، مع --reason اختياري. يطلب منك التأكيد |
| openemail keys list-requests <id> | اقرأ سجل طلبات مفتاح واحد: الطريقة، والمسار، والحالة، ورمز الخطأ، والمدة، وعنوان IP، ووكيل المستخدم |
| openemail keys list-activity <id> | اقرأ ما حدث لمفتاح واحد: الإنشاء، والتغيير، والتدوير، والإيقاف والتشغيل، والإبطال، والحذف، وكل استدعاء مرفوض |
| openemail keys list-workspace-requests | اقرأ سجل طلبات كل مفتاح تستطيع رؤيته، أو المفاتيح التي يسمّيها --key-ids |
| openemail keys list-workspace-activity | اقرأ ما حدث لكل مفتاح تستطيع رؤيته، أو للمفاتيح التي يسمّيها --key-ids |
| openemail roles list | اسرد أدوار مساحة العمل، المزروعة أولًا، مع عدد الأعضاء والمفاتيح التي تحمل كلًّا منها |
| openemail roles get <id> | اقرأ دورًا واحدًا مع أذوناته وأعداد استخدامه الحية |
| openemail roles create --name <value> --permissions <a,b> | أنشئ دورًا مخصصًا، مع --description اختياري |
| openemail roles update <id> | أعِد تسمية دور، أو غيّر وصفه، أو استبدل قائمة أذوناته كلها |
| openemail roles delete <id> | احذف دورًا وانقل من يحمله إلى الدور المحدد في --reassign-to. يطلب منك التأكيد |
| openemail roles list-permissions | اسرد مفردات الأذونات، مع تسمية ومجموعة وما إذا كان المفتاح يستطيع حمل كل منها |
| openemail members list | اسرد كل من لديه وصول، المالك أولًا، مع دوره وأذوناته والعناوين والنطاقات التي يجوز لكل منهم استخدامها |
| openemail members get <user-id> | قراءة عضو واحد بمعرّف الحساب |
| openemail members add --email <value> --role-id <value> | ادعُ شخصًا بدور، ومع عناوين أو نطاقات كاملة عبر --address-ids و--domain-ids و--access |
| openemail members update <user-id> --role-id <value> | انقل عضوًا إلى دور آخر. وتبقى منح العناوين والنطاقات الخاصة به كما هي |
| openemail members remove <user-id> | أخرج شخصًا من مساحة العمل مع كل منحة عنوان يحملها. يطلب منك التأكيد |
| openemail members grant-address <user-id> --address-id <value> | امنح عضوًا عنوانًا واحدًا، أو غيّر --access الخاص به عليه |
| openemail members revoke-address <user-id> <address-id> | استرجع عنوانًا واحدًا من عضو. يطلب منك التأكيد |
| openemail members list-invitations | اسرد الدعوات التي لم يقبلها أحد بعد، بما فيها المنتهية |
| openemail members revoke-invitation <invitation-id> | اسحب دعوة، فيتوقف رابطها عن العمل. يطلب منك التأكيد |
| openemail members resend-invitation <invitation-id> | أرسل دعوة من جديد، برابط جديد و14 يومًا إضافية |
| openemail languages list | اسرد كل لغة يقبلها الإرسال المترجَم، بالترتيب الذي ينبغي أن يعرضها به المنتقي. لا يحتاج إلى نطاق |
| openemail temp new [--name <local-part>] [--domain <domain>] [--ttl <minutes>] | أنشئ صندوق وارد مؤقتًا واطبع عنوانه فقط. لا يحتاج إلى تسجيل دخول |
| openemail temp list | اسرد صناديق الوارد المؤقتة التي أنشأتها هذه CLI، دون قراءة الشبكة |
| openemail temp read [inbox] [message-id] | اسرد البريد في صندوق وارد، أو اطبع رسالة واحدة نصًا مقروءًا |
| openemail temp watch [inbox] [--first] | اطبع كل رسالة جديدة لحظة وصولها، مع الفحص كل 3 ثوانٍ |
| openemail temp delete [inbox] [--yes] | احذف صندوق وارد وبريده الآن، وانسَ رمزه. يطلب منك التأكيد |
| openemail temp-mail list-domains | اسرد النطاقات التي يمكن إنشاء صندوق وارد مؤقت عليها. لا يحتاج إلى بيانات اعتماد |
| openemail temp-mail create | أنشئ صندوق وارد مؤقتًا ورمز صندوقه، الذي تحفظه CLI. لا يحتاج إلى بيانات اعتماد |
| openemail temp-mail get <inbox-id> | اقرأ انتهاء صلاحية صندوق وارد، والتمديدات المتبقية، وعدد الرسائل |
| openemail temp-mail extend <inbox-id> | ادفع انتهاء الصلاحية حتى ساعة أبعد، ضمن 24 ساعة من إنشاء صندوق الوارد |
| openemail temp-mail delete <inbox-id> | دمّر صندوق وارد وبريده الآن. يطلب منك التأكيد |
| openemail temp-mail list-messages <inbox-id> | اسرد صفحة واحدة من الرسائل، الأحدث أولًا، لكل منها مقتطف نصي قصير |
| openemail temp-mail get-message <inbox-id> <message-id> | اقرأ رسالة واحدة مع نصها المخزن، وعلّمها كمطّلع عليها |
| openemail temp-mail delete-message <inbox-id> <message-id> | احذف رسالة واحدة مع نصها ومرفقاتها. يطلب منك التأكيد |
| openemail temp-mail list-attachments <inbox-id> <message-id> | اقرأ مرفقات رسالة، ببايتاتها بترميز base64 |
| openemail api <method> <path> | استدعِ أي نقطة نهاية REST بتسجيل دخولك، ورموز التحقق الخاصة به، وتأكيداته |
كل خيار موجود في مساعدة أمره، مثل openemail keys create --help أو openemail members add --help أو openemail temp new --help.
مفاتيح API
قراءة المفاتيح تحتاج إلى keys:read، وكل تغيير يحتاج إلى keys:manage. ولا يُمنح تسجيل الدخول عبر المتصفح أبدًا keys:write أو keys:manage، لذا يتطلب إنشاء المفاتيح وتغييرها وتدويرها وإبطالها وحذفها مفتاح API يحمل keys:manage، أو تطبيق الويب (openemail open api-keys). وتسجيل الدخول عبر المتصفح مع keys:read لا يقرأ المفاتيح إلا لمالك مساحة العمل، ويُرفض تسجيل دخول العضو بـ 403 owner_only.
- تطبع
keys createوkeys rotateوme rotateسر المفتاح، فيtoken، مرة واحدة، ثم تحذّر CLI من أنه لن يُعرض مرة أخرى. وكل قراءة تعرضmaskedKeyبدلًا منه. - إن أُغفلت القيم، فالمفتاح الجديد يحمل
emails:sendفقط، ويأخذ دور المفتاح الذي ينشئه ونطاق إرساله وانتهاء صلاحيته. ويحدد--domain-allowlistو--address-allowlistمن يجوز له الإرسال باسمه، ويأخذ--expires-in-minutesمن 5 إلى 5,256,000، أي عشر سنوات. - المفتاح لا ينشئ أبدًا مفتاحًا أوسع منه ولا يصل إليه. يجب أن تقع النطاقات والدور وانتهاء الصلاحية والوضع ونطاق الإرسال كلها داخل المفتاح المستدعي، وإلا رُفض الاستدعاء بـ 403
beyond_caller_authority، وتسمّيparamما كان أوسع مما ينبغي. والمفتاح المقيّد ببعض النطاقات أو العناوين لا يرى إلا المفاتيح الواقعة داخل نطاق إرساله، وأي مفتاح آخر يعطي 404. - يستبدل
keys updateما ترسله: يأخذ كل من--scopesو--address-allowlistو--domain-allowlistالقائمة الجديدة كلها، والخيار الذي تُغفله يبقى كما كان. ويوقف--no-enabledالمفتاح، فيُرفض كل استدعاء به بـinactive_api_key، ويعيده--enabledكما كان تمامًا. وهذا يوقف المفتاح بطريقة يمكن التراجع عنها. keys revokeنهائي: لا يمكن أبدًا إعادة تشغيل المفتاح أو تدويره أو تغييره. ولا يزيلkeys deleteإلا مفتاحًا مبطَلًا، وأي مفتاح آخر يُرفض بـ 409not_revoked. ويبقى سجل طلبات المفتاح المحذوف ونشاطه، تحت «مفتاح محذوف».- لا نافذة تداخل في
keys rotate، فيتوقف السر القديم عن العمل لحظة عودة الجديد. وحين يكون المفتاح هو الذي يستخدمه ملفك الشخصي المحفوظ، تحفظ CLI السر الجديد في ذلك الملف فيظل يعمل. أما المفتاح القادم منOPENEMAIL_API_KEYأو--api-keyفلا يمكن حفظه، لذا تطلب منك CLI تخزين الرمز الجديد حيثما كان المفتاح القديم محفوظًا.
يسجل سجل الطلبات كل استدعاء أجراه مفتاح: الطريقة، والمسار، والحالة، ورمز الخطأ، والمدة، وعنوان IP، ووكيل المستخدم، ولا جسم ولا سلسلة استعلام أبدًا. لا يُقتطع منه شيء، فيمتد إلى أول استدعاء للمفتاح، والاستدعاءات التي تجري بتسجيل الدخول عبر المتصفح ليست فيه. ويسجل سجل النشاط كل تغيير على مفتاح، وكل استدعاء قدّم المفتاح ورُفض، بوصفه auth_failed، مع من أجرى كل تغيير في actor.
- يقرأ
list-requestsوlist-activityمفتاحًا واحدًا. ويقرأlist-workspace-requestsوlist-workspace-activityكل مفتاح تستطيع رؤيته، أو حتى 50 مفتاحًا يسمّيها--key-ids، بما فيها المفاتيح المحذوفة. - يُبقي
--sinceو--untilفترة ويأخذان وقتًا بصيغة ISO 8601 مثل2026-09-01T00:00:00Z. ويُبقي--failed-onlyالاستدعاءات التي أُجيبت بحالة 400 أو أكثر.
بيانات اعتمادك، واللغات
openemail me get هو أول أمر تشغّله حين يُرفض استدعاء. لا يحتاج إلى نطاق، لذا يستطيع أي مفتاح أو تسجيل دخول صالح أن يصف نفسه.
scopesهي ما يجوز لبيانات الاعتماد فعله الآن: النطاقات التي أُنشئت بها، مقلَّصة بالدور الذي صدرت تحته، تُحسب في كل طلب. وgrantedScopesهي ما أُنشئت به، وroleIdيسمّي الدور. والنطاق الموجود فيgrantedScopesوالناقص منscopesأزاله الدور. وهذا هو السبب المعتاد لـ 403insufficient_scopeعلى مفتاح يبدو أنه يحمل النطاق، والحل هو تغيير الدور لا إنشاء مفتاح آخر.- تقول
domainAllowlistوaddressAllowlistمن يجوز له الإرسال باسمه. وكون الاثنين null يعني أي عنوان تملكه مساحة العمل. - مع تسجيل الدخول عبر المتصفح يصف تسجيل الدخول:
objectهوoauth_token، وclientIdيسمّي التطبيق المرتبط الخاص بهذه CLI، وexpiresAtهو موعد انتهاء موافقتك، أو null حين لا تنتهي أبدًا. - يجيب
me pingبـok: trueمع تفاصيل النطاق نفسها لكن دون قوائم السماح، وهذا يناسب فحص الصحة. والمفتاح المبطَل أو المنتهي أو الموقوف أو المكتوب خطأً يفشل بـ 401 ورمز الخروج3. - يمنح
me rotateالمفتاح الذي تستدعي به سرًّا جديدًا. ويحتاج إلىkeys:write، الذي لا يحمله تسجيل الدخول عبر المتصفح أبدًا، لذا يحتاج إلى مفتاح API. ويبقى كل شيء آخر في المفتاح، ويتوقف السر القديم فورًا، ويحصل الملف الشخصي المحفوظ على الجديد، كما فيkeys rotate. وضياع الجواب قد يترك المفتاح بسرّ لم يره أحد، فيحتاج حينها إلى سرّ جديد من تطبيق الويب. - يعرض
openemail whoamiالجواب نفسه منسقًا للبشر.
يطبع openemail languages list جدول اللغات كله في جواب واحد، نحو مئتي صف، مع رمز كل لغة واسمها بالإنجليزية واسمها بلغتها وعلمها وما إذا كانت تُكتب من اليمين إلى اليسار. ويعمل الرمز أو الاسم الإنجليزي أو الاسم بلغتها كلها هدفًا للإرسال المترجَم. ويحتاج إلى تسجيل دخول دون نطاق. ويطبع openemail ai languages الجدول نفسه مع خيار --search، ودون تسجيل دخول يطبع الجدول المضمَّن في CLI.
الأعضاء والأدوار
يحمل العضو شيئين لا يُدمجان أبدًا. دوره يقول ما يجوز له فعله، ومنح العناوين والنطاقات الخاصة به تقول أي بريد يجوز له فعل ذلك به، ولكل منحة وصولها الخاص: member يقرأ ويرسل، وviewer يقرأ فقط. والإرسال يحتاج إلى الاثنين، فالدور الذي فيه emails:send مع منحة viewer على عنوان لا يستطيع الإرسال منه. والنطاق الكامل يغطي كل عنوان عليه، بما فيها العناوين التي تُنشأ لاحقًا.
- يضع
members listمالك مساحة العمل أولًا، معلَّمًا بـisOwner، لذا استبعد ذلك الصف عند عدّ المقاعد. يحمل المالك كل إذن ولا يمكن دعوته أو تغييره أو إزالته، ولا يمكن كذلك دعوة من هو في مساحة العمل بالفعل مرة أخرى: وكلاهما 422member_is_owner. - الأشخاص الذين يحملون منح عناوين لكنهم لم يُعطوا دورًا قط يعودون مع
implied: true، ويُستنتج دورهم من منحهم. ويمنحهمmembers updateدورًا حقيقيًا. - يرسل
members addدعوة، حتى لمن لديه حساب بالفعل. لا يُمنح شيء حتى يقبل، ثم يُمنح بالضبط الدور والعناوين والنطاقات التي تحملها. ودعوة العنوان نفسه من جديد خلال عشر دقائق تعطي 409invitation_too_soon، وبعد ذلك تُحدِّث الدعوة المنتظرة بدلًا من إرسال ثانية. - يرسل
resend-invitationرابطًا جديدًا صالحًا لـ 14 يومًا إضافية ويُحيل القديم إلى التقاعد، وهذا يجدد أيضًا الدعوة المنتهية. ويسحبrevoke-invitationدعوة، والدعوة المقبولة بالفعل تعطي 409invitation_accepted، فأزِل العضو بدلًا من ذلك. - يغيّر
members updateالدور ولا شيء غيره. ويمنحgrant-addressعنوانًا واحدًا أو يغيّر الوصول إليه، فتشغيله مرة أخرى مع--accessآخر يغيّر المنحة بدلًا من إضافة ثانية. ويسترجعrevoke-addressعنوانًا واحدًا ويترك البقية. وإبطال آخر منحة لعضو مستنتَج يزيله من مساحة العمل. - ينهي
members removeوصول شخص إلى مساحة العمل، وعضويته وكل منحة له، ويبلّغ فيaddressesRevokedعن عدد منح العناوين التي ذهبت. ويبقى حسابه والبريد الذي أرسله دون مساس.
الدور سقف أيضًا لمفاتيح API الصادرة تحته. وما يجوز للمفتاح فعله هو نطاقاته الخاصة مقلَّصة بأذونات دوره، تُحسب في كل طلب.
- يعرض
roles listالأدوار المزروعة أولًا، بالترتيب Owner وAdmin وMember وViewer وDeveloper وBilling، ثم الأدوار المخصصة بالاسم. وتضم مساحة العمل حتى 24 دورًا مخصصًا، وبعد ذلك يعطيroles createالرمز 422role_limit_reached. - يخزّن الدور الأذونات التي تقتضيها أذوناته، فـ
templates:writeيخزّن أيضًاtemplates:read، وroles:writeيجلبroles:readوmembers:read. اقرأ القائمة من الجواب بدلًا من افتراضها. - يستبدل
roles update --permissionsالقائمة كلها، لذا اقرأ الدور، وغيّر القائمة، وأرسلها كلها. ويمسح--description nullالملاحظة. ويسري التغيير في الاستدعاء التالي لكل عضو ومفتاح يحمل الدور. - يمكن إعادة تسمية كل دور عدا Owner وإعادة كتابته وحذفه، بما فيها الأدوار المزروعة، والدور المزروع المحذوف لا يعود. ويجيب دور المالك عن التعديل بـ 409
role_immutableوعن الحذف بـ 409role_undeletable. - ما دام أي عضو أو مفتاح API أو دعوة منتظرة يحمل دورًا، يحتاج
roles deleteإلى--reassign-toمع الدور الذي يتولاهم، وإلا رُفض بـ 409role_in_use. والمفاتيح المبطَلة لا تزال تشير إلى دورها، لذا قد يحتاجه دور عددapiKeysفيه 0. ويبلّغ الجواب عن الأشخاص فيreassignedوالمفاتيح فيkeysReassigned. - يسرد
roles list-permissionsالمفردات كلها مع تسمية ومجموعة لكل منها. وبعضها، مثلbilling:writeوworkspace:manage، يعود معscope: false: يجوز للدور أن يحملها، لكن لا يستطيع ذلك أي مفتاح.
المفتاح الذي يحمل roles:write يستطيع تعديل الدور الذي يحدّه وتوسيع نفسه في استدعائه التالي، لذا أبعد ذلك النطاق عن المفاتيح التي لا تحتاج إلا إلى القراءة. ومع تسجيل الدخول عبر المتصفح، لا يُمنح members:write وroles:write إلا حين تشمل الموافقة مساحة العمل كلها لا بعض النطاقات أو العناوين.
صناديق وارد مؤقتة
لا يحتاج صندوق الوارد المؤقت إلى حساب ولا إلى تسجيل دخول. يُوصَل إليه برمز صندوقه الخاص، الذي يبدأ بـ oe_inbox_ ويعود مرة واحدة، عند إنشاء الصندوق. استخدم openemail temp في الاستخدام اليومي، وopenemail temp-mail حين تحتاج إلى حقل أو خطوة لا يعرضها temp، مثل التمديدات المتبقية، أو تمديد، أو بايتات مرفق.
- كلاهما يحفظ الرمز في
~/.openemail/temp-mail.json، الذي لا يقرؤه أحد سواك. يحفظهtemp newوtemp-mail create، ويعرضtemp listالصناديق المنشأة بأي من الطريقتين، وينساه كلا الحذفين. ويمكن تسمية الصندوق المحفوظ بعنوانه أينما طلب أمر معرّفه. - لصندوق وارد لم تنشئه هذه CLI، مرّر الرمز بـ
--inbox-token. ودون رمز محفوظ أو ممرَّر، يتوقف الأمر برمز الخروج3قبل إرسال أي شيء. - يسمّي أمرا الإنشاء خياراتهما بطريقة مختلفة: يأخذ
temp newالخيارات--nameو--domainو--ttl، ويأخذtemp-mail createالخيارات--local-partو--domainو--ttl-minutes. والجزء المحلي من 3 إلى 32 حرفًا من الحروف أو الأرقام أو النقاط أو الشرطات أو الشرطات السفلية، يبدأ وينتهي بحرف أو رقم، وتُرفض أسماء مثلpostmaster. ومدة الإيجار من 1 إلى 1440 دقيقة، و60 افتراضيًا. - يستطيع كل عنوان IP إنشاء 6 صناديق في الساعة و30 في اليوم، والتالي يعطي 429
too_many_inboxes، برمز الخروج8. وتمديد صندوق تملكه بالفعل لا يُحتسب، لذا فإنtemp-mail extendهو الجواب عن ذلك الحد. - يضيف
temp-mail extendحتى ساعة، ولا يتجاوز أبدًا 24 ساعة بعد إنشاء الصندوق، و23 مرة على الأكثر. اقرأextensionsLeftمن الجواب. وعند 0 يصبح 409extension_limitنهائيًا. - يقرأ
temp-mail list-messagesمن 1 إلى 50 رسالة في الصفحة، و50 افتراضيًا، لكل منهاsnippetنصي حتى 400 حرف كثيرًا ما يحمل رمزًا لمرة واحدة. ولا يُسقط شيء بعد الصفحة، ويمر--allعلى كل صفحة. - قراءة رسالة بـ
temp readأوtemp-mail get-messageأوtemp-mail list-attachmentsتعلّمها كمطّلع عليها. والنص الذي يتجاوز 2 MB يُقتطع، وتقولtruncatedذلك، والمرفق الذي يتجاوز 8 MB لم يُحتفظ به قط، فتكونcontentالخاصة به null. - حذف صندوق وارد يحذف بريده فورًا، لكن العنوان يبقى محجوزًا حتى 7 أيام بعد الموعد الذي كان إيجاره سينتهي فيه، وطلبه من جديد قبل ذلك يعطي 409
address_taken.
البريد في صندوق الوارد المؤقت يأتي من غرباء، إلى عنوان يستطيع أي أحد تسميته. مرسله لا يُتحقق منه أبدًا ولا يُفحص شيء فيه، لذا تعامل بحذر مع روابطه وHTML ومرفقاته.
أي نقطة نهاية، ومساحة الأسماء security
يرسل openemail api <method> <path> طلبًا واحدًا عبر النقل نفسه الذي يستخدمه كل أمر آخر، لذا ينطبق ملفك الشخصي أو مفتاحك، وتجديد الرمز، ورموز التحقق، والتأكيدات كلها. والمسار وحده يعني GET، ويُطبع جواب JSON منسقًا. وopenemail api /keys/self هو الاستدعاء الذي يقف وراء me get.
- يأخذ
-dو--dataالجسم بصيغة JSON مضمّنة، أو من ملف بـ@path، أو من stdin بـ-. ويأخذ-qو--queryو-Hو--headerالقيمةkey=valueويمكن تكرارها، ويحفظ-oو--outالرد في ملف كما وصل. DELETE، وأي استدعاء كان أمر الموارد سيطلب تأكيده، مثل إبطال مفتاح أو تدويره، يطلب منك التأكيد أولًا، ومن دون إشراف يحتاج إلى--yes.- الطلب الفاشل يطبع خطأ API ويخرج بالرمز المطابق.
لا تُسرد مساحة الأسماء security في openemail --help، لأن openemail verify يقودها. وأفعالها step-up-status وbegin-step-up وverify-step-up هي الاستدعاءات التي يجريها verify: يقرأ verify --status الحالة، ويطلب verify رمزًا، ويسألك عنه، ويتحقق منه. وهي موجودة لتسجيل الدخول عبر المتصفح. ومع مفتاح API يُرفض كل منها بـ 400 step_up_not_applicable، ويقول openemail verify إن المفتاح لا يحتاج إلى رمز أبدًا.
أمثلة
openemail keys create --name 'Billing sender' --scopes emails:send \ --domain-allowlist billing.acme.com --expires-in-minutes 129600 --json \ | jq -r .token | openemail login --with-token --profile billingopenemail whoami --profile billingشغّله بمفتاح API يحمل keys:manage، عبر OPENEMAIL_API_KEY مثلًا. يذهب السر من الجواب مباشرة إلى ملف شخصي جديد، فلا يظهر أبدًا على الشاشة ولا في ملف. ولا يستطيع المفتاح الإرسال إلا من billing.acme.com، وتنتهي صلاحيته بعد 90 يومًا.
openemail keys list --all | jq -r 'select(.status != "active") | [.name, .status, .lastUsedAt] | @tsv'openemail keys list-workspace-requests --failed-only --since 2026-09-26T00:00:00Z --all \ | jq -r '[.createdAt, .keyName, .status, .errorCode, .method, .path] | @tsv'id=4c1b257a66287fd113bd89d0openemail keys update "$id" --no-enabledopenemail keys list-activity "$id" --since 2026-09-27T00:00:00Z --all | jq -r 'select(.type == "auth_failed") | .createdAt'openemail keys revoke "$id" --reason 'Contractor offboarded' --yesopenemail keys delete "$id" --yesإيقاف المفتاح أولًا يمكن التراجع عنه بـ --enabled. وكل استدعاء لا يزال يقدّمه يُرفض ويظهر في نشاطه بوصفه auth_failed، وهذا يخبرك بما لا يزال يعتمد عليه. أما الإبطال فلا تراجع عنه، ولا يمكن حذف إلا مفتاح مبطَل.
openemail roles list-permissions --json | jq -r '.[] | [.group, .id, .label] | @tsv'role=$(openemail roles create --name Support --permissions threads:write,emails:send,templates:read \ --description 'Answers help@ and nothing else.' --json | jq -r .id)openemail members add --email [email protected] --role-id "$role" \ --domain-ids 93542ff8-2baa-4f2f-841d-5ceaa074ab0d --access memberopenemail members list-invitationsيعود الدور حاملًا threads:read وemails:read أيضًا، لأن الأذونات التي يسمّيها تقتضيهما. ولا يحصل Sam على الدور والنطاق الكامل إلا بعد أن يقبل. ومع تسجيل الدخول عبر المتصفح، يطلب members add رمز تحقق أولًا.
old=role_8b1f4c2e9a7d3b60e5f1a2c4new=role_2c7e9a1f4b8d3e60c5a7f1b9user=$(openemail members list --all | jq -r 'select(.email == "[email protected]") | .userId')openemail members update "$user" --role-id "$new"openemail roles get "$old" --json | jq '{name, members, apiKeys}'openemail roles delete "$old" --reassign-to "$new" --dry-runopenemail roles delete "$old" --reassign-to "$new" --yesيُعدّ members وapiKeys حين تسأل، فيبيّنان ما سينقله الحذف. ويطبع التشغيل التجريبي DELETE مع reassignTo في استعلامه دون إرساله. ومع تسجيل الدخول عبر المتصفح، يطلب كل من التحديث والحذف رمز تحقق، لذا شغّل openemail verify أولًا حين يفعل سكربت ذلك.
address=$(openemail temp new --ttl 15)openemail send --from [email protected] --to "$address" --subject 'Delivery check' --text 'Your code is 482913' --yesopenemail temp watch "$address" --first --json | jq -r .snippet | grep -oE '[0-9]{6}'openemail temp delete "$address" --yesلا يطبع temp new إلا العنوان، فيتسع له متغير صدفة، ويتوقف temp watch --first عند أول رسالة. وجّه نموذج تسجيل إلى العنوان بدلًا من openemail send لتلتقط رمز تأكيده بالطريقة نفسها.
النطاقات والتأكيدات والأخطاء
| النطاق | الأوامر |
|---|---|
| keys:read | keys list, get, list-requests, list-activity, list-workspace-requests, list-workspace-activity |
| keys:manage | keys create, update, delete, rotate, revoke |
| keys:write | me rotate |
| roles:read | roles list, get, list-permissions |
| roles:write | roles create, update, delete |
| members:read | members list, get, list-invitations |
| members:write | members add, update, remove, grant-address, revoke-address, revoke-invitation, resend-invitation |
| لا شيء، مع أي مفتاح أو تسجيل دخول | me get, me ping, languages list |
| لا شيء، ودون تسجيل دخول | temp وtemp-mail list-domains وcreate. وتأخذ أوامر temp-mail الأخرى رمز الصندوق |
- تسجيل الدخول أو المفتاح الذي لا يملك النطاق يتوقف برمز الخروج
4، ويسمّي النطاق الناقص ويقول كيف تحصل عليه. - تطلب هذه منك التأكيد:
keys deleteوrotateوrevoke، وme rotate، وroles delete، وmembers removeوrevoke-addressوrevoke-invitation، وtemp delete، وtemp-mail deleteوdelete-message. والإجابة بلا تخرج بالرمز10ولا تغيّر شيئًا. ومن دون إشراف ودون--yesتتوقف برمز الخروج2قبل إرسال أي شيء. - مع تسجيل الدخول عبر المتصفح، يطلب
roles updateوroles delete، وmembers addوupdateوremoveوgrant-addressوrevoke-address، رمز تحقق أيضًا، ما لم يكن تسجيل الدخول هذا قد تحقق من رمز خلال الدقائق الـ 60 الماضية. لا يتخطاه--yesأبدًا، ومن دون إشراف لا أحد يستطيع كتابته، فيتوقف الأمر برمز الخروج4. شغّلopenemail verifyأولًا. ولا يُطلب من مفتاح API أبدًا. - يطبع
--dry-runالطلب الذي كان التغيير سيرسله، مع جسمه، ويخرج بالرمز0دون إرساله أو طلب التأكيد منك. - تقرأ القائمة صفحة واحدة. يأخذ
--limitمن 1 إلى 100 ويرسل الخادم 25 حين يُغفل، عداtemp-mail list-messagesالذي يأخذ من 1 إلى 50 ويرسل 50. ويأخذ--cursorقيمةnextCursorمن الصفحة السابقة. ويقرأ--allكل صفحة، ويتوقف--max <n>بعد هذا العدد من العناصر، ويطبع--ndjson، أو--allفي أنبوب، كائن JSON واحدًا في كل سطر. ومع--jsonتطبع القائمة مستند{ items, hasMore, nextCursor }واحدًا. - تعيد
roles list-permissionsوlanguages listوtemp-mail list-domainsوtemp-mail list-attachmentsكل شيء دفعة واحدة، في مصفوفة عادية، دون صفحات. - يخرج الرفض برمز حالته:
3لـ 401، مثل مفتاح مبطَل، و4لـ 403، مثلbeyond_caller_authorityأوowner_only، و5لـ 404، و6لـ 409، مثلnot_revokedأوrole_in_useأوinvitation_too_soon، و7لـ 400 أو 422، مثلmember_is_ownerأوrole_limit_reached، و8لـ 429، مثلtoo_many_inboxes. - التغيير الذي قد يفعل شيئًا مرتين لا يُعاد أبدًا بعد فشل في الشبكة:
keys createوrotate، وme rotate، وroles createوdelete، وmembers addوremoveوrevoke-addressوresend-invitation، وtemp-mail createوextendوdeleteوdelete-message. تحقّق قبل أن تشغّل أحدها من جديد. أما القراءات، والتغييرات التي تنتهي إلى النتيجة نفسها مرتين، مثلkeys updateوkeys revokeوroles updateوmembers updateوgrant-address، فتُعاد تلقائيًا.