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

جهات الاتصال والجماهير والبث

كل أمر لدفتر العناوين والجماهير والبث وقائمة المنع، مع أمثلة تطبيقية.

كيف تترابط

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

  • جهة الاتصال بلا معرّف. عنوانها هو المفتاح الذي يأخذه كل أمر contacts، بعد تقليم المسافات وتحويله إلى أحرف صغيرة، فـ [email protected] و[email protected] جهة اتصال واحدة. وللجمهور معرّف aud_، وللبث معرّف brd_، وللمنع المعرّف الذي يطبعه suppressions list.
  • كل جهة اتصال موجودة في الجمهور الافتراضي ما دامت قائمة. ولا يمكن حذف ذلك الجمهور ولا إفراغه ولا إنقاصه، وقيمة builtin فيه default.
  • دفتر العناوين ملك لمساحة العمل، لذا يقرأ كل عضو وكل مفتاح الدفتر نفسه ويكتب فيه.
  • تستجيب كل مساحة أسماء أيضًا لصيغة المفرد، كما في openemail contact get، وتعمل الأسماء البديلة المعتادة: ls وshow وnew وedit وrm. وفي suppressions، التي أفعالها add وremove، يقود new إلى add وrm إلى remove.

يعرض openemail <namespace> <verb> --help كل خيار بنوعه، والنطاقات، ونقطة النهاية، وما يعيده الأمر. أضف --json لتحصل على الصفحة نفسها في صورة بيانات.

جهات الاتصال

دفتر عناوين مساحة العمل: الأشخاص الذين كتب إليهم عضو من محرّر الرسائل في التطبيق، إضافة إلى كل من حُفظ يدويًا. البريد الوارد لا يضيف أحدًا، ولا الإرسال عبر API أو CLI.

الأمرما تفعله
openemail contacts listصفحة واحدة من جهات الاتصال المحفوظة، الأحدث مراسلة أولًا. يُبقي --source جهات الاتصال manual أو auto، ويبحث --q في الأسماء والعناوين
openemail contacts get <email>جهة اتصال واحدة، مع كل جمهور تنتمي إليه
openemail contacts create --email <value>احفظ جهة اتصال جديدة، مع --name و--notes و--audience-ids. والعنوان الموجود بالفعل في الدفتر يُرفض بـ 409 contact_exists
openemail contacts update <email>غيّر --name أو --notes، حيث تمسح null أيًّا منهما. ولا يمكن تغيير العنوان نفسه
openemail contacts delete <email>احذف جهة الاتصال مع ملاحظاتها وصورتها وعضوياتها، وأخفِ العنوان كي لا يسجله محرّر الرسائل من جديد
openemail contacts set-audiences <email> --audience-ids <a,b>اجعل الجماهير التي تنتمي إليها جهة الاتصال هذه القائمة بالضبط. ويُحتفظ دائمًا بالجمهور الافتراضي
openemail contacts list-peopleكل من في صفحة جهات الاتصال: جهات الاتصال المحفوظة، ومع threads:read كل عنوان ظهر في البريد، مع أعداد المحادثات. ويضيّقها --sort و--q و--email و--blocked
openemail contacts save <email>احفظ عنوانًا، أو أبقِ عنوانًا سُجّل من إرسال، أو أعِد عنوانًا محذوفًا. لا يعطي خطأ أبدًا، أيًّا كانت حالة العنوان
openemail contacts delete-many <emails...>احذف من 1 إلى 200 عنوان وأخفِها في استدعاء واحد
openemail contacts set-photo <email> <data>ارفع الصورة من ملف، أو من stdin عبر -: PNG أو JPEG أو WebP أو GIF حتى 5 MB
openemail contacts remove-photo <email>أزل الصورة واحذف الصورة المخزنة
openemail contacts block <email>ضع العنوان في قائمة حظر مساحة العمل، فيُرفض البريد القادم منه. ويُحذف وسم الزائد
openemail contacts unblock <email>أزل كل قاعدة حظر تحظر العنوان، بما فيها قاعدة النطاق الكامل
openemail contacts list-threads <email>المحادثات التي كتبها العنوان أو كُتبت إليه، في كل مجلد. ويبحث --q داخلها
openemail contacts activity <email>البريد المستلم من العنوان والمرسل إليه خلال فترة، 90 يومًا ما لم يحدد --minutes غير ذلك، مع المحادثات التي تنتظر ردًا ووسيط زمن الرد في كل اتجاه

