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

جهات الاتصال

`contacts.list` و`get` و`create` و`save` و`update` و`set_audiences` و`delete` و`delete_many` و`list_people` و`set_photo` و`remove_photo` و`block` و`unblock` و`list_threads` و`activity`.

كل الدوالّ

usage.rb
page = client.contacts.list(limit: 100)contact = client.contacts.get("[email protected]") saved = client.contacts.create(  email: "[email protected]",  name: "Grace Hopper",  notes: "Met at the compiler workshop") client.contacts.update("[email protected]", notes: nil)client.contacts.set_audiences("[email protected]", audienceIds: ["aud_4c1b8e2a7d9f05c36b4e8a71"])client.contacts.delete("[email protected]") puts page.items.size, page.has_more?, contact[:source], contact[:lastSeenAt], saved[:source]

يعيد list جهات الاتصال الأحدث ظهورًا أولًا، وجهات الاتصال التي لم تُراسَل قط في الآخر. وتكون قيمة source هي auto حين كُتب السجل لأن عضوًا أرسل إلى ذلك العنوان رسالة من محرّر الرسائل في التطبيق، وهو ادعاء مختلف جوهريًا عن أن شخصًا قد حفظه. ووصول بريد من عنوان لا يكتب شيئًا، وكذلك الإرسال عبر هذه الواجهة.

دفتر العناوين ملك لمساحة العمل لا لشخص واحد، فجهة الاتصال التي يحفظها أي عضو هي نفسها التي يراها كل عضو وكل مفتاح. ويكتب create قيمة source بالقيمة manual ويضع جهة الاتصال في الجمهور الافتراضي فور كتابتها. اذكر قوائمك الخاصة في audienceIds لضمّها في الاستدعاء نفسه، وهو ما يتطلب أيضًا audiences:write، أو أضف جهة الاتصال لاحقًا عبر audiences.add_contact، الذي تشرحه صفحة الجماهير. ويحدّد set_audiences بالضبط القوائم التي تنتمي إليها جهة اتصال، باستدعاء واحد.

تُخزَّن العناوين بأحرف صغيرة ويرمّز الـ gem العنوان الذي تمرّره، فيصل [email protected] إلى الصف الصحيح. والعنوان nil أو الفارغ يرفع ArgumentError قبل إرسال أي شيء. والعنوان هو الهوية، فلا يستطيع update تغييره: فنقل جهة اتصال هو delete ثم create.

المعاملات: contacts.list

limitInteger
كم جهة اتصال تُعاد في كل صفحة: عدد صحيح من 1 إلى 200، والافتراضي 50. ويُحوَّل النوع تلقائيًا، فلا بأس بـ String مثل `"100"` مقروء من سلسلة استعلام، والقيمة خارج المدى تعطي 422 بدل أن تُقصّ.
cursorString
`next_cursor` من الصفحة السابقة. لا تبنِه بنفسك أبدًا: فالمؤشر الذي يسمّي جهة اتصال لم تعد موجودة يعطي 400 `invalid_cursor`، يُرفع في صورة `OpenEmail::InvalidRequestError`، وهذا يعني أن حالة الترقيم لديك قديمة وأن المرور يجب أن يبدأ من جديد دون مؤشر.
sourceString
`manual` لجهات الاتصال التي حفظها شخص عمدًا، و`auto` لتلك التي سجّلها محرّر الرسائل في التطبيق. اتركه للحصول على دفتر العناوين كاملًا.
qString
يبحث في الاسم والعنوان، حتى 200 حرف. وإن لم يطابق شيء تمامًا في الصفحة الأولى، تُعاد تهجئات قريبة بدلًا من ذلك، وتواصل الصفحات التالية المطابقة بالطريقة نفسها.

الاستجابة: جهة اتصال

يعيد contacts.list صفحة OpenEmail::Page، فتكون الصفوف في page.items ويتبع المرور page.next_cursor ما دامت قيمة page.has_more? هي true. ويعيد list_all كل الصفوف في Array واحدة، ويمرّرها iterate واحدًا تلو الآخر. ويعيد كلٌّ من get وcreate وupdate وsave وset_audiences جهة اتصال واحدة في صورة Hash بمفاتيح من نوع Symbol، أي الصف نفسه مع audiences. ودفتر العناوين غير محدود، ولهذا يرقّم هذا المسار الصفحات بدل أن يعيد Array تتوقف بصمت عند 200.

