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

الملفات والاستيراد والإعدادات

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

نظرة عامة

خمس مساحات أسماء تغطي ما يحيط بالبريد نفسه. openemail files هي صفحة الملفات: كل مرفق أُرسل واستُقبل وكل ملف رُفع، ببايتاته وروابط التنزيل التي خرج بها. ويجلب openemail imports صندوق بريد قديمًا إلى عنوان واحد، ويجلب openemail provider-imports حساب Resend. ويقرأ openemail calendar الأحداث المستخرجة من البريد، ويقرأ openemail settings تفضيلات صندوق البريد ويغيّرها، وكذلك توقيع كل عنوان وتتبعه.

  • المعرّف يقول ما يسمّيه: file_ للملف، وimp_ لاستيراد صندوق بريد، وpimp_ لاستيراد Resend، وcal_ لحدث تقويم، يلي كلًّا منها 24 حرفًا ست عشريًا. ولرابط التنزيل معرّف خاص به، من files list-links أو files create-link.
  • --address-id في الاستيراد هو معرّف عنوان، من openemail domains list-addresses <id>، لا العنوان نفسه.
  • تستجيب مساحات الأسماء أيضًا لـ file وimport وprovider-import أو providerImports وsetting. وتأخذ الأفعال الأسماء البديلة المعتادة حيث تتوفر: ls بدلًا من list، وshow وview بدلًا من get، وnew وadd بدلًا من create، وedit بدلًا من settings update، وrm وdel وremove بدلًا من files delete.
  • لا يطلب أي من هذه الأوامر رمز تحقق من تسجيل الدخول عبر المتصفح. وتلك التي تغيّر شيئًا نهائيًا تطلب منك التأكيد، ويجيب --yes عن السكربت.
  • يسرد openemail <command> --help كل وسيط وخيار بنوعه، والنطاق الذي يحتاجه الاستدعاء، وطريقته ومساره، وما يعود. أضف --json لتحصل على الصفحة نفسها في صورة بيانات.

الملفات

يقرأ openemail files كل ملف يضمه صندوق البريد ويديره: المرفقات الواردة، والمرفقات الصادرة، والملفات المرفوعة إلى صفحة الملفات. ويفتح openemail open files الصفحة نفسها في تطبيق الويب.