الجماهير

قوائم مسمّاة من جهات الاتصال، حتى 100 في مساحة العمل. يجب أن يكون العنوان جهة اتصال قبل أن ينضم إلى إحداها، إلا عبر import-contacts الذي يحفظ العناوين الجديدة أثناء عمله.

الأمرما تفعله
openemail audiences listصفحة واحدة من الجماهير، الافتراضي أولًا ثم البقية الأحدث أولًا، لكل منها contactCount
openemail audiences growthكيف نمت الجماهير خلال فترة، 30 يومًا ما لم يحدد --days أو --minutes غير ذلك: الانضمامات وإلغاءات الاشتراك في كل فترة، والمجاميع
openemail audiences get <id>جمهور واحد، مع contactCount محدَّث
openemail audiences create --name <value>أنشئ جمهورًا فارغًا، مع --description اختياري. الأسماء ليست فريدة
openemail audiences update <id>غيّر --name أو --description. لا تُمَس العضوية
openemail audiences delete <id>احذف الجمهور واحتفظ بجهات اتصاله. لا يمكن حذف الجمهور الافتراضي
openemail audiences empty <id>أخرج كل جهة اتصال واحتفظ بالجمهور، بمعرّفه واسمه ووصفه
openemail audiences list-contacts <id>صفحة واحدة من جهات الاتصال في الجمهور، مع وقت انضمام كل منها وما إذا ألغت اشتراكها. ويضيّقها --sort و--q و--source و--statuses
openemail audiences add-contact <id> --email <value>ضع جهة اتصال موجودة واحدة في الجمهور. وإضافة من هو موجود فيه بالفعل لا تغيّر شيئًا
openemail audiences remove-contact <id> <email>أخرج جهة اتصال واحدة. وجهة الاتصال غير الموجودة في الجمهور تعطي 404
openemail audiences add-contacts <id> --emails <a,b>ضع حتى 200 جهة اتصال موجودة فيه، وأبلغ في missing عن العناوين التي ليست جهات اتصال
openemail audiences remove-contacts <id> --emails <a,b>أخرج حتى 200 جهة اتصال، وأبلغ عن تلك التي لم تكن فيه
openemail audiences import-contacts <id> --contacts <json|@file|->استورد حتى 500 صف { email, name }، مع حفظ العناوين التي ليست جهات اتصال بعد

البث

رسالة واحدة إلى كل من في ما يصل إلى 10 جماهير، تُرسل نسخة منفصلة لكل شخص، مع ملء حقول الدمج ورابط لإلغاء الاشتراك. وكل نسخة بريد عادي له معرّف msg_ خاص به وأحداثه وخطافات الويب الخاصة به.

الأمرما تفعله
openemail broadcasts preview --audience-ids <a,b>احسب من سيصل إليهم بث إلى هذه الجماهير، ومن سيتخطاهم لأنهم ألغوا الاشتراك أو ممنوعون. لا يرسل شيئًا
openemail broadcasts send --audience-ids <a,b> --from <value>أرسل بـ --subject و--html أو --text، أو بـ --template محفوظ، الآن أو في --scheduled-at
openemail broadcasts listصفحة واحدة من البث، الأحدث أولًا، مع أعداد حية. ويُبقي --audience-id ما أُرسل إلى ذلك الجمهور
openemail broadcasts get <id>بث واحد، مع حالته وأعداده الحية: الأمر الذي تستطلعه أثناء الإرسال
openemail broadcasts stats <id>مجاميع المسلَّم والمرتد والمفتوح والمنقور عليه وملغى الاشتراك، وسلسلة لكل فترة --grain، ساعة ما لم تحدد غير ذلك
openemail broadcasts list-recipients <id>إلى من ذهبت كل نسخة وما حدث لها. ويُبقي --filter مجموعة واحدة، مثل bounced أو not_opened
openemail broadcasts get-recipient <id> <email-id>نسخة شخص واحد، بالموضوع وHTML والنص كما استلمها تمامًا
openemail broadcasts cancel <id>أوقف بثًّا مجدولًا أو في الطابور أو لا يزال يُرسل. ولا يمكن استرجاع النسخ التي خرجت

