بواسطة مارتين برينان عبر Discourse Meta في 22 يوليو 2022 الساعة 06:34:
حسنًا، هذا أمر ضخم إلى حد ما، لذا أرجو أن تتحملوا معي. أولاً، شكرًا لكم
على الرد التفصيلي الآخر وعلى عرضكم للمساعدة في تصحيح الأخطاء أو المراجعة، فهذا مفيد حقًا
في الواقع، كنت أبحث في هذا الأمر هذا الصباح
وبشكل مفاجئ، فإن الترتيب الخيطي في العرض الموحد يعمل في Thunderbird
في معظم الحالات، وأعتقد أن رأسية References التي تشير باستمرار
إلى المنشور الأصلي (OP) تساهم في ذلك (على سبيل المثال، رأسية Reference في هذه السلسلة والتي تكون موجودة دائمًا هي
<topic/53@discoursehosted.martin-brennan.com>).
لقد أعدت قراءة القسم 3.6.4 من RFC5322 عن كثب للتو. لقد تطور عن
الإصدارات السابقة (822 و 2822)، وقد دمجت رؤوس البريد الإلكتروني In-Reply-To
مع رؤوس References الخاصة بـ USENET، بالإضافة إلى اقتباس الردود الحديثة
التي تشير إلى أكثر من رسالة سابقة واحدة.
ملخص مختصر:
Message-ID هو معرف فريد ومستمر للرسالة.
- تحتوي
In-Reply-To على جميع معرفات الرسائل التي يُعد هذا الرد ردًا مباشرًا عليها، لذا إذا قمت بالرد على زوج من الرسائل، فستحتوي على هذين المعرفين.
References هي سلسلة ردود من معرفات الرسائل السابقة بدءًا من المنشور الأصلي (OP) وصولًا إلى الرسالة السابقة. لذا، يجب بالفعل أن تبدأ دائمًا
بمعرف الرسالة الأصلي (OP).
لذلك، في مناقشات مثل هذه، وبافتراض أن التسميات هي معرفات رسائل:
المنشور الأصلي (OP)
-> الرد1
-> الرد2 ---+
-> الرد3 |
-> الرد4 |
-> الرد5 <+
سيحتوي الرد5 على:
- message-id=الرد5
- in-reply-to=“الرد2 الرد4”
- references=“المنشور الأصلي الرد3 الرد4”
ويُعتبر قانونيًا أيضًا تضمين “الرد1 الرد2” في حقل References (السلسلة الأخرى المؤدية إلى الرد5)، لكن RFC ينصح صراحةً ضد ذلك
لأن بعض العملاء يتوقعون أن تكون References سلسلة خطية واحدة من الردود، وليس رسمًا بيانيًا مسطحًا.
لذلك، توصيتي لبناء حقل References هي استخدام References الخاصة بـ"الرسالة السابقة الأولية" مع إرفاق معرف الرسالة الخاصة بالرسالة السابقة الأولية. بهذه الطريقة، تحصل دائمًا على سلسلة خطية بالترتيب الصحيح.
من المثير للاهتمام أن يبدو أن هناك بعض الترتيب الخيطي هناك.
ولكن لاحظ: أن المنشور العلوي يحتوي على سهم صغير يقول “هو رد”. على الرغم من أنه
المنشور رقم 1. أتوقع أن يكون ذلك بسبب إدخال “الموضوع” في References،
والذي يجعل Thunderbird يعتقد أن هناك رسالة سابقة (وهو أمر لم يحدث بالطبع).
في عالم Mutt، نرى عمليًا لا يوجد أي ترتيب خيطي على الإطلاق:
23Jul2022 06:24 Olha via Discus - ┌>[Py] [Users] I need an advise discuss-users 5.7K
22Jul2022 17:12 Paul Jurczak vi - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 13:21 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.8K
22Jul2022 12:53 vasi-h via Disc - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 11:38 Cameron Simpson - ├>[Py] [Users] I need an advise discuss-users 14K
22Jul2022 10:27 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.6K
22Jul2022 06:14 vasi-h via Disc r ┴>[Py] [Users] I need an advise discuss-users 6.5K
وذلك لأن In-Reply-To في كل رسالة تشير مباشرة إلى
معرف الرسالة الوهمي للموضوع “topic”. ربما يتجاهل Mutt حقل References
لأنه قارئ بريد إلكتروني، وReferences أصلها في أخبار USENET. ربما
يستخدم Thunderbird حقل References أو يعزز حقل In-Reply-To بمعلومات من References.
تحتاج فقط إلى الرجوع إلى أحد حقلين In-Reply-To أو References للقيام
بالترتيب الخيطي؛ الأول يأتي من البريد الإلكتروني والثاني من USENET. أنت
تدعم كلاهما (وهو أمر رائع!) لذا نحتاج إلى جعلهما متسقين.
(ملاحظة جانبية: هناك أيضًا نقاش حول عكس صور USENET، لأن عدة أشخاص من مجتمع بايثون يستهلكون القوائم عبر واجهة USENET. مرة أخرى، هذا موضوع منفصل.)
[…]
[quote=“Cameron Simpson, post:8, topic:233499,
username:cameron-simpson”]
هذا يبدو جيدًا. هل يتم حفظ هذا المعرف مع سجل قاعدة البيانات بحيث يمكن ربط
الردود الواردة بالرسالة السابقة في المنتدى؟
[/quote]
الإجابة هي – الأمر يعتمد. إذا تم إنشاء منشور في Discourse من بريد إلكتروني وارد، مثل هذا الخاص بك، فنحن نستخدم معرف الرسالة الأصلي للبريد الوارد (Message-ID) لذلك المنشور عندما يرد عليه شخص ما في رؤوس In-Reply-To و References وفقًا لما يلي:
discourse/lib/email/sender.rb at 98bacbd2c6b9fe57167cd32af5eb4839b4a5d1f6 · discourse/discourse · GitHub
بخلاف ذلك، نحن نستخدم فقط مرجع المنشور الأصلي للموضوع ونولد مرجعًا جديدًا، وهو ما يسبب بالتأكيد جميع المشاكل. في جميع الحالات، نقوم بتوليد معرف Message-ID جديد في كل مرة يتم فيها إرسال بريد إلكتروني صادر، وهو ما يبدو صحيحًا ومتسقًا مع عملاء البريد الآخرين.
للأسف، ليس تمامًا. إذا كنت أنت مصدر الرسالة (أي تم تأليفها في
Discourse)، فإن توليد معرف الرسالة أمر مقبول. إذا لم يكن هناك معرف رسالة
(وهو أمر غير قانوني)، فإن توليد واحد هو ممارسة قياسية (عادةً بواسطة MTAs). ولكن إذا كنت تنقل رسالة (تم تأليفها في البريد الإلكتروني)، فيجب الحفاظ على معرف الرسالة الحالي.
في رأيي، تحتاج إلى القيام بثلاثة أشياء:
- امتلاك معرف رسالة مستقر وعدم استبدال معرف الرسالة من رسالة واردة.
- توليد
In-Reply-To صحيح، والذي يمكن حسابه بسهولة من الرسالة السابقة المباشرة (أو الرسائل) أي معرفات الرسائل السابقة-Message-ID.
- توليد
References صحيح، والذي يمكن حسابه بسهولة كـ
الرسائل السابقة-References + معرف الرسالة السابقة-Message-ID.
بالنسبة للنقطة 1، بالنظر إلى الكود الذي أشرت إليه، ربما تريد أن يكون معرف رسالة البريد الإلكتروني (بناء جملة شبيه بـ Python، آسف):
def message_id(post):
return post.incoming_email.message_id or discourse_message_id(post)
أي أن يكون معرف رسالة البريد الإلكتروني للمنشور إذا نشأ من البريد الإلكتروني،
وإلا فإن معرف الرسالة الخاص بـ Discourse باستخدام خوارزمية مثل ما شرحت لاحقًا في هذه الرسالة: أي شيء (أ) مستقر و (ب) صالح نحويًا.
ثم تكون حساب حقول In-Reply-To و References أمرًا ميكانيكيًا بسيطًا كما هو موضح في النقطتين 2 و 3.
أعتقد أنني أدرك ما تقصده، هل الأمر كالتالي:
- يرسل Cameron بريدًا إلكترونيًا إلى Discourse من Mutt ويحصل على
Message-ID: 74398756983476983@mail.com
- ينشئ Discourse منشورًا ويخزن
Message-ID مقابل المنشور مع سجل IncomingEmail
صحيح.
- يراقب johndoe الموضوع، لذا يتم إرسال بريد إلكتروني إليه من Discourse يحتوي على
Message-ID: topic/222/44@discourse.com ولا يوجد أي مرجع للمعرف الأصلي Message-ID: 74398756983476983@mail.com
لا. أنت حقًا تريد تمرير IncomingEmail.message_id كـ
Message-ID في البريد الإلكتروني الموجه إلى johndoe. إنها نفس الرسالة.
هل يبدو ذلك صحيحًا، أنه يجب علينا ببساطة “تمرير” ذلك Message-ID إلى أولئك الذين يراقبون الموضوع بدلاً من توليد معرف خاص بنا لأنه فريد بالفعل؟ وماذا يحدث بعد ذلك في عميل البريد الإلكتروني الخاص بـ johndoe إذا
قام Cameron أيضًا بإرسال نسخة منه (CC) إليه في تلك الرسالة الصادرة الأصلية؟ يبدو هذا وكأنه مشكلة منفصلة، لذا سيكون من الجيد فتح موضوع خطأ آخر لها.
عن طريق تمريره، تكون الرسالة الأصلية (Cameron->cc:johndoe) والرسالة
الموجهة من Discourse (Cameron->Discourse->johndoe) لهما نفس
معرف الرسالة ونفس محتوى الرسالة. يقوم نظام البريد المستلم بتخزين كلاهما. يرى قارئ البريد كلاهما، ويعرض إما كلاهما أو يحتفظ بواحد فقط (هذا قرار سياسي لقارئ البريد - الاحتفاظ بواحد فقط هو أمر شائع). لأنهما نفس الرسالة، بشكل عام لا يهم أيهما يتم الاحتفاظ به.
إذا تجاهلنا Discourse واعتبرنا رسالة كانت
نسخة من الرسالة عبر القائمة البريدية وأيضًا عبر البريد الإلكتروني المباشر. إنهما نفس الرسالة، بنفس معرف الرسالة.
سأقوم بإعداد عميل Mutt محليًا لأرى ما ترونه أيضًا، لقد لم أختبر هذه الوظيفة أبدًا في عميل قائم على النص (فقط Gmail و Thunderbird) لذا أنا متحمس لرؤية كيف يبدو الأمر على أي حال.
يسعدني المساعدة في الإعدادات. لعرض الخيوط، تحتاج إلى تعيين الترتيب إلى خيطي. Mutt قابل للتكوين للغاية.
كان خط تفكيري لمعالجة هذه المشاكل هذا الصباح هو التخلص من
اللاحقات المولدة عشوائيًا التي نولدها عند إرسال رؤوس Message-ID في رسائل البريد الإلكتروني وبدلاً من ذلك ننتقل إلى مخطط نستخدم فيه
معرف المستخدم (user_id) لكل من المستخدم المرسل والمستقبل. الفائدة
من ذلك هي عدم الحاجة إلى تخزين Message-ID في أي مكان
(إلا عندما ينشئ بريد إلكتروني وارد منشورًا) وبالتالي ستكون رؤوس References
و In-Reply-To متسقة دائمًا.
نعم، هذا أفضل بكثير. ملاحظة أن معرف رسالة البريد الإلكتروني الوارد
يجب أن يتجاوز معرف الرسالة المشتق من Discourse للبريد الصادر.
(تستخدم معظم أنظمة البريد سلاسل عشوائية لأنه لا يوجد سياق محيط مثل هيكل موضوع Discourse - تُعتبر الرسائل بمفردها؛ لكن المتطلب الحقيقي الوحيد هو التفرد المستمر.)
دعني أعطي مثالًا. لنفترض أن لدينا هؤلاء المستخدمين:
- martin - user_id 25
- cameron - user_id 44
- sam - user_id 78
- bob - user_id 999
ثم لدينا هذا الموضوع، topic_id 233499، مع منشورات تبدأ من post_id 100 كمنشور أصلي (OP). سيكون التنسيق topic/#{topic_id}/#{post_id}.s#{sender_user_id}r#{receiver_user_id}.
ستبدو عملية الترتيب كالتالي:
- martin ينشئ المنشور الأصلي (OP)
- يتم إرسال بريد إلكتروني إلى cameron يحتوي على هذه الرؤوس:
Message-ID: topic/233499.s25r44@meta.discourse.org
References: topic/233499@meta.discourse.org
- يتم إرسال بريد إلكتروني إلى sam يحتوي على هذه الرؤوس:
Message-ID: topic/233499.s25r78@meta.discourse.org
References: topic/233499@meta.discourse.org
-
لا يجب أن يكون هناك رأسية References في المنشور الأصلي (OP). فهي غير
ضرورية للترتيب الخيطي وتفترض فعليًا وجود “منشور 0” غير موجود. هذا يعني أن كل منشور أصلي (أ) يبدو وكأنه رد، وهو ليس كذلك، و (ب) يبدو أن الشيء الذي هو رد عليه مفقود من صندوق بريد القارئ.
-
هذا يجعل معرفات رسائل مختلفة لكل نسخة صادرة من المنشور الأصلي. هذا
سيء. يجب أن تكون هي نفسها. لنفترض أن sam أرسل نسخة من الرسالة (CC) إلى cameron مباشرة في رد. سيحتوي In-Reply-To على معرف رسالة لم يتلقه cameron أبدًا.
يمكنك ببساطة إسقاط sender_user_id و receiver_user_id من حقل
معرف الرسالة والحصول على معرف فريد واحد يراه كل مستقبل.
شرط التفرد هو المنشور نفسه، وليس كائن “الرسالة” على مستوى البريد الإلكتروني الفردي.
بخصوص References، لا يجب أن يكون للمنشور الأصلي (OP) واحد. سيكون Thunderbird وكل شيء آخر على ما يرام. إذا كانوا يستخدمون References للترتيب الخيطي بدلاً من In-Reply-To، فإن References في رسائل الرد كافية.
إليك بداية سلسلة مناقشة في قائمة بريدية في Mutt:
16Jul2022 01:09 Rob Boehne - │├>[Python-Dev] Re: [SPAM] Re: Swit python-dev 9.2K
16Jul2022 01:33 Peter Wang - │├> python-dev 3.0K
16Jul2022 00:24 Skip Montanaro - ├>[Python-Dev] Re: Switching to Dis python-dev 4.2K
16Jul2022 04:49 Erlend Egeberg - ├>[Python-Dev] Re: Switching to Dis python-dev 10K
16Jul2022 04:20 Mariatta - ├>[Python-Dev] Re: Switching to Dis python-dev 10K
15Jul2022 21:18 Petr Viktorin - [Python-Dev] Switching to Discourse python-dev 4.2K
تجاهل أنني أرتب بريدي الإلكتروني الأحدث في الأعلى. لاحظ أنه لا يوجد سهم على
المنشور الأولي (في الأسفل). تلك الرسالة ليس لها References ولا
In-Reply-To. جميع الرسائل الأخرى لها In-Reply-To (وربما
References، لكن هذا قائمة بريدية إلكترونية لذا ليس بالضرورة؛ كما ذكرت سابقًا فهي مكملة لبعضها البعض.)
إذا كررت مثال Discourse الخاص بي من سابقًا:
23Jul2022 06:24 Olha via Discus - ┌>[Py] [Users] I need an advise discuss-users 5.7K
22Jul2022 17:12 Paul Jurczak vi - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 13:21 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.8K
22Jul2022 12:53 vasi-h via Disc - ├>[Py] [Users] I need an advise discuss-users 5.5K
22Jul2022 11:38 Cameron Simpson - ├>[Py] [Users] I need an advise discuss-users 14K
22Jul2022 10:27 Rob via Discuss - ├>[Py] [Users] I need an advise discuss-users 6.6K
22Jul2022 06:14 vasi-h via Disc r ┴>[Py] [Users] I need an advise discuss-users 6.5K
لاحظ أن لديهم جميعًا سهمًا قياديًا؟ هذا لأن عميل البريد الإلكتروني
يعتقد أنها جميعًا ردود على رسالة جذر مشتركة (وغير موجودة)،
وهو ما يرجع إلى معرف الرسالة “الموضوع” في رأسية References. بينما المنشور 1 هو في الواقع الرسالة السفلية المعروضة أعلاه.
ملخص:
- خطتك جيدة، بشرط أن تسقط المرسل والمستقبل من
معرف الرسالة - فهما غير ضروريين وفي الواقع سيؤدي المستقبل إلى مشاكل (المرسل مجرد تكرار).
- اسقط معرف الرسالة الوهمي “الموضوع” من
References - فهو يضلل
عملاء البريد الإلكتروني (بما في ذلك Thunderbird، حتى لو لم يكن ذلك واضحًا بصريًا)
- cameron يرد عبر البريد الإلكتروني
- يتم إرسال بريد إلكتروني إلى discourse يحتوي على هذه الرؤوس من Mutt:
Message-ID: 43585349859734@test.com
References: topic/233499@meta.discourse.org topic/233499.s25r44@meta.discourse.org
In-Reply-To: topic/233499.s25r44@meta.discourse.org
نعم، مرة أخرى مع التحذير من أنه لا يجب أن يكون هناك مرجع “موضوع”.
كما هو متوقع، هناك مرجع لمعرف رسالة المنشور الأصلي (OP). ومع ذلك، يجب أن
يكون نفس معرف الرسالة الذي يراه sam للمنشور الأصلي.
- ينشئ discourse (بصفتي cameron، من البريد الإلكتروني أعلاه) المنشور 101
- يتم إرسال بريد إلكتروني إلى sam من discourse يحتوي على هذه الرؤوس:
Message-ID: topic/233499/101.s44r78@meta.discourse.org
References: 43585349859734@test.com topic/233499@meta.discourse.org
In-Reply-To: 43585349859734@test.com
وهنا يحدث الخطأ. يجب أن يكون Message-ID هو
43585349859734@test.com من حقل .incoming_post.message_id. (حسنًا، في رأيي هذا هو post.message_id()، الذي يعيد
post.incoming_post.message_id لمنشور تم إنشاؤه بواسطة البريد الإلكتروني ورسالة Discourse المولدة في غير ذلك).
تخيل: أنا أكتب وأرسل ردّي بمعرف رسالة 43585349859734@test.com. لأسباب الاستمرارية، احتفظ بنسخة منه في مجلدي المحلي، حيث يظهر كرد على المنشور الأصلي. بشكل مثالي، ترسل لي Discourse أيضًا نسخة من منشوري (هذا إعداد سياسة في العديد من القوائم البريدية)، لذا أحصل أيضًا على نسخة Discourse. يجب أن يكون لها نفس معرف الرسالة، لأنها نفس الرسالة، فقط عبر مسار مختلف.
رسالة Discourse ليست “ردًا على” رسالتي. إنها رسالتي، فقط تم توجيهها.
هذا التأثير يتسلسل عبر الأمثلة التالية الخاصة بك. يجب أن تكون العملية الفعلية
أبسط مما جعلتها.
فكر في الأمر بهذه الطريقة. إذا قمت بالرد على منشور من البريد الإلكتروني، فهو فعليًا
مثل إرسال بريدي إلى sam (والآخرين) عبر Discourse. يقوم Discourse
بتوجيه رسالتي إلى المشتركين المستلمين للبريد الإلكتروني، و
“عن طريق الصدفة” يحتفظ بنسخة على المنتدى 
كإشارة جانبية، لقد بحثت أيضًا في ما يفعله GitHub مع رسائل
الإشعار الخاصة به، ولاحظت أنهم يفعلون شيئًا مشابهًا حيث لديهم مرجع دائم
(discourse/discourse/pull/252@github.com) يُستخدم في جميع رسائل البريد الإلكتروني
المرتبطة بهذا “الموضوع” والذي في هذه الحالة هو طلب سحب (pull request) على GitHub:
References: <discourse/discourse/pull/252@github.com> <discourse/discourse/pull/252/issue_event/7042100517@github.com>
In-Reply-To: <discourse/discourse/pull/252/issue_event/7042100517@github.com>
واو، GitHub. كم هي كارثة رسائل قضاياهم 
ومع ذلك، في سيناريوهم، طلب السحب (PR) هو المنشور الأصلي (OP). لذا فإن المرجع المباشر
إلى طلب السحب أمر منطقي. يمكنك استخدام معرف الرسالة “الموضوع” للمنشور 1،
بشرط ألا تستخدم أيضًا معرف “الموضوع/1” أيضًا. ولكن لا يبدو أن هناك فائدة كبيرة - فهو جهد إضافي لتخصيص حالة المنشور 1 - سأستخدم “الموضوع/1” بنفسي.
لإضافة بعض التعقيد. كما أفهمه، يمكن للمدير نقل منشور أو موضوع. أليس هذا يكسر مخطط “توليد معرف الرسالة”، خاصة إذا نقلوا منشورًا فقط؟ أنا أميل إلى الرأي بأن كل منشور يجب أن يكون لديه حقل _message_id، مملوء من الرسالة الواردة (من البريد الإلكتروني) أو المولد (النشر عبر Discourse). ثم يكون ذلك دائمًا ومستقرًا وقويًا ضد أي تحريك للمنشورات أو تغييرات في الخوارزمية.
أخيرًا، هناك اعتبار أمني صغير: يجب عليك تجاهل معرف رسالة البريد الإلكتروني الوارد (وربما إرجاع الرسالة) إذا ادعى معرف رسالة لمنشور موجود. لأنني كمؤلف، يمكنني وضع أي شيء أريده في ذلك الرأس :-). سأذهب إلى مجرد إسقاط معرف الرسالة - قبول المنشور، ولكن لا تدعه يكذب بأنه منشور آخر - امنح نسختك معرفًا مولدًا بواسطة Discourse ثم تابع كالمعتاد.