الأمرما تفعله
openemail files listاسرد صفحة واحدة من الملفات بالاسم والنوع والحجم والاتجاه والعنوان الذي وصل إليه كل منها وما إذا كان يمكن حذفه
openemail files get <id>اقرأ ملفًا واحدًا، مع المحادثة والرسالة اللتين ينتمي إليهما، وusage وdeletable الخاصين به
openemail files statsاحسب الملفات والبايتات التي تشغلها، مقسمة إلى مستلمة ومرسلة ومرفوعة، مع أعلى الأنواع والعناوين، وآخر 30 يومًا، والروابط التي لا تزال تعمل
openemail files download <id>اجلب بايتات ملف كما خُزّنت بالضبط، إلى --out <file> أو إلى stdout عند التمرير عبر أنبوب
openemail files list-links <id>اسرد روابط التنزيل التي خرج بها ملف، الأحدث أولًا، مع عدد مرات جلب كل منها وما إذا أُبطل
openemail files create-link <id>انشر الملف على رابط تنزيل عام جديد يُفتح دون تسجيل دخول
openemail files revoke-link <id> <link-id>أوقف رابطًا عامًا نهائيًا، في البريد المرسل بالفعل أيضًا. يطلب منك التأكيد
openemail files upload <data>ارفع ملفًا من مسار، أو من stdin عبر -، حتى 100 MB
openemail files delete <id>احذف ملفًا مرفوعًا لا يعتمد عليه شيء، نهائيًا. يطلب منك التأكيد
openemail files delete-many <ids...>احذف حتى 100 ملف في استدعاء واحد وأبلغ عن المحتفَظ بها وغير الموجودة. يطلب منك التأكيد
  • يضيّق files list بـ --q (الاسم والنوع)، و--kind (image أو pdf أو audio أو video أو text)، و--direction (inbound أو outbound أو uploaded)، و--address و--since و--until، ويرتّب بـ --sort (newest أو oldest أو largest أو name). ويأخذ --since و--until تاريخًا أو تاريخًا ووقتًا بصيغة ISO 8601: يشمل --since لحظته ويتوقف --until قبلها.
  • لا يمكن حذف إلا الملف المرفوع الذي لا يعتمد عليه شيء، وتقول deletable ذلك مسبقًا. وتقول usage ما يُبقي أي ملف آخر: received أو sent أو linked لملف مرفوع لا يزال رابط تنزيله يعمل، أو scheduled لملف مرفق برسالة لم تخرج بعد. ويرفضها delete بـ 409 file_in_use. ويحذف delete-many ما يستطيع، ويسرد البقية في kept مع سبب لكل منها، ويسرد المعرّفات المجهولة في missing.
  • يقرأ upload الملف في المسار الذي تعطيه ويخزنه باسم ذلك الملف، بالنوع الذي يدل عليه امتداده. ويتجاوزهما --filename و--content-type. ومن stdin يحتاج - إلى --filename، ودون --content-type يكون النوع application/octet-stream. وينتظر الرفع حتى 10 دقائق، وهو ما يغيّره --timeout-ms.
  • المعرّف الذي يعيده upload يرفق الملف بإرسال بصيغة { "fileId": "…" } في openemail emails send --attachments، وهكذا يخرج الملف الذي يتجاوز حد 5 MB المضمَّن.
  • الملف الفارغ يعطي 400 upload_empty، والبرنامج أو السكربت (حسب اسمه) يعطي 400 upload_dangerous، والملف الذي يتجاوز 100 MB يعطي 413 upload_too_large. وتحتفظ مساحة العمل بما يصل إلى 10 GB من الملفات المرفوعة وتقبل 500 عملية رفع في الساعة.
  • يحتاج download إلى --out <file> في الطرفية ويتوقف برمز الخروج 2 دونه. وعند التمرير عبر أنبوب تذهب البايتات إلى stdout، ويطلب --out - الإخراج إلى stdout أيضًا. ويُحتفظ بالملف كله في الذاكرة.
  • ينشئ create-link رابطًا جديدًا في كل استدعاء، بعدّاد تنزيل خاص به، ويعمل الرابط حتى يُبطَل أو يُحذف الملف. ويقع على نطاق الملفات الخاص بـ --domain حين يكون لذلك النطاق واحد، مثل files.acme.com، وإلا فعلى نطاق الملفات الخاص بعنوان الملف، وإلا فعلى عنوان API. والبرنامج أو السكربت يُرفض بـ 422 file_unshareable.
  • تكرار revoke-link آمن: الرابط المبطَل بالفعل يعود دون تغيير.
  • المفتاح أو تسجيل الدخول المقيّد بعناوين أو نطاقات معيّنة لا يرى إلا الملفات التي وصلت إليها، ولا يرى أبدًا الملفات المرفوعة لمساحة العمل كلها، وملفاته المرفوعة تنتمي إلى أول عنوان يحمله.
  • يبدأ فهرس الملفات من يوم إطلاقه. والمرفقات الأقدم لا تزال على رسائلها، حيث يقرؤها openemail threads list-attachments <id>.

استيراد صناديق البريد

يجلب openemail imports صندوق بريد قديمًا إلى عنوان واحد: أرشيفات Google Takeout، وملفات .mbox من Apple Mail وThunderbird ومعظم تطبيقات سطح المكتب، وملفات .eml، وأرشيفات .zip أو .tgz التي تضم أيًّا منها، حتى 100 GB للملف و50 ملفًا للاستيراد. تنتقل المحادثات والتواريخ والتسميات. والبريد المستورد هادئ: لا يشغّل قواعد ولا إعادات توجيه ولا إشعارات ولا ملخصات ولا خطافات ويب.