قائمة المنع

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

الأمرما تفعله
openemail suppressions listصفحة واحدة من القائمة، الأحدث أولًا. يُبقي --reason القيم bounce أو complaint أو manual، ويبحث --q
openemail suppressions get <id>صف واحد: العنوان، والسبب، والتفاصيل التي حملها الارتداد أو الشكوى، وما إذا كان يمكن إزالته
openemail suppressions add --email <value>أوقف الإرسال إلى عنوان. وإضافة عنوان موجود بالفعل تعيد الصف الذي يشغله
openemail suppressions remove <id>اسمح بالبريد إلى العنوان من جديد. ولا يمكن إزالة الارتداد الصلب

قائمة المنع وقائمة الحظر قائمتان مختلفتان. يوقف suppressions add البريد الخارج إلى عنوان، ويرفض contacts block البريد الوارد منه.

نطاقات الصلاحية

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

النطاقالأوامر
contacts:readcontacts list وget وlist-people
contacts:writecontacts create وupdate وdelete وsave وdelete-many وset-photo وremove-photo، وaudiences import-contacts إلى جانب audiences:write
audiences:readaudiences list وgrowth وget وlist-contacts، وbroadcasts preview، كي يستطيع المفتاح الذي لا يرسل أن يعرض العدد
audiences:writeكل أمر audiences آخر، وcontacts set-audiences. ويحتاجه contacts create --audience-ids إلى جانب contacts:write
threads:readcontacts list-threads وactivity، والعناوين الظاهرة في البريد ضمن list-people
settings:readsuppressions list وget
settings:writesuppressions add وremove، وcontacts block وunblock
emails:readbroadcasts list وget وstats وlist-recipients وget-recipient
emails:sendbroadcasts send، الذي يحتاج إلى audiences:read أيضًا، وbroadcasts cancel
  • المفتاح المقيّد بعناوين أو نطاقات معيّنة يقرأ دفتر العناوين نفسه الذي يقرؤه كل مفتاح آخر ويكتب فيه. لا يرى إلا البث المرسل من عنوان أو نطاق يحمله، ولا يحصل من list-people إلا على جهات الاتصال المحفوظة، ويُرفض بـ 422 capability_unsupported في contacts list-threads وactivity وblock وunblock، وفي suppressions add وremove.
  • تسجيل الدخول عبر المتصفح لعضو لا يصل إلا إلى بعض العناوين يُرفض بـ 422 capability_unsupported في كل أمر contacts وaudiences وbroadcasts. ويرفض suppressions add تسجيل الدخول عبر المتصفح لأي شخص غير مالك مساحة العمل.

أمثلة تطبيقية

ابنِ جمهورًا من ملف، ثم احسب من سيصل إليهم بث إليه. يحفظ import-contacts العناوين التي ليست جهات اتصال بعد، وتشغيله مرة أخرى لا ينشئ شيئًا ولا يضيف شيئًا مرتين.

contacts.json
[  { "email": "[email protected]", "name": "Ada Lovelace" },  { "email": "[email protected]", "name": "Grace Hopper" },  { "email": "[email protected]" }]
بناء الجمهور وعدّه
AUDIENCE=$(openemail audiences create --name 'Product updates' --json | jq -r .id)openemail audiences import-contacts "$AUDIENCE" --contacts @contacts.jsonopenemail broadcasts preview --audience-ids "$AUDIENCE"

افحص بثًّا بـ --dry-run، الذي يطبع الطلب ولا يرسل شيئًا، ثم أرسله. يُنشأ البث فورًا ويُرسل في الخلفية، لذا استطلع get لمتابعته. هذا الجسم لا يضع {{unsubscribeUrl}}، لذا تحصل كل نسخة على تذييل من سطر واحد لإلغاء الاشتراك.