objectString
دائمًا السلسلة `contact`، في سجلات القائمة كما في `get`.
emailString
العنوان، ويُحوَّل إلى أحرف صغيرة عند الكتابة فيصبح `[email protected]` و`[email protected]` جهة اتصال واحدة، وهو المفتاح الذي تأخذه كل دوال contacts، إذ لا يُكشف أي معرّف لجهة الاتصال. والسجلات ملك لمساحة العمل لا للعضو أو المفتاح الذي كتبها، فكل عضو وكل مفتاح في مساحة العمل يقرأ ويكتب في دفتر عناوين واحد.
nameString or nil
الاسم المعروض، أو nil حين لم يُسجَّل أي اسم للعنوان قط. والكتابة التلقائية لا تحمل اسمًا إلا حين توفر الترويسة شيئًا غير العنوان نفسه، ولا يمكنها أبدًا الكتابة فوق اسم كتبه المستخدم.
sourceString
تعني `auto` أن السجل كُتب لأن المستخدم أرسل بريدًا إلى ذلك العنوان. وتعني `manual` أن شخصًا أدخله بنفسه، وهو ادعاء مختلف جوهريًا، ولا تُنزل عملية الإدراج أو التحديث قيمة `manual` إلى `auto` أبدًا. ووصول بريد من عنوان لا يكتب أي سجل على الإطلاق، وهذا مقصود، فمن لم يفعل سوى مراسلتك ليس هنا. وعامل القيمة كـ String مفتوح، لأن العمود نص حر قيمته الافتراضية `manual`.
notesString or nil
نص حر كتبه شخص عن هذا الشخص، في التطبيق أو عبر `update`، ولا يُولَّد آليًا أبدًا. ويكون nil حين لم يكتب أحد شيئًا، و`notes: nil` في `update` يمسحه.
lastSeenAtString or nil
سلسلة ISO 8601 بتوقيت UTC، تُحدَّث في كل مرة يرسل فيها عضو إلى ذلك العنوان من محرّر الرسائل في التطبيق، لا عند وصول بريد منه، فذلك لا يكتب شيئًا. وتكون nil لجهة اتصال حُفظت عبر `create` ولم تُراسَل قط، وتأتي هذه في الآخر في الترتيب التنازلي حسب `lastSeenAt` الذي يعيده هذا المسار.
audiencesArray<Hash>
فقط في `get` و`create` و`update` و`save` و`set_audiences`، ولا يظهر أبدًا في صفوف القوائم. كل جمهور تنتمي إليه جهة الاتصال، بما فيه الجمهور الافتراضي، في صورة Hash فيه `id` و`name` و`builtin`. وتكون قيمة `builtin` هي `default` في الجمهور الذي تنتمي إليه كل جهات الاتصال، وnil في جمهور أنشأه شخص، فتفرّع عليها لا على الاسم الذي يستطيع أي شخص تغييره.
photoUrlString or nil
المكان الذي تُقدَّم منه صورة جهة الاتصال، أو nil حين لا تكون لها صورة. ويضبطها `set_photo`، وكل رفع يحصل على عنوان URL جديد.

ضبط جماهير جهة اتصال

يحدّد set_audiences(email, audienceIds: [...]) بالضبط الجماهير التي تنتمي إليها جهة اتصال واحدة، بطلب واحد. تنضم جهة الاتصال إلى كل جمهور مذكور لم تكن فيه بعد، وتغادر كل جمهور آخر، ويعيد الاستدعاء جهة الاتصال بعد التغيير، مع audiences الخاصة بها. ويتطلب audiences:write، لأنه يكتب العضويات لا جهة الاتصال، وتكراره لا يغيّر شيئًا، فيعيد الـ gem محاولته بعد فشل في الشبكة.

يُحتفظ بالجمهور الافتراضي دائمًا، لذا فإن audienceIds: [] يُبقي جهة الاتصال في الجمهور الافتراضي وحده. ويقبل حتى 100 معرّف. والمعرّف الذي لا يشير إلى أي جمهور في مساحة العمل هذه يعطي 404 audience_not_found ولا يتغير شيء، والعنوان الذي ليس جهة اتصال يعطي 404 contact_not_found. وكلاهما يرفع OpenEmail::NotFoundError.

كل من في صفحة جهات الاتصال

يسرد list_people الأشخاص الذين تعرضهم صفحة جهات الاتصال في التطبيق: جهات الاتصال المحفوظة وكل عنوان ظهر في البريد، ولكلٍّ منها saved وthreads وlastAt. أما list فجهات الاتصال المحفوظة وحدها. ويعيد OpenEmail::PeoplePage، الذي يضيف seen إلى items وhas_more? وnext_cursor. ولا تأتي العناوين التي ظهرت في البريد إلا إذا كان المفتاح يحمل threads:read أيضًا، ويقول page.seen هل أتت. وقيمة sort: هي recent أو name أو threads، ويسمّيها OpenEmail::PEOPLE_SORTS. ويبحث q: في الأسماء والعناوين والملاحظات، ويُبقي blocked: true الأشخاص الذين تحظرهم قائمة حظر مساحة العمل، بما في ذلك قواعد النطاق الكامل. ويسمّي blockedBy القاعدة في كل صف.