import-files هو ما يحتاجه معظم الناس: ينشئ الاستيراد، ويرفع كل ملف على أجزاء مع سطر تقدّم، ويبدؤه. والأفعال الأخرى هي تلك الخطوات واحدة واحدة، لإكمال رفع توقف أو لتقوده بنفسك. يعيد create الخطة وchunkBytes وchunks لكل ملف، ويرسل upload-chunk جزءًا واحدًا، ويقول upload-state أي الأجزاء وصلت، ويضع start الاستيراد في الطابور. ويعرض openemail open imports عمليات الاستيراد نفسها في تطبيق الويب.

الأمرما تفعله
openemail imports listاسرد صفحة واحدة من عمليات الاستيراد في مساحة العمل، الأحدث أولًا، مع الحالة والبايتات المقروءة والأعداد. ويُبقي --address-id عنوانًا واحدًا
openemail imports get <id>اقرأ استيرادًا واحدًا مع حالته وتقدّمه وأعداده. استطلعه حتى يصبح completed أو failed أو cancelled
openemail imports create --address-id <value> --files <json|@file|->أنشئ استيرادًا من قائمة { name, bytes } واحصل على خطة رفعه، مع status بالقيمة uploading
openemail imports upload-state <id>لكل ملف، فهارس الأجزاء المخزنة بالفعل، كي لا يرسل الرفع المتوقف إلا ما ينقص
openemail imports upload-chunk <id> <file> <chunk> <data>ارفع جزءًا واحدًا من ملف واحد، من مسار أو من stdin عبر -. وإرسال جزء مرة أخرى يستبدله
openemail imports start <id>تحقّق من وصول كل جزء، وتعرّف على صيغة كل ملف، وضع الاستيراد في الطابور
openemail imports cancel <id>أوقف الاستيراد عند نقطة التحقق التالية. ويبقى البريد المستورد بالفعل. يطلب منك التأكيد
openemail imports list-failures <id>اسرد كل رسالة أو مدخلة أرشيف لم تنتقل، مع السبب
openemail imports delete-upload <id>احذف الملفات المرفوعة. ويبقى البريد المستورد بالفعل. يطلب منك التأكيد
openemail imports import-files --address-id <value> --files <path>أنشئ استيرادًا وارفعه وابدأه بأمر واحد، ويعود حين يوضع في الطابور
  • يجب أن يكون العنوان واحدًا من نطاقات مساحة العمل نفسها ويجوز للمفتاح أو تسجيل الدخول التصرف باسمه. ولا يعمل إلا استيراد واحد لكل عنوان: وآخر بينما واحد في الطابور أو قيد التشغيل يعطي 409 already_running.
  • يأخذ import-files الخيار --files مرة لكل ملف، أو عدة مسارات تفصل بينها فواصل، ويرسل كلًّا منها باسم ملفه. ويأخذ --options قيمة JSON مثل {"keepInbox":false,"includeSpam":true}. وفي create تكون الثلاثة نفسها مفاتيح: --options-keep-inbox و--options-include-spam و--options-include-trash، ويُطفأ كل منها بـ --no- أمامه، كما في --no-options-keep-inbox.
  • keepInbox مفعّل افتراضيًا، فيصل بريد الوارد القديم إلى الوارد بحالة عدم قراءته. وإيقافه يرتّب كل شيء تحت الأرشيف. ويبقى البريد العشوائي والمهملات خلفًا ما لم تضمّنهما.
  • يأخذ create الخيار --files بصيغة JSON، مضمّنًا أو من ملف عبر @path، ويجب أن تكون كل bytes الحجم الدقيق للملف الذي سترفعه بعد ذلك.
  • طول كل جزء chunkBytes بالضبط، عدا الجزء الأخير من الملف، والجزء ذو الطول الخاطئ يعطي 400 bad_chunk. ويرفض start الملف الذي تنقصه أجزاء بـ 412 missing_chunks، والملف الذي ليس أرشيفًا ولا صندوق بريد بـ 400 unsupported_file. وعلى استيراد غادر uploading بالفعل يعيد الاستيراد دون تغيير.
  • إذا ظل جزء يفشل بعد إعادات محاولته، يتوقف import-files تاركًا الاستيراد في uploading. والكتلة أدناه ترسل الأجزاء الناقصة من الملف الأول وتبدؤه.
  • يبلّغ الاستيراد عن processedBytes من أصل totalBytes، وعن counts مع seen وimported وduplicate وfiltered وfailed وthreads. ولا تُضبط lastError إلا حين تكون status بالقيمة failed.
  • يعطي list-failures كل فشل reason: too-large (أكثر من 50 MB)، أو unparseable، أو no-date، أو storage-error، أو unreadable-entry، أو encrypted-entry، أو archive-limit، مع الموضوع والمرسل حيث أمكنت قراءتهما.
  • cancel على استيراد منتهٍ يعطي 409 not_cancellable. ويلغي delete-upload استيرادًا لا يزال يُرفع، ويرفض الاستيراد الذي في الطابور أو قيد التشغيل بـ 409 still_running، فألغِه أولًا.