broadcast.json
{  "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"],  "from": "Acme <[email protected]>",  "subject": "{{firstName|Hello}}, the September release is out",  "html": "<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>",  "scheduledAt": "2026-10-01T09:00:00Z"}
افحص البث، ثم أرسله
openemail broadcasts send --data @broadcast.json --dry-runBROADCAST=$(openemail broadcasts send --data @broadcast.json --yes --json | jq -r .id)openemail broadcasts get "$BROADCAST"openemail broadcasts stats "$BROADCAST" --grain day

اعرف من لم يصل إليه البث. يطبع --ndjson مستلمًا واحدًا في كل سطر، و--all --json مستندًا واحدًا بكل صفحة.

من لم يصل إليهم
openemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter bounced --ndjson | jq -r .emailopenemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter not_opened --all --json | jq ".items | length"openemail suppressions list --reason bounce --all --max 50

انسخ الأعضاء المشتركين في جمهور إلى جمهور آخر. يحوّل jq التدفق إلى الجسم الذي يأخذه add-contacts، ويقرؤه --data - من stdin. ويحصره --max 200 في 200 عنوان يقبلها الاستدعاء الواحد.

نسخ الأعضاء المشتركين
openemail audiences list-contacts aud_9f2c4b7e1a0d63d84c5f2e7b --statuses subscribed --max 200 --ndjson \  | jq -s '{ emails: map(.email) }' \  | openemail audiences add-contacts aud_1c4e7a9b2d0f36e85a7c1b4d --data -

احذف كل جهة اتصال سجّلها محرّر الرسائل في نطاق واحد. يأخذ delete-many حتى 200 عنوان في الاستدعاء، لذا يقسّم xargs -n 200 القائمة الأطول. افحص الدفعات بـ --dry-run أولًا، لأنه لا تراجع.

الحذف حسب النطاق
openemail contacts list --source auto --all --ndjson \  | jq -r 'select(.email | endswith("@old-vendor.example")) | .email' > leaving.txtxargs -n 200 openemail contacts delete-many --dry-run < leaving.txtxargs -n 200 openemail contacts delete-many --yes < leaving.txt

أوقف الإرسال إلى عنوان، واسمح بعنوان من جديد، واحظر مرسلًا. تبيّن removable الصفوف التي سيأخذها suppressions remove.

المنع والسماح والحظر
openemail suppressions add --email [email protected]openemail suppressions list --q [email protected] --json | jq -r '.items[] | select(.removable) | .id'openemail suppressions remove 7b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e --yesopenemail contacts block [email protected]

التأكيدات ورموز التحقق

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

مساحة الأسماءيطلب التأكيد
contactsdelete وdelete-many وremove-photo وunblock
audiencesdelete وempty وremove-contact وremove-contacts
broadcastssend وcancel
suppressionsremove
  • يؤكد --yes نيابةً عنك. ومن دون إشراف، مع --json أو --no-input، أو في CI، أو دون طرفية، يتوقف الأمر الذي كان سيسأل بالرسالة Refusing to run unattended. Pass --yes to confirm. ورمز الخروج 2.
  • يطبع --dry-run الطلب الذي كان الأمر سيرسله ويخرج بالرمز 0، دون أن يسأل ودون أن يغيّر شيئًا.
  • مع تسجيل الدخول عبر المتصفح، يطلب audiences delete رمز تحقق أولًا، كما يفعل تطبيق الويب. لا يتخطاه --yes أبدًا، ومن دون إشراف يتوقف الأمر برمز الخروج 4. شغّل openemail verify مسبقًا، أو استخدم مفتاح API، الذي لا يُطلب منه ذلك أبدًا.
  • لا يطلب audiences empty رمز تحقق أبدًا، لذا تحقّق من المعرّف قبل أن تمرّر --yes.

التصفح

كل أمر يسرد يقرأ صفحة واحدة. وحين يبقى المزيد، مرّر المؤشر الذي طبعه إلى --cursor، مع المرشّحات نفسها، أو اقرأها كلها:

  • يقرأ --all كل صفحة ويبث العناصر: جدولًا في الطرفية، وكائن JSON واحدًا في كل سطر عند التمرير عبر أنبوب أو مع --ndjson.
  • يتوقف --max <n> بعد هذا العدد من العناصر، ويتضمن --all.
  • يطبع --json مستند { items, hasMore, nextCursor } واحدًا، ومع --all كذلك.
  • المؤشر المشوَّه أو المنتهي يعطي 400 invalid_cursor. ابدأ من جديد دونه.