people.rb
page = client.contacts.list_people(sort: "threads", limit: 50) page.items.each do |person|  client.contacts.save(person[:email]) if !person[:saved] && person[:threads].to_i > 5end blocked = client.contacts.list_all_people(blocked: true)puts page.seen, blocked.size

يعيد list_all_people كل الصفحات في Array واحدة، ويمرّر iterate_people كل شخص إلى كتلة، أو يعيد Enumerator دونها. ولا يبلّغ أيٌّ منهما عن seen، فاقرأ صفحة واحدة عبر list_people لتعرفه. والمؤشر معتم، فمرّر next_cursor مرة أخرى بوصفه cursor: كما جاء تمامًا، مع sort: وq: وblocked: نفسها.

الحفظ والحذف والصور

save(email)، مع name: وnotes: اختياريين، هو إضافة إلى جهات الاتصال والإبقاء في جهات الاتصال: يحفظ عنوانًا ليس جهة اتصال بعد، ويُبقي عنوانًا سُجّل من إرسال محفوظًا يدويًا، ويعيد عنوانًا محذوفًا. وdelete هو حذف: يزيل جهة الاتصال المحفوظة ويُخفي العنوان، كي لا يسجّله محرّر الرسائل مجددًا، ويقبل كذلك عنوانًا لم يظهر إلا في البريد. ويقول wasSaved في الـ Hash الذي يعيده أيّهما كان. ويحذف delete_many ما يصل إلى 200 في استدعاء واحد.

photo.rb
client.contacts.save("[email protected]", name: "Grace Hopper") contact = client.contacts.set_photo("[email protected]", File.binread("photo.jpg"), content_type: "image/jpeg")puts contact[:photoUrl] client.contacts.set_photo("[email protected]", Pathname("photo.png")) client.contacts.remove_photo("[email protected]")client.contacts.delete_many(["[email protected]", "[email protected]"])

يرسل set_photo بايتات الصورة كما هي: PNG أو JPEG أو WebP أو GIF حتى 5 ميغابايت، ملاءَمة داخل مربع 512 بكسل. والبايتات String ثنائي أو IO أو Pathname. مرّر content_type:، أو بايتات تحمل نوعها بنفسها: كائن يستجيب لـ content_type، مثل ملف مرفوع في Rails، أو File أو Pathname ينتهي اسمه بـ .png أو .jpg أو .jpeg أو .webp أو .gif. ودون نوع تُرسَل البايتات بوصفها application/octet-stream، ويرفضها الخادم بالخطأ 422 invalid_image. ويسمّي OpenEmail::CONTACT_PHOTO_TYPES الأنواع الأربعة. ويجب أن يكون العنوان جهة اتصال محفوظة أولًا.

الحظر

يضع block(email) العنوان في قائمة حظر مساحة العمل كي يُرفض بريده، مُسقطًا أي وسم زائد، ويزيل unblock(email) كل قاعدة تحظره. وكلاهما يحتاج settings:write، لأنهما يغيّران قائمة الحظر لا جهة الاتصال، ولا يحتاج أيٌّ منهما أن يكون العنوان جهة اتصال.

حين يرفع unblock قاعدة نطاق كامل، يسردها removed مع list مضبوطًا على blockedDomains، ويُلغى معها حظر كل من في ذلك النطاق. ويسمّي OpenEmail::CONTACT_BLOCK_LISTS القائمتين كلتيهما.

المحادثات والنشاط

يتصفح list_threads(email) صفحةً تلو صفحة المحادثاتِ التي كتبها العنوان أو كُتبت إليه، في كل المجلدات، ويمر list_all_threads وiterate_threads عليها كلها. ويعيد activity(email) الأرقام التي خلف تبويب النشاط لجهة اتصال: الوارد والصادر لكل فاصل زمني، والمحادثات التي تنتظر ردك، والزمن الوسيط للرد في كل اتجاه. وكلاهما يحتاج إلى threads:read.

activity.rb
threads = client.contacts.list_threads("[email protected]", q: "invoice") activity = client.contacts.activity(  "[email protected]",  minutes: 30 * 24 * 60,  grain: "day",  offset_minutes: Time.now.utc_offset / 60) puts threads.items.size, activity.dig(:totals, :waiting)

يأخذ activity وسائط مسمّاة بصيغة snake_case. ويضبط minutes: النافذة، وهي 90 يومًا إذا أُغفل. ويضبط grain: عرض الفاصل الزمني: minute أو hour أو day. ويضبط offset_minutes: عدد الدقائق شرق UTC حيث تنقسم الأيام. وTime.now.utc_offset / 60 هو الإزاحة المحلية، ويرسلها الـ gem بوصفها offsetMinutes الخاصة بـ API.