إكمال رفع توقف
openemail imports get "$import_id" --json > import.jsonopenemail imports upload-state "$import_id" --json > state.jsonchunk=$(jq .chunkBytes import.json)chunks=$(jq '.files[0].chunks' import.json)for i in $(seq 0 $((chunks - 1))); do  jq -e --argjson i "$i" '.received[0] | any(. == $i)' state.json > /dev/null && continue  dd if=takeout-001.zip bs="$chunk" skip="$i" count=1 2> /dev/null |    openemail imports upload-chunk "$import_id" 0 "$i" -doneopenemail imports start "$import_id"

الاستيراد من Resend

ينقل openemail provider-imports مساحة عمل من Resend بمفتاح API واحد كامل الصلاحية من Resend. تحتفظ عناصر المنع بسببها، وتصبح الشرائح جماهير، وتصل جهات الاتصال المشتركة بأسمائها، وتصل القوالب قوالبَ HTML مع التصريح بمتغيراتها. وتُسجَّل خطافات الويب معطّلة، لأن التسليمات هنا موقّعة بطريقة مختلفة. ولا يمكن لمفتاح توقيع أو رمز أن يغادر Resend، لذا تعود النطاقات ومفاتيح API قائمةَ تحقق في التقرير بدلًا من ذلك.

الأمرما تفعله
openemail provider-imports inspect <api-key>احسب ما يضمه حساب Resend، لكل مورد، قبل الاستيراد. لا يُخزَّن شيء ولا يُحتفظ بالمفتاح
openemail provider-imports create --resend-key <value> --resources <a,b>ضع في الطابور استيرادًا للموارد التي تسمّيها
openemail provider-imports listاسرد صفحة واحدة من عمليات الاستيراد من مزوّدي الإرسال، الأحدث أولًا، لكل منها تقريرها
openemail provider-imports get <id>اقرأ استيرادًا واحدًا: حالته، والخطوة التي بلغها، والتقرير حتى الآن
openemail provider-imports cancel <id>أوقف الاستيراد وامحُ مفتاح Resend. ويبقى ما انتقل بالفعل. يطلب منك التأكيد
  • مرّر مفتاح Resend بصيغة @path لقراءته من ملف، أو - لقراءته من stdin، كي يبقى خارج سجل الصدفة وقائمة العمليات. والمفتاح المكتوب في سطر الأوامر يظل يعمل، مع تحذير. ويطبع --dry-run الجسم مع حجب المفتاح.
  • يأخذ --resources أيًّا من suppressions وaudiences وcontacts وtemplates وwebhooks وdomains وapi-keys، مفصولة بفواصل أو مكررة.
  • المفتاح المقتصر على الإرسال يعطي 400 restricted_key. أنشئ مفتاحًا كامل الصلاحية في Resend للاستيراد، وأبطله بعد ذلك.
  • يقرأ inspect الصفحة الأولى من كل مورد ويعيد counts، أي { count, more } لكل مورد، مع ضبط more حيث يتجاوز المورد صفحته الأولى.
  • لا يعمل إلا استيراد واحد لكل مساحة عمل في الوقت نفسه، والثاني يعطي 409 already_running. وتشغيل الاستيراد نفسه مرتين لا يكرر شيئًا. ويُحتفظ بالمفتاح مشفَّرًا فقط ما دام الاستيراد يعمل، ويُمحى حين ينتهي أو يفشل أو يُلغى.
  • تُستبعد جهات الاتصال التي ألغت اشتراكها في Resend وتُحتسب في report.contacts.unsubscribed.
  • تسرد report.domains كل نطاق من Resend مع state: absent حين لا يكون في مساحة العمل هذه، وadded حين يكون فيها لكنه غير متحقَّق منه، وverified، مع السجلات التي كانت له في Resend. أضف الناقص بـ openemail domains create. وتسمّي report.apiKeys المفاتيح التي يجب إنشاؤها من جديد بـ openemail keys create.
  • مع تسجيل الدخول عبر المتصفح لا يستطيع استخدام هذه الأوامر إلا مالك مساحة العمل، ويحصل العضو على 403 owner_only. ولا يخضع مفتاح API لذلك. والمفتاح أو تسجيل الدخول المقيّد بعناوين أو نطاقات معيّنة لا يستطيع فحص استيراد أو إنشاءه، لأن الجماهير وقائمة المنع والقوالب ملك لمساحة العمل كلها.
  • يحتاج create أيضًا إلى نطاق كل مورد يجلبه: audiences:write للجماهير، وcontacts:write وaudiences:write لجهات الاتصال، وtemplates:write للقوالب، وwebhooks:write لخطافات الويب، وdomains:read للنطاقات.