الأمرحجم الصفحة
openemail contacts listمن 1 إلى 200، و50 ما لم يحدد --limit غير ذلك
openemail contacts list-peopleمن 1 إلى 100، و25 ما لم يحدد --limit غير ذلك
openemail contacts list-threadsمن 1 إلى 100، و25 ما لم يحدد --limit غير ذلك
openemail audiences listمن 1 إلى 100، و25 ما لم يحدد --limit غير ذلك
openemail audiences list-contactsمن 1 إلى 200، و50 ما لم يحدد --limit غير ذلك
openemail broadcasts listمن 1 إلى 100، و25 ما لم يحدد --limit غير ذلك
openemail broadcasts list-recipientsمن 1 إلى 200، و50 ما لم يحدد --limit غير ذلك
openemail suppressions listمن 1 إلى 100، و25 ما لم يحدد --limit غير ذلك

من المفيد معرفته

  • يرفض contacts create العنوان الموجود بالفعل في الدفتر بـ 409 contact_exists، فلا تكتب إعادة المحاولة أبدًا فوق اسم عدّله أحدهم. أما contacts save فلا يرفض أبدًا: يحفظ العنوان أو يبقيه أو يعيده، أيًّا كانت حالته.
  • يأخذ contacts delete أيضًا عنوانًا لم يظهر إلا في البريد، فيُخرج ذلك الشخص من list-people. ويبقى البريد. ولا تراجع: حفظ العنوان من جديد يبدأ جهة اتصال بلا اسم ولا ملاحظات ولا جمهور سوى الافتراضي.
  • العنوان هو هوية جهة الاتصال، لذا لا يستطيع contacts update تغييره. ونقل جهة اتصال هو delete ثم create.
  • يقرأ contacts set-photo الصورة من ملف، أو من stdin عبر -. مرّر --content-type، مثل image/jpeg: فمن دونه قد تُرسل الصورة على أنها application/octet-stream، وهو ما يرفضه الخادم بـ 422 invalid_image.
  • يأخذ broadcasts send --scheduled-at وقتًا بصيغة ISO 8601 مثل 2026-10-01T09:00:00Z، أو مدة بصيغة ISO 8601 مثل PT2H أو P1D، حتى 365 يومًا من الآن. والمهل القصيرة التي يأخذها send --at، مثل 2h، تُرفض هنا.
  • تعمل حقول الدمج في --subject و--html و--text: {{firstName}} و{{lastName}} و{{name}} و{{email}} و{{unsubscribeUrl}}، ولكل منها قيمة احتياطية بعد خط عمودي، كما في {{firstName|there}}. والجسم الذي لا يضع {{unsubscribeUrl}} يحصل على تذييل من سطر واحد لإلغاء الاشتراك. أما القالب فيُرسل كما هو، لذا ضع الرابط في القالب.
  • يُفحص البث مقابل عمليات الإرسال الشهرية للخطة قبل كتابة أي شيء، وكل نسخة تُحتسب إرسالًا واحدًا. والبث الذي لا تكفيه الحصة يُرفض بـ 429 send_quota_exceeded، ولا يبقى منه شيء.
  • مرّر --idempotency-key خاصًا بك إلى broadcasts send حين قد يعيد سكربت تشغيل الخطوة. والمفتاح نفسه يجيب بالبث الذي أنشأه بدلًا من إرسال بث جديد.
  • جهة الاتصال التي تلغي اشتراكها من بث تبقى في الجمهور مع ضبط unsubscribedAt، ويتخطاها البث اللاحق إلى ذلك الجمهور. ويسردها audiences list-contacts --statuses unsubscribed.
  • يبقى الارتداد الصلب في قائمة المنع. يرفضه suppressions remove بـ 409 suppression_not_removable، وتقول removable في كل صف ذلك مسبقًا.

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

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

OpenEmail

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

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