الملفات والاستيراد والإعدادات
كل أمر للملفات التي يضمها صندوق البريد، واستيراد صندوق بريد قديم أو حساب 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بـ 409file_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، والبرنامج أو السكربت (حسب اسمه) يعطي 400upload_dangerous، والملف الذي يتجاوز 100 MB يعطي 413upload_too_large. وتحتفظ مساحة العمل بما يصل إلى 10 GB من الملفات المرفوعة وتقبل 500 عملية رفع في الساعة. - يحتاج
downloadإلى--out <file>في الطرفية ويتوقف برمز الخروج2دونه. وعند التمرير عبر أنبوب تذهب البايتات إلى stdout، ويطلب--out -الإخراج إلى stdout أيضًا. ويُحتفظ بالملف كله في الذاكرة. - ينشئ
create-linkرابطًا جديدًا في كل استدعاء، بعدّاد تنزيل خاص به، ويعمل الرابط حتى يُبطَل أو يُحذف الملف. ويقع على نطاق الملفات الخاص بـ--domainحين يكون لذلك النطاق واحد، مثلfiles.acme.com، وإلا فعلى نطاق الملفات الخاص بعنوان الملف، وإلا فعلى عنوان API. والبرنامج أو السكربت يُرفض بـ 422file_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بالضبط، عدا الجزء الأخير من الملف، والجزء ذو الطول الخاطئ يعطي 400bad_chunk. ويرفضstartالملف الذي تنقصه أجزاء بـ 412missing_chunks، والملف الذي ليس أرشيفًا ولا صندوق بريد بـ 400unsupported_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على استيراد منتهٍ يعطي 409not_cancellable. ويلغيdelete-uploadاستيرادًا لا يزال يُرفع، ويرفض الاستيراد الذي في الطابور أو قيد التشغيل بـ 409still_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 يومًا على الأكثر، لأن السلسلة المتكررة لا نهاية لها يُسرد حتى بلوغها. والحد الناقص يعطي 422invalid_parameter. والحد الذي لا يُحلَّل، أو الفترة المعكوسة أو المفرطة الطول، أو المنطقة الزمنية المجهولة، يعطي 400invalid_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بـ 422address_requiredولا يكتب شيئًا. ومعه لا يأخذupdateإلا تلك الأربعة، وأي شيء آخر يعطي 422not_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. وتُسقط المفاتيح التي لا تعرفها الإعدادات دون خطأ، والمفتاح المعروف بنوع خاطئ يعطي 422invalid_parameter. - القائمة مثل
blockedDomainsتُستبدل كلها، لذا اقرأها أولًا وأرسلها مع تغييرك، كما يفعل المثال أدناه. ومدخلة قائمة الحظر الأقصر من أن تكون قاعدة تعطي 422blocklist_entry_too_broad. - يُحفظ
--timezoneو--languageكما أُعطيا، دون فحص، لذا تحقّق من المنطقة أو رمز اللغة قبل إرساله. - حقول الخصوصية،
externalImagesوtrustedSendersوblockedSendersوblockedDomainsوblockedWordsوuseDefaultBlockedWords، ملك لمساحة العمل. والمفتاح أو تسجيل الدخول المقيّد بعناوين أو نطاقات معيّنة لا يستطيع تغييرها، ولا يجوز له أن يسمّي في--addressإلا عنوانًا يحمله، أو catch-all على نطاق يحمله كاملًا. وكلا الرفضين 422capability_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 للصفحة التالية.
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.icsopenemail 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:read | files list, get, stats, download, list-links |
| files:write | files create-link, revoke-link, upload, delete, delete-many |
| threads:read | imports list, get, list-failures |
| threads:write | imports create, upload-state, upload-chunk, start, cancel, delete-upload, import-files |
| settings:read | provider-imports list وget، وsettings get |
| settings:write | provider-imports inspect وcreate وcancel، وsettings update |
| calendar:read | calendar 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من الصفحة السابقة، و--limit100 على الأكثر، وهي القيمة الافتراضية، ولا يوجد--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.