التقويم

يقرأ openemail calendar أحداث التقويم المستخرجة من البريد. والأوامر الثلاثة كلها للقراءة فقط. يوسّع list-events كل حدث إلى تكراراته ضمن فترة تعطيها، فيكون الاجتماع الأسبوعي صفًا لكل أسبوع، ويقرأ get-event وget-event-ics حدثًا واحدًا كاملًا. ويفتح openemail open calendar التقويم في تطبيق الويب.

الأمرما تفعله
openemail calendar list-events --from <when> --to <when>اسرد صفحة واحدة من التكرارات بين لحظتين، مرتبة بوقت البدء، يشير كل منها إلى حدثه عبر eventId
openemail calendar get-event <id>اقرأ حدثًا مع حضوره وأجوبتهم، وقاعدة تكراره، والتواريخ المستثناة، والمنظِّم، والتذكيرات
openemail calendar get-event-ics <id>نزّل الحدث كمستند iCalendar، مطبوعًا أو مكتوبًا في --out <file>
  • --from و--to تاريخان ووقتان بصيغة ISO 8601 مثل 2026-10-01T00:00:00Z. ويجب أن يكون --to بعد --from وبعده بـ 366 يومًا على الأكثر، لأن السلسلة المتكررة لا نهاية لها يُسرد حتى بلوغها. والحد الناقص يعطي 422 invalid_parameter. والحد الذي لا يُحلَّل، أو الفترة المعكوسة أو المفرطة الطول، أو المنطقة الزمنية المجهولة، يعطي 400 invalid_parameter.
  • --timezone منطقة IANA مثل Europe/London، وUTC حين يُغفل. وهو يوسّع الأحداث المخزنة دون منطقة خاصة بها، وهذا ما يحدد اليوم الذي يقع فيه حدث يستغرق اليوم كله.
  • يأخذ get-event وget-event-ics قيمة eventId لتكرار، لا uid الخاص بـ iCalendar. والسلسلة المتكررة حدث واحد، لذا يصف start وend الخاصان بها المثيل الأول.
  • تُسرد الأحداث الملغاة أيضًا، مع status بالقيمة CANCELLED. وmyPartstat هو الجواب المسجل لأي عنوان تحمله مساحة العمل على نطاقاتها الخاصة، وتكون null حين لا يكون أي منها بين الحضور.
  • يتواصل التصفح بـ --cursor والفترة نفسها. والمفتاح أو تسجيل الدخول المقيّد بعناوين معيّنة لا يرى إلا الأحداث التي ينظّمها أحدها أو يحضرها، وأي حدث آخر يعطي 404.
  • يعلن get-event-ics عن METHOD:PUBLISH، لذا يعرض استيراده الحدث كما هو بدلًا من عرض قبوله أو رفضه. وتُكتب الأحداث المؤقتة كلحظات UTC والأحداث التي تستغرق اليوم كله كتواريخ. وDTSTAMP هو وقت التنزيل، لذا يختلف تنزيلان لحدث لم يتغير في ذلك السطر.

الإعدادات

يقرأ openemail settings تفضيلات صندوق البريد ويغيّرها، مثل المنطقة الزمنية واللغة وتنسيق الوقت وقوائم الحظر. وأربعة إعدادات تخص العنوان لا مساحة العمل: signature وopenEmailSignature (تذييل OpenEmail) وtrackOpens وtrackClicks. سمِّ العنوان بـ --address، أو *@acme.com لـ catch-all نطاق.

الأمرما تفعله
openemail settings getاقرأ كل إعداد مع ملء القيم الافتراضية. ومع --address تُقرأ الإعدادات الأربعة الخاصة بالعنوان كما يحلّها إرسال من ذلك العنوان
openemail settings updateغيّر الإعدادات التي تمرّرها واحتفظ بالباقي. والجواب هو كل إعداد، مقروءًا بعد الكتابة
  • دون --address يقرأ get الإعدادات الأربعة الخاصة بالعنوان على أنها القيم الافتراضية المدمجة: لا توقيع، وتذييل OpenEmail مفعّل، وتتبع الفتح والروابط مفعّل. ومعه تأتي من قيم العنوان نفسه، ثم من catch-all نطاقه حين يكون catch-all قد التقط ذلك العنوان، ثم من القيم الافتراضية. والعنوان ذو علامة الزائد الذي لا إعدادات خاصة به يقرأ إعدادات عنوانه الأساسي.
  • دون --address يرفض update كلًّا من --signature و--open-email-signature و--track-opens و--track-clicks بـ 422 address_required ولا يكتب شيئًا. ومعه لا يأخذ update إلا تلك الأربعة، وأي شيء آخر يعطي 422 not_per_address. ويجب أن يكون العنوان في مساحة العمل هذه، أو *@domain لنطاق متحقَّق منه هنا مع تشغيل catch-all.
  • تُطفأ المفاتيح بـ --no- أمامها: --no-open-email-signature و--no-track-opens و--no-track-clicks.
  • --signature هو HTML لا يتجاوز 150,000 حرف، يُنقّى عند الكتابة، فما يعود هو ما سيُرسل. والسلسلة الفارغة تزيله. أما إضافته في الإرسال فأمر يعود إلى الإرسال: انظر --signature في openemail emails send --help.
  • تغطي الخيارات الحقول الشائعة. ويأخذ --data أي إعداد مخزن بصيغة JSON، مضمّنًا، أو من ملف عبر @path، أو من stdin عبر -، مثل timeFormat وweekStart وundoSendEnabled وblockedSenders وblockedDomains. وتُسقط المفاتيح التي لا تعرفها الإعدادات دون خطأ، والمفتاح المعروف بنوع خاطئ يعطي 422 invalid_parameter.
  • القائمة مثل blockedDomains تُستبدل كلها، لذا اقرأها أولًا وأرسلها مع تغييرك، كما يفعل المثال أدناه. ومدخلة قائمة الحظر الأقصر من أن تكون قاعدة تعطي 422 blocklist_entry_too_broad.
  • يُحفظ --timezone و--language كما أُعطيا، دون فحص، لذا تحقّق من المنطقة أو رمز اللغة قبل إرساله.
  • حقول الخصوصية، externalImages وtrustedSenders وblockedSenders وblockedDomains وblockedWords وuseDefaultBlockedWords، ملك لمساحة العمل. والمفتاح أو تسجيل الدخول المقيّد بعناوين أو نطاقات معيّنة لا يستطيع تغييرها، ولا يجوز له أن يسمّي في --address إلا عنوانًا يحمله، أو catch-all على نطاق يحمله كاملًا. وكلا الرفضين 422 capability_unsupported.
  • التحديث الذي لا شيء فيه لا يغيّر شيئًا ويعيد الإعدادات الحالية. ولا يفعل defaultEmailAlias سوى تحديد عنوان From مسبقًا في محرّر رسائل تطبيق الويب، ولا تستخدمه API أبدًا لاختيار مرسل.

أمثلة

ارفع ملفًا وشاركه برابط
file_id=$(openemail files upload ./price-list.pdf --json | jq -r .id)openemail files create-link "$file_id" --domain acme.com --json | jq -r .urlopenemail files list-links "$file_id"openemail files download "$file_id" --out copy.pdf

كل create-link ينشئ رابطًا جديدًا، لذا شغّله مرة واحدة واقرأ الرابط من جديد بـ list-links. ويوقفه revoke-link لاحقًا، في البريد الذي خرج بالفعل أيضًا.

تخلّص من كل ملف مرفوع لا يستخدمه شيء
openemail files list --direction uploaded --all | jq -r 'select(.deletable) | .id' > deletable.txtwc -l < deletable.txtxargs -r -n 100 openemail files delete-many --yes --json < deletable.txt | jq -c '.kept[]'

مع --all في أنبوب، يطبع files list ملفًا واحدًا في كل سطر. ويسلّم xargs -n 100 الأمر delete-many 100 معرّف على الأكثر في كل استدعاء، وأي ملف صار مستخدمًا في الأثناء يعود في kept مع سببه بدلًا من إفشال الاستدعاء.

استورد صندوق بريد قديمًا وتابعه
domain_id=$(openemail domains list --all | jq -r 'select(.domain == "acme.com") | .id')address_id=$(openemail domains list-addresses "$domain_id" --all | jq -r 'select(.address == "[email protected]") | .id')openemail imports import-files --address-id "$address_id" --files ~/Downloads/takeout-001.zip --files ~/Downloads/takeout-002.zip --json > import.jsonimport_id=$(jq -r .id import.json)until openemail imports get "$import_id" --json | jq -e '.status != "queued" and .status != "running"' > /dev/null; do  sleep 60doneopenemail imports get "$import_id" --json | jq '{status, counts, lastError}'openemail imports list-failures "$import_id" --json | jq -r '.data[] | [.reason, .subject] | @tsv'

يطبع --dry-run في import-files الطلب POST /imports الذي كان سيرسله، مع اسم كل ملف وحجمه، ولا يرفع شيئًا. ويقرأ list-failures 100 في كل مرة: مرّر nextCursor الذي طبعه بوصفه --after للصفحة التالية.

الانتقال من Resend
openemail provider-imports inspect @resend-key.txtopenemail provider-imports create --resend-key @resend-key.txt --resources suppressions,audiences,contacts,templates,webhooks,domains,api-keys --json > resend.jsonpimp_id=$(jq -r .id resend.json)until openemail provider-imports get "$pimp_id" --json | jq -e '.status != "queued" and .status != "running"' > /dev/null; do  sleep 10doneopenemail provider-imports get "$pimp_id" --json | jq '.report | {contacts, domains: [.domains[] | {name, state}], apiKeys: [.apiKeys[].name]}'
قراءة شهر من الاجتماعات
openemail calendar list-events --from 2026-10-01T00:00:00Z --to 2026-11-01T00:00:00Z --timezone Europe/London --all |  jq -r 'select(.status != "CANCELLED") | [.start, .summary, .myPartstat] | @tsv'openemail calendar get-event cal_8d3f0a2b9c4e41f7a6b5c2d1 --json | jq '.attendees[] | {email, partstat}'openemail calendar get-event-ics cal_8d3f0a2b9c4e41f7a6b5c2d1 --out standup.ics
التوقيع والتتبع وقائمة الحظر
openemail settings get --address [email protected] --json | jq '{signature, openEmailSignature, trackOpens, trackClicks}'openemail settings update --address [email protected] --signature "$(cat signature.html)" --no-track-clicks --dry-runopenemail settings update --address [email protected] --signature "$(cat signature.html)" --no-track-clicksopenemail settings update --address '*@acme.com' --no-track-opensopenemail settings update --timezone Europe/London --language enopenemail settings get --json | jq -c '{blockedDomains: ((.blockedDomains + ["spam.example"]) | unique)}' |  openemail settings update --data -

يطبع التشغيل التجريبي PATCH /settings?address=sales%40acme.com وجسمه دون إرساله. ويضبط سطر catch-all التتبع لكل عنوان يلتقطه catch-all الخاص بـ acme.com، ويضيف السطر الأخير نطاقًا واحدًا إلى قائمة الحظر دون إسقاط البقية.

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

النطاقالأوامر
files:readfiles list, get, stats, download, list-links
files:writefiles create-link, revoke-link, upload, delete, delete-many
threads:readimports list, get, list-failures
threads:writeimports create, upload-state, upload-chunk, start, cancel, delete-upload, import-files
settings:readprovider-imports list وget، وsettings get
settings:writeprovider-imports inspect وcreate وcancel، وsettings update
calendar:readcalendar list-events, get-event, get-event-ics
  • تسجيل الدخول أو المفتاح الذي لا يملك النطاق يتوقف برمز الخروج 4، ويسمّي النطاق الناقص ويقول كيف تحصل عليه.
  • تطلب files revoke-link وfiles delete وfiles delete-many وimports cancel وimports delete-upload وprovider-imports cancel منك التأكيد. والإجابة بلا تخرج بالرمز 10 ولا تغيّر شيئًا. ومن دون إشراف ودون --yes تتوقف برمز الخروج 2 قبل إرسال أي شيء.
  • لا يطلب أي أمر هنا رمز تحقق، سواء مع تسجيل الدخول عبر المتصفح أو مع مفتاح API، لذا فإن --yes هو كل ما يحتاجه السكربت.
  • يطبع --dry-run الطلب الذي كان التغيير سيرسله، مع جسمه، ويخرج بالرمز 0 دون إرساله أو طلب التأكيد منك. ويُعرض جسم الملف بحجمه ونوعه.
  • تقرأ files list وfiles list-links وimports list وprovider-imports list وcalendar list-events صفحة واحدة: يأخذ --limit من 1 إلى 100 ويرسل الخادم 25 حين يُغفل، ويأخذ --cursor قيمة nextCursor من الصفحة السابقة. ويقرأ --all كل صفحة، ويتوقف --max <n> بعد هذا العدد من العناصر، ويطبع --ndjson، أو --all في أنبوب، كائن JSON واحدًا في كل سطر. ومع --json تطبع مستند { items, hasMore, nextCursor } واحدًا.
  • يتصفح imports list-failures بطريقته الخاصة: يأخذ --after قيمة nextCursor من الصفحة السابقة، و--limit 100 على الأكثر، وهي القيمة الافتراضية، ولا يوجد --all. ومع --json يطبع { object, data, nextCursor }.
  • تُعاد القراءات والتغييرات التي تنتهي إلى النتيجة نفسها مرتين بعد فشل في الشبكة: files revoke-link وimports upload-chunk وimports start وsettings update. وكل تغيير آخر يُرسل مرة واحدة. وبعد ضياع الجواب، تحقّق قبل المحاولة من جديد: فـ upload الثاني يخزّن نسخة ثانية، وcreate-link الثاني ينشئ رابطًا ثانيًا، و404 في files delete الثاني يعني أن الأول نجح، وdelete-many الثاني يسرد في missing ما حذفه الأول.
  • يخرج الرفض برمز حالته: 4 لـ 403، و5 لـ 404، و6 لـ 409، و7 لـ 400 أو 422، و8 لـ 429.

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

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

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

OpenEmail

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

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