الفرق بين المراجعتين لصفحة: «Rails/action mailer basics»

من موسوعة حسوب
إنشاء الصفحة
 
طلا ملخص تعديل
 
(2 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
سطر 1: سطر 1:
= أساسيات إجراء المراسلة =
<noinclude>{{DISPLAYTITLE:أساسيات Action Mailer في ريلز}}</noinclude>
يوفّر لك هذا الدليل كل ما تحتاجه للبدء في إرسال واستقبال رسائل البريد الإلكتروني من وإلى تطبيقك، والعديد من عمليّات إجراء المراسلة (Action Mailer) الداخليّة. كما يغطي كيفية اختبار مُرسلي بريدك (mailers).
يوفّر لك هذا الدليل كل ما تحتاجه للبدء في إرسال واستقبال رسائل البريد الإلكتروني من وإلى تطبيقك، والعديد من عمليّات [[Rails/action mailer|Action Mailer]] الداخليّة. كما يغطي كيفية اختبار مُرسلي بريدك (mailers).


ستتعلم بعد قراءة هذا الدليل:
ستتعلم بعد قراءة هذا الدليل:
* كيفيّة إرسال واستقبال البريد الإلكتروني داخل تطبيق ريلز.
* كيفيّة إرسال واستقبال البريد الإلكتروني داخل تطبيق ريلز.
* كيفيّة إنشاء وتعديل صنف إجراء المراسلة والعرض المرتبط به.
* كيفيّة إنشاء وتعديل صنف [[Rails/action mailer|Action Mailer]] والعرض المرتبط به.
* كيفيّة إعداد إجراء المراسلة لبيئتك.
* كيفيّة إعداد [[Rails/action mailer|Action Mailer]] لبيئتك.
* كيفيّة اختبار أصنافك لإجراء المراسلة.
* كيفيّة اختبار أصنافك لـ [[Rails/action mailer|Action Mailer]].


== مقدمة ==
== مقدمة ==
يسمح لك إجراء المراسلة (Action Mailer) بإرسال رسائل البريد الإلكتروني من تطبيقك باستخدام الأصناف <code>mailer</code> والعروض المرتبطة بها (views).
يسمح لك [[Rails/action mailer|Action Mailer]] بإرسال رسائل البريد الإلكتروني من تطبيقك باستخدام الأصناف <code>mailer</code> والعروض المرتبطة بها (views).


تعمل مُرسلات البريد بطريقة مشابهة جدًا لوحدات التحكّم. وهي ترث من <code>ActionMailer::Base</code> وتتوضع في app/mailers  ولديها عروض مرتبطة تظهر في app/views.
تعمل مُرسلات البريد بطريقة مشابهة جدًا لوحدات التحكّم. وهي ترث من <code>ActionMailer::Base</code> وتتوضع في app/mailers ولديها عروض مرتبطة تظهر في app/views.


== إرسال البريد الإلكتروني ==
== إرسال البريد الإلكتروني ==
سطر 63: سطر 63:
   end
   end
end
end
</syntaxhighlight>فيما يلي شرح سريع للعناصر المعروضة في التابع. للحصول على قائمة كاملة بجميع الخيارات المتاحة، يرجى إلقاء نظرة أدناه في قسم "قائمة خصائص إجراء المراسلة الكاملة القابلة للتعيين من طرف المستخدم".
</syntaxhighlight>فيما يلي شرح سريع للعناصر المعروضة في التابع. للحصول على قائمة كاملة بجميع الخيارات المتاحة، يرجى إلقاء نظرة أدناه في قسم "قائمة خصائص [[Rails/action mailer|Action Mailer]] الكاملة القابلة للتعيين من طرف المستخدم".
* <code>default</code>: (كائن <code>[[Ruby/Hash|Hash]]</code>) يمثِّل جدول <code>[[Ruby/Hash|Hash]]</code> للقيم الافتراضية لأي بريد إلكتروني ترسله من هذا المُرسل. نُعيّن في هذه الحالة قيمة  الترويسة <code>from:</code> لجميع الرسائل في هذا الصنف. يمكن إعادة تعريف (override) هذا الحقل مع كل بريد إلكتروني على حدة.
* <code>default</code>: (كائن <code>[[Ruby/Hash|Hash]]</code>) يمثِّل جدول <code>[[Ruby/Hash|Hash]]</code> للقيم الافتراضية لأي بريد إلكتروني ترسله من هذا المُرسل. نُعيّن في هذه الحالة قيمة  الترويسة <code>from:</code> لجميع الرسائل في هذا الصنف. يمكن إعادة تعريف (override) هذا الحقل مع كل بريد إلكتروني على حدة.
* <code>mail</code>: رسالة البريد الإلكتروني الفعليّة التي نُمرّر الترويستين <code>to:</code> و <code>subject:</code> داخلها.
* <code>mail</code>: رسالة البريد الإلكتروني الفعليّة التي نُمرّر الترويستين <code>to:</code> و <code>subject:</code> داخلها.
تصبح أي متغيّرات نسخة نعرّفها في التابع متاحة للاستخدام في العرض مثل حالة وحدات التحكم تمامًا.
تصبح أي متغيّرات نسخة نعرّفها في التابع متاحة للاستخدام في العرض مثل حالة وحدات التحكم تمامًا.


==== إنشاء عرض لإجراء المراسلة ====
==== إنشاء عرض لـ Action Mailer ====
أنشئ ملفًا يسمّى welcome_email.html.erb في app/views/user_mailer/. سيُستخدم هذا القالب (template) للبريد الإلكتروني بتنسيق [[HTML]]:<syntaxhighlight lang="html">
أنشئ ملفًا يسمّى welcome_email.html.erb في ‎app/views/user_mailer/‎‎. سيُستخدم هذا القالب (template) للبريد الإلكتروني بتنسيق [[HTML]]:<syntaxhighlight lang="html">
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<html>
سطر 98: سطر 98:
Thanks for joining and have a great day!
Thanks for joining and have a great day!


</syntaxhighlight>عند استدعاء التابع <code>mail</code> الآن، سيكتشف إجراء المراسلة قالبين (النص و HTML) ويُنشئ بريدًا إلكترونيًّا multipart/alternative تلقائيًا.
</syntaxhighlight>عند استدعاء التابع <code>mail</code> الآن، سيكتشف [[Rails/action mailer|Action Mailer]] قالبين (النص و HTML) ويُنشئ بريدًا إلكترونيًّا multipart/alternative تلقائيًا.


==== استدعاء المرسل ====
==== استدعاء المرسل ====
سطر 110: سطر 110:
</syntaxhighlight>لدينا الآن نموذج مُستخدم للتلاعب به. سنُعدّل فقط على الملف app/controllers/users_controller.rb بجعله يرشد <code>UserMailer</code> لإرسال بريد إلكتروني للمستخدم حديث الإنشاء عبر تعديل إجراء الإنشاء (create action) وإدخال نداء إلى <code>UserMailer.with(user: @user).welcome_email</code> مباشرةً بعد حفظ المستخدم بنجاح.
</syntaxhighlight>لدينا الآن نموذج مُستخدم للتلاعب به. سنُعدّل فقط على الملف app/controllers/users_controller.rb بجعله يرشد <code>UserMailer</code> لإرسال بريد إلكتروني للمستخدم حديث الإنشاء عبر تعديل إجراء الإنشاء (create action) وإدخال نداء إلى <code>UserMailer.with(user: @user).welcome_email</code> مباشرةً بعد حفظ المستخدم بنجاح.


يتكامل إجراء المراسلة بشكل جيد مع الوظيفة الفعالة (Active Job)، لذا تتمكن من إرسال رسائل إلكترونيّة خارج دورة الطلب-الاستجابة، بحيث لا يضطر المستخدم إلى الانتظار:<syntaxhighlight lang="rails">
يتكامل [[Rails/action mailer|Action Mailer]] بشكل جيد مع [[Rails/active support|Active Job]]، لذا تتمكن من إرسال رسائل إلكترونيّة خارج دورة الطلب-الاستجابة، بحيث لا يضطر المستخدم إلى الانتظار:<syntaxhighlight lang="rails">
class UsersController < ApplicationController
class UsersController < ApplicationController
   # POST /users
   # POST /users
سطر 119: سطر 119:
     respond_to do |format|
     respond_to do |format|
       if @user.save
       if @user.save
         # Tell the UserMailer to send a welcome email after save
         # بإرسال بريد ترحيبي بعد حفظ UserMailer أخبر
         UserMailer.with(user: @user).welcome_email.deliver_later
         UserMailer.with(user: @user).welcome_email.deliver_later
   
   
سطر 131: سطر 131:
   end
   end
end
end
</syntaxhighlight>'''ملاحظة''': السلوك الافتراضي للوظيفة الفعالة (Active Job) هو تنفيذ المهام عبر المحوّل <code>async:</code>. لذا يمكنك استخدام <code>deliver_later</code> الآن لإرسال رسائل البريد الإلكتروني بشكل غير متزامن. يُشغّل محوّل الوظيفة الفعالة الافتراضي المهام مع مجمع خيوط قيد المعالجة. وهو مناسب تمامًا لبيئات التطوير/الاختبار، نظرًا لأنَّه لا يتطلب أي بنية تحتيّة خارجيّة ولكنه غير ملائم للإنتاج بما أنّه يزيل الوظائف المعلّقة عند إعادة التشغيل. إن كنت في حاجة إلى خلفيّة دائمة (persistent backend)، فستحتاج لاستخدام محوّل وظيفة فعالة (Active Job adapter) يحوي خلفيّة دائمة (Sidekiq ،Resque، إلخ).
</syntaxhighlight>'''ملاحظة''': السلوك الافتراضي لـ [[Rails/active support|Active Job]] هو تنفيذ المهام عبر المحوّل <code>async:</code>. لذا يمكنك استخدام <code>deliver_later</code> الآن لإرسال رسائل البريد الإلكتروني بشكل غير متزامن. يُشغّل محوّل [[Rails/active support|Active Job]] الافتراضي المهام مع مجمع خيوط قيد المعالجة. وهو مناسب تمامًا لبيئات التطوير/الاختبار، نظرًا لأنَّه لا يتطلب أي بنية تحتيّة خارجيّة ولكنه غير ملائم للإنتاج بما أنّه يزيل الوظائف المعلّقة عند إعادة التشغيل. إن كنت في حاجة إلى خلفيّة دائمة (persistent backend)، فستحتاج لاستخدام محوّل [[Rails/active support|Active Job]] (أي Active Job adapter) يحوي خلفيّة دائمة (Sidekiq ،Resque، ...إلخ).


إن رغبت في إرسال بريد إلكتروني على الفور (من cronjob على سبيل المثال) فقط استدعي <code>deliver_now</code>:<syntaxhighlight lang="rails">
إن رغبت في إرسال بريد إلكتروني على الفور (من cronjob على سبيل المثال) فقط استدعي <code>deliver_now</code>:<syntaxhighlight lang="rails">
سطر 141: سطر 141:
   end
   end
end
end
</syntaxhighlight>أي زوج قيم مفتاح مُمرّر إلى <code>with</code> يصبح <code>params</code> لإجراء المراسلة (mailer action). لذلك، يجعل
</syntaxhighlight>أي زوج قيم مفتاح مُمرّر إلى <code>with</code> يصبح <code>params</code> لـ [[Rails/action mailer|Action Mailer]]. لذلك، يجعل


<code>with(user: @user, account: @user.account)‎</code> المعاملين <code>params[:user]‎</code> و <code>params[:account]‎</code> متوفّرين في إجراء المراسلة.
<code>with(user: @user, account: @user.account)‎</code> المعاملين <code>params[:user]‎</code> و <code>params[:account]‎</code> متوفّرين في [[Rails/action mailer|Action Mailer]].


ويعيد التابع <code>welcome_email</code> كائنًا من النوع <code>ActionMailer::MessageDelivery</code> والذي يمكن إخباره لاحقًا بالإرسال الأن عبر <code>deliver_now</code> أو الإرسال لاحقًا عبر <code>deliver_later</code> لإرسال نفسه. الكائن <code>ActionMailer::MessageDelivery</code> هو مجرد غلاف (wrapper) حول <code>Mail::Message</code>. إن رغبت في فحص أو تغيير أو فعل بأي شيء آخر مع الكائن <code>Mail::Message</code>، تستطيع الوصول إليه عبر التابع <code>message</code> في الكائن <code>ActionMailer::MessageDelivery</code>.
ويعيد التابع <code>welcome_email</code> كائنًا من النوع <code>ActionMailer::MessageDelivery</code> والذي يمكن إخباره لاحقًا بالإرسال الأن عبر <code>deliver_now</code> أو الإرسال لاحقًا عبر <code>deliver_later</code> لإرسال نفسه. الكائن <code>ActionMailer::MessageDelivery</code> هو مجرد غلاف (wrapper) حول <code>Mail::Message</code>. إن رغبت في فحص أو تغيير أو فعل بأي شيء آخر مع الكائن <code>Mail::Message</code>، تستطيع الوصول إليه عبر التابع <code>message</code> في الكائن <code>ActionMailer::MessageDelivery</code>.


=== التشفير التلقائي لقيم الترويسة ===
=== التشفير التلقائي لقيم الترويسة ===
يعالج إجراء المراسلة الترميز التلقائي لأحرف متعددة البايت داخل الترويسات وجسم الرسالة.
يعالج [[Rails/action mailer|Action Mailer]] الترميز التلقائي لأحرف متعددة البايت داخل الترويسات وجسم الرسالة.


لأمثلة أكثر تعقيدًا مثل تعريف مجموعات أحرف بديلة أو ترميز النص ذاتيًّا أولًا، الرجاء الرجوع إلى المكتبة [https://github.com/mikel/mail Mail].
لأمثلة أكثر تعقيدًا مثل تعريف مجموعات أحرف بديلة أو ترميز النص ذاتيًّا أولًا، الرجاء الرجوع إلى المكتبة [https://github.com/mikel/mail Mail].


=== قائمة توابع إجراء المراسلة الكاملة ===
=== قائمة توابع Action Mailer الكاملة ===
تحتاج ثلاثة توابع فقط لأي رسالة بريد إلكتروني:
تحتاج ثلاثة توابع فقط لأي رسالة بريد إلكتروني:
* <code>headers</code> - يحدّد أي ترويسة بريد تريدها. تستطيع تمرير [[Ruby/Hash|جدول Hash]] بأسماء حقول وأزواج القيم أو يمكنك استدعاءه بالشكل <code>headers[:field_name]‎ = 'value'‎</code>.
* <code>headers</code> - يحدّد أي ترويسة بريد تريدها. تستطيع تمرير [[Ruby/Hash|جدول Hash]] بأسماء حقول وأزواج القيم أو يمكنك استدعاءه بالشكل <code>headers[:field_name]‎ = 'value'‎</code>.
سطر 161: سطر 161:


==== إضافة المرفقات ====
==== إضافة المرفقات ====
يُسهّل إجراء المراسلة إضافة المرفقات.
يُسهّل [[Rails/action mailer|Action Mailer]] إضافة المرفقات.
* مرّر اسم الملف والمحتوى وسيخمّن إجراء المراسلة و[https://github.com/mikel/mail جوهرة البريد] (Mail gem) تلقائيًا النوع MIME، ويضبط التشفير وينشئ المُرفق.
* مرّر اسم الملف والمحتوى وسيخمّن [[Rails/action mailer|Action Mailer]] و[https://github.com/mikel/mail جوهرة البريد] (Mail gem) تلقائيًا النوع MIME، ويضبط التشفير وينشئ المُرفق.
<syntaxhighlight lang="rails">
<syntaxhighlight lang="rails">
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
سطر 168: سطر 168:


'''ملاحظة''': سيُشفّر البريد المُرفق تلقائيا بتشفير Base64. إن أردت شيئًا مختلفًا شفّر مُحتواك ومرّره المحتوى المشفّر وترميزه داخل [[Ruby/Hash|جدول Hash]] إلى التابع <code>attachments</code>.
'''ملاحظة''': سيُشفّر البريد المُرفق تلقائيا بتشفير Base64. إن أردت شيئًا مختلفًا شفّر مُحتواك ومرّره المحتوى المشفّر وترميزه داخل [[Ruby/Hash|جدول Hash]] إلى التابع <code>attachments</code>.
* مرّر اسم الملف وحدد الترويسة والمحتوى وسيستخدم إجراء المراسلة و <code>mail</code> الإعدادات التي تمررها.
* مرّر اسم الملف وحدد الترويسة والمحتوى وسيستخدم [[Rails/action mailer|Action Mailer]] و <code>mail</code> الإعدادات التي تمررها.
<syntaxhighlight lang="rails">
<syntaxhighlight lang="rails">
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
سطر 179: سطر 179:


==== إنشاء مرفقات مضمّنة (Making Inline Attachments) ====
==== إنشاء مرفقات مضمّنة (Making Inline Attachments) ====
يجعل إجراء المراسلة 3.0 المُرفقات المضمّنة - والتي تطلّبت الكثير من التلاعب في الإصدارات قبل 3.0 - بالبساطة والسهولة كما يجدر بها أن تكون.
يجعل [[Rails/action mailer|Action Mailer]] 3.0 المُرفقات المضمّنة - والتي تطلّبت الكثير من التلاعب في الإصدارات قبل 3.0 - بالبساطة والسهولة كما يجدر بها أن تكون.
* أولًا لتأمر mail يتحويل مُرفق إلى مُرفق مضمّن (Inline Attachment) عليك فقط استدعاء <code>inline.</code> مع تابع المرفقات داخل مُرسلك (Mailer):
* أولًا لتأمر <code>mail</code> بتحويل مُرفق إلى مُرفق مضمّن (Inline Attachment)، عليك فقط استدعاء <code>inline.</code> مع تابع المرفقات داخل مُرسلك (Mailer):
<syntaxhighlight lang="rails">
<syntaxhighlight lang="rails">
def welcome
def welcome
سطر 222: سطر 222:


=== عروض المرسل (Mailer Views) ===
=== عروض المرسل (Mailer Views) ===
تُوجد عروض المُرسل (Mailer) في المُجلّد app/views/name_of_mailer_class. يعرف الصنف عرض مرسل البريد المحدّد تلقائيًّا لأنَّ اسمه مماثل لتابع المُرسل. في المثال الوارد أعلاه، سيكون عرض مُرسل بريدنا للتابع <code>welcome_email</code> هو app/views/user_mailer/welcome_email.html.erb بالنسبة للنسخة [[HTML]] و welcome_email.text.erb لنسخة النص العادي.
تُوجد عروض المُرسل (Mailer) في المُجلّد app/views/name_of_mailer_class. يعرف الصنف عرض مرسل البريد المحدّد تلقائيًّا لأنَّ اسمه مماثل لتابع المُرسل. في المثال الوارد أعلاه، سيكون عرض مُرسل بريدنا للتابع <code>welcome_email</code> هو pp/views/user_mailer/welcome_email.html.erb بالنسبة للنسخة [[HTML]] و welcome_email.text.erb لنسخة النص العادي.


لتغيير عرض المُرسل الافتراضي لإجرائك (action)،نفّذ ما يلي:<syntaxhighlight lang="rails">
لتغيير عرض المُرسل الافتراضي لإجرائك (action)، نفّذ ما يلي:<syntaxhighlight lang="rails">
class UserMailer < ApplicationMailer
class UserMailer < ApplicationMailer
   default from: 'notifications@example.com'
   default from: 'notifications@example.com'
سطر 266: سطر 266:
</syntaxhighlight>يُدعم التخزين المؤقت للأجزاء أيضًا في رسائل البريد متعدّدة الأجزاء. اقرأ المزيد حول التخزين المؤقت في [[Rails/caching with rails|دليل التخزين المؤقت]] في ريلز.
</syntaxhighlight>يُدعم التخزين المؤقت للأجزاء أيضًا في رسائل البريد متعدّدة الأجزاء. اقرأ المزيد حول التخزين المؤقت في [[Rails/caching with rails|دليل التخزين المؤقت]] في ريلز.


=== تخطيطات إجراء المراسلة ===
=== تخطيطات Action Mailer ===
يملك مُرسل البريد تخطيطات تمامًا مثل عروض وحدات التحكّم. يجب أن يكون اسم التخطيط نفس اسم مُرسلك مثل user_mailer.html.erb و user_mailer.text.erb كي يُتعرّف عليه تلقائيًا كتخطيط من طرف مُرسلك.
يملك مُرسل البريد تخطيطات تمامًا مثل عروض وحدات التحكّم. يجب أن يكون اسم التخطيط نفس اسم مُرسلك مثل user_mailer.html.erb و user_mailer.text.erb كي يُتعرّف عليه تلقائيًا كتخطيط من طرف مُرسلك.


سطر 287: سطر 287:


=== معاينة رسائل البريد الإلكتروني (Previewing Emails) ===
=== معاينة رسائل البريد الإلكتروني (Previewing Emails) ===
توفر معاينات إجراء المراسلة طريقة لمعرفة كيفيّة ظهور الرسائل الإلكترونية من خلال زيارة عنوان URL خاص يعرضها. يجب تسمية صنف معاينة <code>UserMailer</code> في المثال أعلاه <code>UserMailerPreview</code> ووضعه في test/mailers/previews/user_mailer_preview.rb. لمشاهدة معاينة <code>welcome_email</code>، عرّف استخدام تابع له نفس الاسم واستدعي <code>UserMailer.welcome_email</code>:<syntaxhighlight lang="rails">
توفر معاينات [[Rails/action mailer|Action Mailer]] طريقة لمعرفة كيفيّة ظهور الرسائل الإلكترونية من خلال زيارة عنوان URL خاص يعرضها. يجب تسمية صنف معاينة <code>UserMailer</code> في المثال أعلاه <code>UserMailerPreview</code> ووضعه في test/mailers/previews/user_mailer_preview.rb. لمشاهدة معاينة <code>welcome_email</code>، عرّف استخدام تابع له نفس الاسم واستدعي <code>UserMailer.welcome_email</code>:<syntaxhighlight lang="rails">
class UserMailerPreview < ActionMailer::Preview
class UserMailerPreview < ActionMailer::Preview
   def welcome_email
   def welcome_email
سطر 301: سطر 301:
</syntaxhighlight>
</syntaxhighlight>


=== توليد العناوين URL في عروض إجراء المراسلة ===
=== توليد العناوين URL في عروض Action Mailer ===
لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل <code>host:</code> بنفسك.
لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل <code>host:</code> بنفسك.


سطر 328: سطر 328:
</syntaxhighlight>'''ملاحظة''': تتطلب الروابط غير GET استخدام [https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts rails-ujs] أو [https://github.com/rails/jquery-ujs jQuery UJS] ولن تعمل في قوالب المُرسل (mailer templates). سيؤدي ذلك إلى طلبات GET العادية.
</syntaxhighlight>'''ملاحظة''': تتطلب الروابط غير GET استخدام [https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts rails-ujs] أو [https://github.com/rails/jquery-ujs jQuery UJS] ولن تعمل في قوالب المُرسل (mailer templates). سيؤدي ذلك إلى طلبات GET العادية.


=== إضافة الصور في عروض إجراء المراسلة ===
=== إضافة الصور في عروض Action Mailer ===
لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل <code>asset_host:</code> بنفسك.
لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل <code>asset_host:</code> بنفسك.


سطر 338: سطر 338:


=== إرسال رسائل متعددة الأجزاء ===
=== إرسال رسائل متعددة الأجزاء ===
سيُرسل إجراء المراسلة رسائل إلكترونيّة متعددة الأجزاء تلقائيًا إن كان لديك قوالب مختلفة لنفس الإجراء (action). لذلك، سيُسرسل إجراء المراسلة تلقائيًا رسالة إلكترونيّة متعدّدة الأجزاء مع نسختين نصيّة و HTML مُعدّتين كجزئين مختلفين بالنسبة لمثالنا <code>UserMailer</code> إن كان الملف welcome_email.text.erb والملف welcome_email.html.erb موجودين في app/views/user_mailer.
سيُرسل [[Rails/action mailer|Action Mailer]] رسائل إلكترونيّة متعددة الأجزاء تلقائيًا إن كان لديك قوالب مختلفة لنفس الإجراء (action). لذلك، سيُسرسل [[Rails/action mailer|Action Mailer]] تلقائيًا رسالة إلكترونيّة متعدّدة الأجزاء مع نسختين نصيّة و HTML مُعدّتين كجزئين مختلفين بالنسبة لمثالنا <code>UserMailer</code> إن كان الملف welcome_email.text.erb والملف welcome_email.html.erb موجودين في app/views/user_mailer.


يُحدّد <code>parts_order:</code> ترتيب الأجزاء التي تُدخَل داخل التابع <code>ActionMailer::Base.default</code>.
يُحدّد <code>parts_order:</code> ترتيب الأجزاء التي تُدخَل داخل التابع <code>ActionMailer::Base.default</code>.
سطر 371: سطر 371:


== استلام رسائل البريد الإلكتروني ==
== استلام رسائل البريد الإلكتروني ==
يمكن أن يكون تلقي رسائل البريد الإلكتروني وتحليلها باستخدام إجراء المراسلة معقّدًا نوعًا ما. عليك إعداد نظامك لتوجيه رسائل البريد إلى تطبيقك بطريقة ما، قبل وصول بريد إلكتروني إلى تطبيقك ريلز، والذي يحتاج للاستماع كي يتحقّق. لذلك لتلقي رسائل البريد الإلكتروني في تطبيق ريلز ستحتاج إلى:
يمكن أن يكون تلقي رسائل البريد الإلكتروني وتحليلها باستخدام [[Rails/action mailer|Action Mailer]] معقّدًا نوعًا ما. عليك إعداد نظامك لتوجيه رسائل البريد إلى تطبيقك بطريقة ما، قبل وصول بريد إلكتروني إلى تطبيقك ريلز، والذي يحتاج للاستماع كي يتحقّق. لذلك لتلقي رسائل البريد الإلكتروني في تطبيق ريلز ستحتاج إلى:
* تعريف استخدام التابع <code>receive</code> في مُرسل بريدك.
* تعريف استخدام التابع <code>receive</code> في مُرسل بريدك.
* إعداد خادم بريدك الإلكتروني لإعادة توجيه الرسائل من العنوان (أو العناوين) الذي تريد استلام رسائل البريد الإلكتروني إلى <code>‎/path/to/app/bin/rails runner 'UserMailer.receive(STDIN.read)'</code>‎ .
* إعداد خادم بريدك الإلكتروني لإعادة توجيه الرسائل من العنوان (أو العناوين) الذي تريد استلام رسائل البريد الإلكتروني إلى <code>‎/path/to/app/bin/rails runner 'UserMailer.receive(STDIN.read)'</code>‎ .
يُحلّل (parse) إجراء المراسلة البريد الإلكتروني الوارد الخام بمجرّد تعريف التابع المُسمّى <code>receive</code> جاعلًا منه كائن بريد إلكتروني، ثم يفك ترميزه، وينشئ نسخة مُرسل بريد جديدة، ويُمرّر كائن البريد الإلكتروني إلى تابع نُسخة المُرسل <code>receive</code>. إليك مثال على ذلك:<syntaxhighlight lang="rails">
يُحلّل [[Rails/action mailer|Action Mailer]] البريد الإلكتروني الوارد الخام بمجرّد تعريف التابع المُسمّى <code>receive</code> جاعلًا منه كائن بريد إلكتروني، ثم يفك ترميزه، وينشئ نسخة مُرسل بريد جديدة، ويُمرّر كائن البريد الإلكتروني إلى تابع نُسخة المُرسل <code>receive</code>. إليك مثال على ذلك:<syntaxhighlight lang="rails">
class UserMailer < ApplicationMailer
class UserMailer < ApplicationMailer
   def receive(email)
   def receive(email)
سطر 395: سطر 395:
</syntaxhighlight>
</syntaxhighlight>


== ردود نداء إجراء المراسلة ==
== ردود نداء Action Mailer ==
يتيح لك إجراء المراسلة تحديد <code>before_action</code> و <code>after_action</code> و <code>around_action</code>.
يتيح لك [[Rails/action mailer|Action Mailer]] تحديد <code>before_action</code> و <code>after_action</code> و <code>around_action</code>.
* يمكن تحديد الفلاتر ببُنية أو رمز لتابع في صنف مرسل البريد بشكل شبيه بوحدات التحكّم.
* يمكن تحديد الفلاتر ببُنية أو رمز لتابع في صنف مرسل البريد بشكل شبيه بوحدات التحكّم.
* تستطيع استخدام <code>before_action</code> لتعبئة كائن البريد افتراضيًا أو <code>delivery_method_options</code> أو إدراج ترويسات ومرفقات افتراضية.
* تستطيع استخدام <code>before_action</code> لتعبئة كائن البريد افتراضيًا أو <code>delivery_method_options</code> أو إدراج ترويسات ومرفقات افتراضية.
سطر 459: سطر 459:
end
end
</syntaxhighlight>
</syntaxhighlight>
* تقوم مرشحات إجراء المراسلة بإحباط المعالجة الإضافيّة إن ضبط جسم الرسالة إلى قيمة غير معدومة (non-nil).
* تقوم مرشحات [[Rails/action mailer|Action Mailer]] بإحباط المعالجة الإضافيّة إن ضبط جسم الرسالة إلى قيمة غير معدومة (non-nil).


== استخدام مساعدي مُرسل الأفعال إجراء المراسلة ==
== استخدام مساعدي Action Mailer ==
يرث إجراء المراسلة الآن من AbstractController، لذلك لديك حق الوصول إلى نفس المُساعدات العاديّة كما تفعل في Action Controller.
يرث [[Rails/action mailer|Action Mailer]] الآن من <code>AbstractController</code>، لذلك لديك حق الوصول إلى نفس المُساعدات العاديّة كما تفعل عادةً مع إجراء التحكم (Action Controller).


== إعداد مُرسل البريد ==
== ضبط Action Mailer ==
من الأفضل وضع خيارات التكوين التالية في أحد ملفات البيئة (environment.rb ،production.rb، إلخ ...)
من الأفضل وضع خيارات الضبط التالية في أحد ملفات البيئة (environment.rb، أو production.rb، ...إلخ):
{| class="wikitable"
{| class="wikitable"
|الإعداد
!الإعداد
|الوصف
!الوصف
|-
|-
|logger
|<code>logger</code>
|يولّد معلومات حول الدورة البريديّة (mailing run) إن توفّرت. يمكن ضبطه على nil كي لا يُسجّل أي شيء. يتوافق مع كل من مُسجّل روبي Logger والمسجّلات Log4r.
|يولّد معلومات حول الدورة البريديّة (mailing run) إن توفّرت. يمكن ضبطه إلى القيمة <code>nil</code> كي لا يُسجّل أي شيء. يتوافق مع كل من مُسجّل روبي Logger والمسجّلات Log4r.
|-
|-
|smtp_settings
|<code>smtp_settings</code>
|يسمح بالإعداد المُفصّل لتابع التسليم smtp:
|يسمح بالإعداد المُفصّل لتابع التسليم <code>smtp</code>:
* address: - يسمح لك باستخدام خادم بريد عن بعد. كل ما عليك هو تغييره عن إعداده "localhost" الافتراضي.
* <code>address:‎</code> - يسمح لك باستخدام خادم بريد عن بعد. كل ما عليك هو تغييره عن إعداده "localhost" الافتراضي.
* port: - تستطيع في حالة عدم عمل خادم بريدك على المنفذ 25 تغييره.
* <code>port:‎</code> - تستطيع تغييره في حال عدم عمل خادم بريدك على المنفذ 25.
* domain: - تستطيع إن إحتجت لتحديد نطاق HELO فعل ذلك هنا.
* <code>domain:‎</code> - تستطيع إن إحتجت لتحديد نطاق HELO فعل ذلك هنا.
* user_name: - إن تطلّب خادم بريدك الإستيثاق عيّن اسم مستخدم في هذا الإعداد.
* <code>user_name:‎</code> - إن تطلّب خادم بريدك الاستيثاق، عيّن اسم مستخدم في هذا الإعداد.
* password: - إن تطلّب خادم بريدك الإستيثاق عيّن كلمة المرور في هذا الإعداد.
* <code>password:‎</code> - إن تطلّب خادم بريدك الاستيثاق عيّن كلمة المرور في هذا الإعداد.
* authentication: - إن تطلّب خادم بريدك الإستيثاق ستحتاج إلى تحديد نوعه في هذا الإعداد. هذا رمز وواحد من plain: (يرسل كلمة المرور بشكل واضح) و login: (سيرسل كلمة المرور المشفّرة على Base64) أو cram_md5: (يجمع آلية تحدّي/استجابة لتبادل المعلومات وخوارزميّة Message Digest 5 المُشفّرة لتجزئة المعلومات المهمّة)
* <code>authentication:‎</code> - إن تطلّب خادم بريدك الاستيثاق، ستحتاج إلى تحديد نوعه في هذا الإعداد. هذا رمزٌ وواحدٌ من <code>plain:‎</code> (يرسل كلمة المرور بشكل واضح) و <code>login:‎</code> (سيرسل كلمة المرور المشفّرة على Base64) أو <code>cram_md5:‎</code> (يجمع آلية تحدّي/استجابة لتبادل المعلومات وخوارزميّة Message Digest 5 المُشفّرة لتجزئة المعلومات المهمّة)
* enable_starttls_auto: - يكتشف ما إن فُعّل STARTTLS في خادمك SMTP ويبدأ في استخدامه. إفتراضيّاً true.
* <code>enable_starttls_auto:‎</code> - يكتشف إن فُعّل STARTTLS في خادمك SMTP ويبدأ في استخدامه. القيمة الافتراضية له هي <code>true</code>.
* openssl_verify_mode: - عند استخدام TLS تستطيع ضبط كيفيّة تحقّق OpenSSL من الشهادة. يكون هذا مفيدًا حقًا إن إحتجت للتحقّق من صحّة شهادة ذاتيّة التوقيع و/أو بطاقة بدل (wildcard certificate). تستطيع استخدام اسم OpenSSL للتحقق من الثابت ('none' أو 'peer') أو مباشرة من الثابت ( OpenSSL::SSL::VERIFY_NONE أو OpenSSL::SSL::VERIFY_PEER)
* <code>openssl_verify_mode:‎</code> - عند استخدام TLS، تستطيع ضبط كيفيّة تحقّق OpenSSL من الشهادة. يكون هذا مفيدًا حقًا إن احتجت للتحقّق من صحّة شهادة ذاتيّة التوقيع و/أو بطاقة بدل (wildcard certificate). تستطيع استخدام اسم OpenSSL للتحقق من الثابت ('none' أو 'peer') أو مباشرة من الثابت ( OpenSSL::SSL::VERIFY_NONE أو OpenSSL::SSL::VERIFY_PEER).
|-
|-
|sendmail_settings
|<code>sendmail_settings</code>
|يسمح لك بإعادة تعريف خيارات تابع التسليم sendmail:
|يسمح لك بإعادة تعريف خيارات تابع التسليم <code>sendmail:‎</code>.
* location: - موقع ملف sendmail التنفيذي (executable). إفتراضيًّا هي /usr/sbin/sendmail .
* <code>location:‎</code> - موقع ملف <code>sendmail</code> التنفيذي (executable). القيمة الافتراضية هي /usr/sbin/sendmail .
* arguments: - مُتغيّرات سطر الأوامر التي ستُمرّر إلى sendmail. إفتراضيًّا -i.
* <code>arguments:‎</code> - مُتغيّرات سطر الأوامر التي ستُمرّر إلى <code>sendmail</code>. القيمة الافتراضية هي ‎<code>-i</code>.
|-
|-
|raise_delivery_errors
|<code>raise_delivery_errors</code>
|ما إن وجب رفع الأخطاء أم لا إن لم يُسلّم البريد الإلكتروني. يعمل هذا الإعداد فقط إن أُعدّ خادم البريد الإلكتروني الخارجي للتسليم الفوري.
|يحدِّد إن وجب رفع الأخطاء أم لا إن لم يُسلّم البريد الإلكتروني. يعمل هذا الإعداد فقط إن أُعدّ خادم البريد الإلكتروني الخارجي للتسليم الفوري.
|-
|-
|delivery_method
|<code>delivery_method</code>
|يُعرّف تابع تسليم. القيم المحتملة هي:
|يُعرّف تابع تسليم. القيم المحتملة هي:
* smtp: (افتراضي) يمكن إعداده باستخدام config.action_mailer.smtp_settings
* <code>smtp:‎</code>: (الافتراضية) يمكن إعداده باستخدام <code>config.action_mailer.smtp_settings</code>.
* sendmail: يمكن إعداده باستخدام config.action_mailer.sendmail_settings.
* <code>sendmail:‎</code>: يمكن إعداده باستخدام <code>config.action_mailer.sendmail_settings</code>.
* file: حفظ رسائل البريد الإلكتروني بملفّات. يمكن إعداده باستخدام config.action_mailer.file_settings.
* <code>file:‎</code>:  حفظ رسائل البريد الإلكتروني بملفّات. يمكن إعداده باستخدام <code>config.action_mailer.file_settings</code>.
* test: حفظ رسائل البريد الإلكتروني في ActionMailer::Base.deliveries
* <code>test:‎</code>: حفظ رسائل البريد الإلكتروني في <code>ActionMailer::Base.deliveries</code>.
راجع توثيقات API لمزيد من المعلومات.
راجع توثيقات API لمزيد من المعلومات.
|-
|-
|perform_deliveries
|<code>perform_deliveries</code>
|يحدّد إن نُفّذت عمليات التسليم فعلًا عند مُناداة التابع deliver على رسالة البريد. ذلك هو الوضع إفتراضيًّا ولكن يمكن إيقاف تشغيله للمساعدة في الاختبار الوظيفي.
|يحدّد إن نُفّذت عمليات التسليم فعلًا عند استدعاء التابع <code>deliver</code> على رسالة البريد. ذلك هو الوضع افتراضيًّا ولكن يمكن إيقاف تشغيله للمساعدة في الاختبار الوظيفي.
|-
|-
|deliveries
|<code>deliveries</code>
|يحافظ على مصفوفة من جميع الرسائل المرسلة عبر إجراء المراسلة  مع delivery_method :test. مفيدة خاصّة بلاختبار الوحدوي والوظيفي.
|يحافظ على مصفوفة من جميع الرسائل المرسلة عبر [[Rails/action mailer|Action Mailer]] مع <code>delivery_method :test</code>. مفيدة خاصّة بلاختبار الوحدوي والوظيفي.
|-
|-
|default_options
|<code>default_options</code>
|تسمح لك بتعيين القيم الافتراضية لخيارات التابع mail (مثل from: و reply_to: وما إلى ذلك).
|تسمح لك بتعيين القيم الافتراضية لخيارات التابع <code>mail</code> (مثل <code>from:‎</code> و <code>reply_to:‎</code> وما إلى ذلك).
|}
|}
للحصول على معلومات كاملة عن الإعدادات المحتملة راجع توثيق إعداد إجراء المراسلة في دليلنا إعداد تطبيقات ريلز.
للحصول على معلومات كاملة عن الإعدادات المحتملة، راجع توثيق إعداد [[Rails/action mailer|Action Mailer]] في دليل [[Rails/configuring|ضبط تطبيقات ريلز]].
 
== مثال لإعداد إجراء المراسلة ==
مثال على ذلك هو إضافة ما يلي بملفك config/environments/$RAILS_ENV.rb المناسب:
{| class="wikitable"
|config.action_mailer.delivery_method = :sendmail
 
<nowiki>#</nowiki> Defaults to:
 
<nowiki>#</nowiki> config.action_mailer.sendmail_settings = {
 
<nowiki>#</nowiki>   location: '/usr/sbin/sendmail',
 
<nowiki>#</nowiki>   arguments: '-i'
 
<nowiki>#</nowiki> }


=== مثال عن إعداد Action Mailer ===
مثال على ذلك هو إضافة ما يلي بملفك config/environments/$RAILS_ENV.rb المناسب:<syntaxhighlight lang="rails">
config.action_mailer.delivery_method = :sendmail
# :القيم الافتراضية هي
# config.action_mailer.sendmail_settings = {
#  location: '/usr/sbin/sendmail',
#  arguments: '-i'
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'no-reply@example.com'}
config.action_mailer.default_options = {from: 'no-reply@example.com'}
|}
</syntaxhighlight>
 
=== إعداد إجراء المراسلة لـ Gmail ===
بما أن إجراء المراسلة يستخدم الآن جوهرة البريد تصبح العمليّة ببساطة الإضافة إلى ملفكconfig/environments/$RAILS_ENV.rb:
{| class="wikitable"
|config.action_mailer.delivery_method = :smtp


=== إعداد Action Mailer مع Gmail ===
بما أن [[Rails/action mailer|Action Mailer]] يستخدم الآن جوهرة البريد، تصبح العمليّة ببساطة إضافة ما يلي إلى ملفك config/environments/$RAILS_ENV.rb:<syntaxhighlight lang="rails">
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
config.action_mailer.smtp_settings = {
 
  address:             'smtp.gmail.com',
 address:           'smtp.gmail.com',
  port:                 587,
 
  domain:               'example.com',
 port:              587,
  user_name:           '<username>',
 
  password:             '<password>',
 domain:            'example.com',
  authentication:       'plain',
 
  enable_starttls_auto: true }
 user_name:         '<username>',
</syntaxhighlight>'''ملاحظة''': بدءًا من 15 تموز 2014، عمدت Google إلى زيادة [https://support.google.com/accounts/answer/6010255 إجراءاتها الأمنيّة]،  إذ تحظر الآن محاولات التطبيقات التي تراها أقل أمانًا. تستطيع تغيير إعدادات حسابك Gmail هنا للسماح بالمحاولات. إن كانت المصادقة الثنائية (‎2-factor authentication) مُفعّلة بحسابك Gmail، فستحتاج لتعيين [https://myaccount.google.com/apppasswords كلمة مرور تطبيق] واستخدامها بدلًا من كلمة مرورك العاديّة. أو تستطيع بدلًا من ذلك استخدام ESP آخر لإرسال البريد الإلكتروني عن طريق استبدال "smtp.gmail.com" أعلاه بعنوان موفّرك.
 
== اختبار مرسل البريد (Mailer Testing) ==
 password:          '<password>',
تستطيع إيجاد تعليمات مفصّلة حول كيفيّة اختبار مُرسلي بريدك في [[Rails/testing#.D8.A7.D8.AE.D8.AA.D8.A8.D8.A7.D8.B1 .D8.A5.D8.AC.D8.B1.D8.A7.D8.A1 .D8.A7.D9.84.D9.85.D8.B1.D8.A7.D8.B3.D9.84.D8.A9 .D8.A7.D9.84.D8.AE.D8.A7.D8.B5 .D8.A8.D9.83|دليل الاختبار]].
 
 authentication:    'plain',
 
 enable_starttls_auto: true }
|}
ملاحظة: اعتبارًا من 15 تموز 2014 عمدت Google إلى زيادة إجراءاتها الأمنيّة وتحظر الآن محاولات التطبيقات التي تراها أقل أمانًا. تستطيع تغيير إعدادات حسابك Gmail هنا للسماح بالمحاولات. إن كانت المصادقة الثنائيةمُفعّلة  بحسابك Gmail ستحتاج لتعيين كلمة مرور تطبيق واستخدامها بدلاً من كلمة مرورك العاديّة. أو تستطيع بدلاً من ذلك استخدام ESP آخر لإرسال البريد الإلكتروني عن طريق استبدال "smtp.gmail.com" أعلاه بعنوان موفّرك.
 
== اختبار مُرسل البريد (Mailer Testing) ==
تستطيع إيجاد تعليمات مفصّلة حول كيفيّة اختبار مُرسلي بريدك في دليل الاختبار.


== اعتراض رسائل البريد الإلكتروني ==
== اعتراض رسائل البريد الإلكتروني ==
هناك حالات تحتاج فيها لتعديل بريد إلكتروني قبل تسليمه. لحسن الحظ يوفّر إجراء المراسلة خطافًا لاعتراض كل بريد إلكتروني. تستطيع تسجيل مُعترض لإجراء تعديلات على رسائل البريد قبل تسليمها لوكلاء التوصيل مباشرة.
هناك حالات تحتاج فيها لتعديل بريد إلكتروني قبل تسليمه. لحسن الحظ يوفّر [[Rails/action mailer|Action Mailer]] خطافًا لاعتراض كل بريد إلكتروني. تستطيع تسجيل مُعترض لإجراء تعديلات على رسائل البريد قبل تسليمها لوكلاء التوصيل مباشرة.<syntaxhighlight lang="rails">
{| class="wikitable"
class SandboxEmailInterceptor
|class SandboxEmailInterceptor
  def self.delivering_email(message)
 
    message.to = ['sandbox@example.com']
 def self.delivering_email(message)
  end
 
   message.to = ['sandbox@example.com']
 
 end
 
end
end
|}
</syntaxhighlight>يجب تسجيل المُعترض في إطار عمل [[Rails/action mailer|Action Mailer]] قبل أن يتمكن من القيام بواجبه. يمكنك ذلك في ملف تهيئة (initializer) من config/initializers/sandbox_email_interceptor.rb:<syntaxhighlight lang="rails">
يجب تسجيل المُعترض في إطار عمل إجراء المراسلة قبل أن يتمكن من القيام بواجبه. يمكنك ذلك في ملف تهيئة (initializer) من config/initializers/sandbox_email_interceptor.rb
if Rails.env.staging?
{| class="wikitable"
  ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
|if ريلز.env.staging?
 
 ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
 
end
end
|}
</syntaxhighlight>'''ملاحظة''': يستخدم المثال أعلاه بيئة مخصصّة تسمى "منصة الإطلاق" (staging) لاختبار خادم شبيه بخادم الإنتاج ولكن لأغراض الاختبار. تستطيع قراءة القسم "إنشاء بيئات ريلز" في دليل [[Rails/configuring|ضبط تطبيقات ريلز]]  لمزيد من المعلومات حول بيئات ريلز المخصصّة.
يستخدم المثال أعلاه بيئة مخصصّة تسمى "التدريج" لاختبار خادم شبيه بخادم الإنتاج ولكن لأغراض الاختبار. تستطيع قراءة إنشاء بيئات ريلز لمزيد من المعلومات حول بيئات ريلز المخصصّة.
== مصادر ==
 
* [https://guides.rubyonrails.org/action_mailer_basics.html صفحة Action Mailer Basics في توثيق Ruby On Rails الرسمي.]
== مصدر ==
[[تصنيف:Rails]]
* صفحة إجراء المراسلة بتوثيق ريلز
[[تصنيف:Rails Digging Deeper]]

المراجعة الحالية بتاريخ 06:47، 25 مارس 2019

يوفّر لك هذا الدليل كل ما تحتاجه للبدء في إرسال واستقبال رسائل البريد الإلكتروني من وإلى تطبيقك، والعديد من عمليّات Action Mailer الداخليّة. كما يغطي كيفية اختبار مُرسلي بريدك (mailers).

ستتعلم بعد قراءة هذا الدليل:

  • كيفيّة إرسال واستقبال البريد الإلكتروني داخل تطبيق ريلز.
  • كيفيّة إنشاء وتعديل صنف Action Mailer والعرض المرتبط به.
  • كيفيّة إعداد Action Mailer لبيئتك.
  • كيفيّة اختبار أصنافك لـ Action Mailer.

مقدمة

يسمح لك Action Mailer بإرسال رسائل البريد الإلكتروني من تطبيقك باستخدام الأصناف mailer والعروض المرتبطة بها (views).

تعمل مُرسلات البريد بطريقة مشابهة جدًا لوحدات التحكّم. وهي ترث من ActionMailer::Base وتتوضع في app/mailers ولديها عروض مرتبطة تظهر في app/views.

إرسال البريد الإلكتروني

سيوفر هذا القسم دليلًا مُفصّلًا لإنشاء مُرسل بريد والعروض المرتبطة به.

خطوات إنشاء مرسل بريد إلكتروني

إنشاء المرسل

$ bin/rails generate mailer UserMailer
create  app/mailers/user_mailer.rb
create  app/mailers/application_mailer.rb
invoke  erb
create    app/views/user_mailer
create    app/views/layouts/mailer.text.erb
create    app/views/layouts/mailer.html.erb
invoke  test_unit
create    test/mailers/user_mailer_test.rb
create    test/mailers/previews/user_mailer_preview.rb
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "from@example.com"
  layout 'mailer'
end
 
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
end

كما ترى، يمكنك توليد مُرسلات بريد مثلما تستخدم المولّدات الأخرى مع ريلز. تتشابه مُرسلات البريد من الناحية النظرية مع وحدات التحكّم، ولذلك نحصل على مُرسل بريد ومجلّد للعروض واختبار. إن لم ترغب في استخدام مولّد، يمكنك إنشاء ملفك الخاص داخل app/mailers لكن المهم أن تتأكّد أنّه يرث من ActionMailer::Base:

class MyMailer < ActionMailer::Base
end

تعديل المرسل

تشبه مُرسلات البريد الإلكتروني إلى حد بعيد وحدات تحكّم ريلز. لديها أيضا توابع تسمّى "إجراءات" (actions) وتستخدم العروض لهيكلة المحتوى. يُنشئ مرسلٌ رسالة للتسليم عبر البريد الإلكتروني عندما تُولّد وحدة التحكّم محتوى مثل HTML لإرساله مرة أخرى إلى العميل.

يحتوي app/mailers/user_mailer.rb على مُرسل بريد فارغ.

class UserMailer < ApplicationMailer
end

فلنضف تابعًا باسم welcome_email يرسل بريدًا إلكترونيًا إلى عنوان البريد الإلكتروني المسجل للمستخدم:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'
 
  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end

فيما يلي شرح سريع للعناصر المعروضة في التابع. للحصول على قائمة كاملة بجميع الخيارات المتاحة، يرجى إلقاء نظرة أدناه في قسم "قائمة خصائص Action Mailer الكاملة القابلة للتعيين من طرف المستخدم".

  • default: (كائن Hash) يمثِّل جدول Hash للقيم الافتراضية لأي بريد إلكتروني ترسله من هذا المُرسل. نُعيّن في هذه الحالة قيمة  الترويسة from: لجميع الرسائل في هذا الصنف. يمكن إعادة تعريف (override) هذا الحقل مع كل بريد إلكتروني على حدة.
  • mail: رسالة البريد الإلكتروني الفعليّة التي نُمرّر الترويستين to: و subject: داخلها.

تصبح أي متغيّرات نسخة نعرّفها في التابع متاحة للاستخدام في العرض مثل حالة وحدات التحكم تمامًا.

إنشاء عرض لـ Action Mailer

أنشئ ملفًا يسمّى welcome_email.html.erb في ‎app/views/user_mailer/‎‎. سيُستخدم هذا القالب (template) للبريد الإلكتروني بتنسيق HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Welcome to example.com, <%= @user.name %></h1>
    <p>
      You have successfully signed up to example.com,
      your username is: <%= @user.login %>.<br>
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>.
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>

لننشئ أيضًا جزءًا نصيًا لهذا البريد الإلكتروني. لا يفضّل كل العملاء رسائل إلكترونيّة بتنسيق HTML، وبالتالي إرسال كليهما هو أفضل الممارسات. أنشئ إذًا ملفًّا يسمّى welcome_email.text.erb في app/views/user_mailer/‎ :

Welcome to example.com, <%= @user.name %>
===============================================
 
You have successfully signed up to example.com,
your username is: <%= @user.login %>.
 
To login to the site, just follow this link: <%= @url %>.
 
Thanks for joining and have a great day!

عند استدعاء التابع mail الآن، سيكتشف Action Mailer قالبين (النص و HTML) ويُنشئ بريدًا إلكترونيًّا multipart/alternative تلقائيًا.

استدعاء المرسل

مُرسلات البريد هي في الواقع مجرد طريقة أخرى لتصيير (rendering) العرض. بدلًا من تصيير عرض وإرساله عبر بروتوكول HTTP، يُرسلونه ببساطة عبر بروتوكولات البريد الإلكتروني. ونتيجة لهذا، من المنطقي أن تطلب وحدة تحكّمك من مرسل رسائل البريد بإرسال بريد إلكتروني عند إنشاء مستخدم بنجاح.

ضبط هذه العملية بسيط للغاية.

فلننشئ أولًا، سقالة بسيطة (أي scaffold) باسم User:

$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate

لدينا الآن نموذج مُستخدم للتلاعب به. سنُعدّل فقط على الملف app/controllers/users_controller.rb بجعله يرشد UserMailer لإرسال بريد إلكتروني للمستخدم حديث الإنشاء عبر تعديل إجراء الإنشاء (create action) وإدخال نداء إلى UserMailer.with(user: @user).welcome_email مباشرةً بعد حفظ المستخدم بنجاح. يتكامل Action Mailer بشكل جيد مع Active Job، لذا تتمكن من إرسال رسائل إلكترونيّة خارج دورة الطلب-الاستجابة، بحيث لا يضطر المستخدم إلى الانتظار:

class UsersController < ApplicationController
  # POST /users
  # POST /users.json
  def create
    @user = User.new(params[:user])
 
    respond_to do |format|
      if @user.save
        # بإرسال بريد ترحيبي بعد حفظ UserMailer أخبر
        UserMailer.with(user: @user).welcome_email.deliver_later
 
        format.html { redirect_to(@user, notice: 'User was successfully created.') }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
end

ملاحظة: السلوك الافتراضي لـ Active Job هو تنفيذ المهام عبر المحوّل async:. لذا يمكنك استخدام deliver_later الآن لإرسال رسائل البريد الإلكتروني بشكل غير متزامن. يُشغّل محوّل Active Job الافتراضي المهام مع مجمع خيوط قيد المعالجة. وهو مناسب تمامًا لبيئات التطوير/الاختبار، نظرًا لأنَّه لا يتطلب أي بنية تحتيّة خارجيّة ولكنه غير ملائم للإنتاج بما أنّه يزيل الوظائف المعلّقة عند إعادة التشغيل. إن كنت في حاجة إلى خلفيّة دائمة (persistent backend)، فستحتاج لاستخدام محوّل Active Job (أي Active Job adapter) يحوي خلفيّة دائمة (Sidekiq ،Resque، ...إلخ). إن رغبت في إرسال بريد إلكتروني على الفور (من cronjob على سبيل المثال) فقط استدعي deliver_now:

class SendWeeklySummary
  def run
    User.find_each do |user|
      UserMailer.with(user: user).weekly_summary.deliver_now
    end
  end
end

أي زوج قيم مفتاح مُمرّر إلى with يصبح params لـ Action Mailer. لذلك، يجعل

with(user: @user, account: @user.account)‎ المعاملين params[:user]‎ و params[:account]‎ متوفّرين في Action Mailer.

ويعيد التابع welcome_email كائنًا من النوع ActionMailer::MessageDelivery والذي يمكن إخباره لاحقًا بالإرسال الأن عبر deliver_now أو الإرسال لاحقًا عبر deliver_later لإرسال نفسه. الكائن ActionMailer::MessageDelivery هو مجرد غلاف (wrapper) حول Mail::Message. إن رغبت في فحص أو تغيير أو فعل بأي شيء آخر مع الكائن Mail::Message، تستطيع الوصول إليه عبر التابع message في الكائن ActionMailer::MessageDelivery.

التشفير التلقائي لقيم الترويسة

يعالج Action Mailer الترميز التلقائي لأحرف متعددة البايت داخل الترويسات وجسم الرسالة.

لأمثلة أكثر تعقيدًا مثل تعريف مجموعات أحرف بديلة أو ترميز النص ذاتيًّا أولًا، الرجاء الرجوع إلى المكتبة Mail.

قائمة توابع Action Mailer الكاملة

تحتاج ثلاثة توابع فقط لأي رسالة بريد إلكتروني:

  • headers - يحدّد أي ترويسة بريد تريدها. تستطيع تمرير جدول Hash بأسماء حقول وأزواج القيم أو يمكنك استدعاءه بالشكل headers[:field_name]‎ = 'value'‎.
  • attachments - يسمح لك بإضافة مرفقات إلى بريدك الإلكتروني مثل attachments['file-name.jpg'] = File.read('file-name.jpg')‎.
  • mail - يرسل البريد الإلكتروني الفعلي ذاته. تستطيع تمرير ترويسة كجدول Hash إلى التابع mail كمعاملة، ثم يُنشئ التابع  بريدًا إلكترونيَّا، إما كنص عادي أو نص متعدّد الأجزاء، اعتمادًا على قوالب البريد الإلكتروني التي عرّفتها.

إضافة المرفقات

يُسهّل Action Mailer إضافة المرفقات.

  • مرّر اسم الملف والمحتوى وسيخمّن Action Mailer وجوهرة البريد (Mail gem) تلقائيًا النوع MIME، ويضبط التشفير وينشئ المُرفق.
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

عندما ينفَّذ التابع mail، سيُرسل بريد إلكتروني متعدد الأجزاء مع مُرفق، مُضمّن بشكل مناسب مع كون المستوى الأعلى multipart/mixed والجزء الأول عبارة عن multipart/alternative يحتوي على النص العادي ورسائل بريد إلكتروني بتنسيق HTML.

ملاحظة: سيُشفّر البريد المُرفق تلقائيا بتشفير Base64. إن أردت شيئًا مختلفًا شفّر مُحتواك ومرّره المحتوى المشفّر وترميزه داخل جدول Hash إلى التابع attachments.

  • مرّر اسم الملف وحدد الترويسة والمحتوى وسيستخدم Action Mailer و mail الإعدادات التي تمررها.
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
attachments['filename.jpg'] = {
  mime_type: 'application/gzip',
  encoding: 'SpecialEncoding',
  content: encoded_content
}

ملاحظة: يفترض البريد أنَّ محتواك مُشفّر مسبقًا ولا يحاول تشفيره عبر Base64.

إنشاء مرفقات مضمّنة (Making Inline Attachments)

يجعل Action Mailer 3.0 المُرفقات المضمّنة - والتي تطلّبت الكثير من التلاعب في الإصدارات قبل 3.0 - بالبساطة والسهولة كما يجدر بها أن تكون.

  • أولًا لتأمر mail بتحويل مُرفق إلى مُرفق مضمّن (Inline Attachment)، عليك فقط استدعاء inline. مع تابع المرفقات داخل مُرسلك (Mailer):
def welcome
  attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
end
  • ثم تستطيع في عرضك أن تشير (reference) إلى attachments كجدول Hash وتحدد المُرفق الذي تريد إظهاره، وتستدعي url عليه ثم تمرر النتيجة إلى التابع image_tag:
<p>Hello there, this is our image</p>
 
<%= image_tag attachments['image.jpg'].url %>
  • نظرًا لأن هذا استدعاء اعتيادي إلى image_tag، تستطيع تمرير جدول Hash من الخيارات بعد عنوان URL المُرفق كما هو الحال مع أي صورة أخرى:
<p>Hello there, this is our image</p>
 
<%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>

إرسال بريد إلكتروني إلى عدة مستلمين

من الممكن إرسال بريد إلى مستلم واحد أو أكثر في بريد إلكتروني واحد (مثلًا إعلام كافة المسؤولين بتسجيل جديد) عن طريق تعيين قائمة بعناوين البريد إلى المفتاح to:. يمكن أن تكون قائمة عناوين البريد مصفوفة من عناوين البريد أو سلسلة واحدة مع عناوين مفصولة بفواصل.

class AdminMailer < ApplicationMailer
  default to: -> { Admin.pluck(:email) },
          from: 'notification@example.com'
 
  def new_registration(user)
    @user = user
    mail(subject: "New User Signup: #{@user.email}")
  end
end

يمكن استخدام نفس التنسيق لوضع نسخة كربونية (:Cc) ونسخة كربونية مخفية (:Bcc) باستخدام المفتاحين cc: و bcc: على التوالي.

إرسال البريد الإلكتروني بالاسم

قد ترغب في بعض الأحيان في إظهار اسم الشخص بدلًا عن مجرّد عنوان بريده الإلكتروني عندما يستلم البريد الإلكتروني الذي أرسلته إليه. وطريقة عمل ذلك هي بتنسيق عنوان البريد الإلكتروني بالشكل ‎"Full Name" <email>‎.

def welcome_email
  @user = params[:user]
  email_with_name = %("#{@user.name}" <#{@user.email}>)
  mail(to: email_with_name, subject: 'Welcome to My Awesome Site')
end

عروض المرسل (Mailer Views)

تُوجد عروض المُرسل (Mailer) في المُجلّد app/views/name_of_mailer_class. يعرف الصنف عرض مرسل البريد المحدّد تلقائيًّا لأنَّ اسمه مماثل لتابع المُرسل. في المثال الوارد أعلاه، سيكون عرض مُرسل بريدنا للتابع welcome_email هو pp/views/user_mailer/welcome_email.html.erb بالنسبة للنسخة HTML و welcome_email.text.erb لنسخة النص العادي.

لتغيير عرض المُرسل الافتراضي لإجرائك (action)، نفّذ ما يلي:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'
 
  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: 'Welcome to My Awesome Site',
         template_path: 'notifications',
         template_name: 'another')
  end
end

سيبحث في هذه الحالة عن قوالب في app/views/notifications بالاسم another. تستطيع أيضًا تحديد مصفوفة مسارات لـ template_path وسيُبحث بها حسب الترتيب. إن أردت مزيدًا من المرونة، تستطيع أيضًا تمرير كتلة (block) وتصيير (render) قوالب محددّة أو حتى تصيير على نفس السطر أو تصيير نص دون استخدام ملف قالب:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'
 
  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: 'Welcome to My Awesome Site') do |format|
      format.html { render 'another_template' }
      format.text { render plain: 'Render text' }
    end
  end
end

سيُصيّر هذا القالب "another_template.html.erb" لجزء HTML ويستخدم النص المُصيّر للجزء النصّي.

أمر التصيير (render) هو نفسه المُستخدم داخل وحدة التحكم (Action Controller) كي تستطيع استخدام جميع الخيارات نفسها مثل text: و inline: ...إلخ.

التخزين المؤقت لعرض المرسل

تستطيع تخزين الأجزاء مؤقّتًّا (fragment caching) في عروض المُرسل مثلما نفعل مع عروض التطبيق باستخدام التابع cache.

<% cache do %>
  <%= @company.name %>
<% end %>

ولاستخدام هذه الخاصيّة، تحتاج لإعداد تطبيقك بالشكل التالي:

config.action_mailer.perform_caching = true

يُدعم التخزين المؤقت للأجزاء أيضًا في رسائل البريد متعدّدة الأجزاء. اقرأ المزيد حول التخزين المؤقت في دليل التخزين المؤقت في ريلز.

تخطيطات Action Mailer

يملك مُرسل البريد تخطيطات تمامًا مثل عروض وحدات التحكّم. يجب أن يكون اسم التخطيط نفس اسم مُرسلك مثل user_mailer.html.erb و user_mailer.text.erb كي يُتعرّف عليه تلقائيًا كتخطيط من طرف مُرسلك.

استدعي التابع layout كي تستخدم ملفًّا مختلفًا في مُرسلك:

class UserMailer < ApplicationMailer
  layout 'awesome' # use awesome.(html|text).erb as the layout
end

استخدم yield لتصيير العرض داخل التخطيط مثل طرق العرض لوحدات التحكّم تمامًا. تستطيع أيضًا تمرير الخيار 'layout: 'layout_name لاستدعاء التصيير داخل بُنية التنسيق لتحديد مخططات مختلفة للتنسيقات المختلفة:

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email) do |format|
      format.html { render layout: 'my_layout' }
      format.text
    end
  end
end

سيُعرض جزء HTML باستخدام الملف my_layout.html.erb وجزء النص مع ملف user_mailer.text.erb المعتاد في حالة وجوده.

معاينة رسائل البريد الإلكتروني (Previewing Emails)

توفر معاينات Action Mailer طريقة لمعرفة كيفيّة ظهور الرسائل الإلكترونية من خلال زيارة عنوان URL خاص يعرضها. يجب تسمية صنف معاينة UserMailer في المثال أعلاه UserMailerPreview ووضعه في test/mailers/previews/user_mailer_preview.rb. لمشاهدة معاينة welcome_email، عرّف استخدام تابع له نفس الاسم واستدعي UserMailer.welcome_email:

class UserMailerPreview < ActionMailer::Preview
  def welcome_email
    UserMailer.with(user: User.first).welcome_email
  end
end

ثم ستُصبح المعاينة متاحة في http://localhost:3000/rails/mailers/user_mailer/welcome_email.

سيُعاد التحميل تلقائيًا إن غيّرت شيئًا ما في app/views/user_mailer/welcome_email.html.erb أو المُرسل نفسه حتى تتمكن من رؤية التنسيق الجديد على الفور. تتوفّر أيضًا قائمة بالمعاينات في http://localhost:3000/rails/mailers.

توجد أصناف المعاينة هذه في test/mailers/previews. يمكن إعدادها باستخدام الخيار preview_path. إن أردت مثلًا تغييرها إلى lib/mailer_previews تستطيع إعداد في config/application.rb:

config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"

توليد العناوين URL في عروض Action Mailer

لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل host: بنفسك.

نظرًا لأنه عادةً ما يكون host: متسقًا عبر التطبيق، تستطيع إعداده على العموم (globally) في config/application.rb:

config.action_mailer.default_url_options = { host: 'example.com' }

لا تستطيع استخدام أي من المساعدين path_* داخل البريد الإلكتروني بسبب هذا السلوك. سوف تحتاج بدلًا من ذلك إلى استخدام المساعد url_*. مثلًا بدل استخدام:

<%= link_to 'welcome', welcome_path %>

ستحتاج لاستخدام:

<%= link_to 'welcome', welcome_url %>

ستعمل الروابط الآن في رسائلك الإلكترونية باستخدام العنوان URL الكامل.

إنشاء عناوين URL مع url_for

ينشئ url_for عنوان URL كامل افتراضيًا في القوالب.

إن لم تضبط الخيار host: على المستوى العام، تأكّد من تمريره إلى url_for.

<%= url_for(host: 'example.com',
            controller: 'welcome',
            action: 'greeting') %>

إنشاء عناوين URL باستخدام المسارات المسماة

لا يمتلك عملاء البريد الإلكتروني أي سياق ويب وبالتالي لا تحتوي المسارات على عنوان URL أساسي لتكوين عناوين ويب كاملة. لذلك يجب دائمًا استخدام المتغيّر "url_" لمساعدي المسارات الموجهة المُسمّاة.

إن لم تضبط الخيار host: على المستوى العام، فتأكّد من تمريره إلى المساعد url.

<%= user_url(@user, host: 'example.com') %>

ملاحظة: تتطلب الروابط غير GET استخدام rails-ujs أو jQuery UJS ولن تعمل في قوالب المُرسل (mailer templates). سيؤدي ذلك إلى طلبات GET العادية.

إضافة الصور في عروض Action Mailer

لا تحتوي نسخة البريد على أي سياق حول الطلب الوارد عكس وحدات التحكّم، لذا عليك تقديم المعامل asset_host: بنفسك.

نظرًا لكون asset_host: عادةً متسقًا عبر التطبيق، تستطيع إعداده بشكل عام (globally) في config/application.rb:

config.action_mailer.asset_host = 'http://example.com'

تستطيع الآن عرض صورة داخل رسالتك الإلكترونيّة.

<%= image_tag 'image.jpg' %>

إرسال رسائل متعددة الأجزاء

سيُرسل Action Mailer رسائل إلكترونيّة متعددة الأجزاء تلقائيًا إن كان لديك قوالب مختلفة لنفس الإجراء (action). لذلك، سيُسرسل Action Mailer تلقائيًا رسالة إلكترونيّة متعدّدة الأجزاء مع نسختين نصيّة و HTML مُعدّتين كجزئين مختلفين بالنسبة لمثالنا UserMailer إن كان الملف welcome_email.text.erb والملف welcome_email.html.erb موجودين في app/views/user_mailer.

يُحدّد parts_order: ترتيب الأجزاء التي تُدخَل داخل التابع ActionMailer::Base.default.

إرسال البريد الإلكتروني مع خيارات التسليم الديناميكي (Dynamic Delivery Options)

إن رغبت في إعادة تعريف (override) خيارات التسليم الافتراضيّة (مثل بيانات اعتماد SMTP) أثناء تسليم البريد الإلكتروني، تستطيع القيام بذلك باستخدام delivery_method_options في الإجراء mailer.

class UserMailer < ApplicationMailer
  def welcome_email
    @user = params[:user]
    @url  = user_url(@user)
    delivery_options = { user_name: params[:company].smtp_user,
                         password: params[:company].smtp_password,
                         address: params[:company].smtp_host }
    mail(to: @user.email,
         subject: "Please see the Terms and Conditions attached",
         delivery_method_options: delivery_options)
  end
end

إرسال رسائل البريد الإلكتروني دون تصيير القالب

قد توجد حالات تريد فيها تخطّي خطوة تصيير القالب وتزويد نص البريد الإلكتروني كسلسلة نصيّة. يمكنك تحقيق ذلك باستخدام الخيار body:. لا تنسَ في مثل هذه الحالات إضافة الخيار content_type:. وإلّا سوف يفترض ريلز انّ نوعه text/plain افتراضيّا.

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email,
         body: params[:email_body],
         content_type: "text/html",
         subject: "Already rendered!")
  end
end

استلام رسائل البريد الإلكتروني

يمكن أن يكون تلقي رسائل البريد الإلكتروني وتحليلها باستخدام Action Mailer معقّدًا نوعًا ما. عليك إعداد نظامك لتوجيه رسائل البريد إلى تطبيقك بطريقة ما، قبل وصول بريد إلكتروني إلى تطبيقك ريلز، والذي يحتاج للاستماع كي يتحقّق. لذلك لتلقي رسائل البريد الإلكتروني في تطبيق ريلز ستحتاج إلى:

  • تعريف استخدام التابع receive في مُرسل بريدك.
  • إعداد خادم بريدك الإلكتروني لإعادة توجيه الرسائل من العنوان (أو العناوين) الذي تريد استلام رسائل البريد الإلكتروني إلى ‎/path/to/app/bin/rails runner 'UserMailer.receive(STDIN.read)'‎ .

يُحلّل Action Mailer البريد الإلكتروني الوارد الخام بمجرّد تعريف التابع المُسمّى receive جاعلًا منه كائن بريد إلكتروني، ثم يفك ترميزه، وينشئ نسخة مُرسل بريد جديدة، ويُمرّر كائن البريد الإلكتروني إلى تابع نُسخة المُرسل receive. إليك مثال على ذلك:

class UserMailer < ApplicationMailer
  def receive(email)
    page = Page.find_by(address: email.to.first)
    page.emails.create(
      subject: email.subject,
      body: email.body
    )
 
    if email.has_attachments?
      email.attachments.each do |attachment|
        page.attachments.create({
          file: attachment,
          description: email.subject
        })
      end
    end
  end
end

ردود نداء Action Mailer

يتيح لك Action Mailer تحديد before_action و after_action و around_action.

  • يمكن تحديد الفلاتر ببُنية أو رمز لتابع في صنف مرسل البريد بشكل شبيه بوحدات التحكّم.
  • تستطيع استخدام before_action لتعبئة كائن البريد افتراضيًا أو delivery_method_options أو إدراج ترويسات ومرفقات افتراضية.
class InvitationsMailer < ApplicationMailer
  before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
  before_action { @account = params[:inviter].account }
 
  default to:       -> { @invitee.email_address },
          from:     -> { common_address(@inviter) },
          reply_to: -> { @inviter.email_address_with_name }
 
  def account_invitation
    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
  end
 
  def project_invitation
    @project    = params[:project]
    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)
 
    mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
  end
end
  • تستطيع استخدام after_action لتنفيذ إعداد مشابه كإجراء سابق before_action ولكن باستخدام متغيّرات نسخة (instance variables) مضبوطة بإجراء مُرسل بريدك (mailer action).
class UserMailer < ApplicationMailer
  before_action { @business, @user = params[:business], params[:user] }
 
  after_action :set_delivery_options,
               :prevent_delivery_to_guests,
               :set_business_headers
 
  def feedback_message
  end
 
  def campaign_message
  end
 
  private
 
    def set_delivery_options
      # mail لديك الوصول إلى النسخة,
      # @business و @user ومتغيرات النسخة
      if @business && @business.has_smtp_settings?
        mail.delivery_method.settings.merge!(@business.smtp_settings)
      end
    end
 
    def prevent_delivery_to_guests
      if @user && @user.guest?
        mail.perform_deliveries = false
      end
    end
 
    def set_business_headers
      if @business
        headers["X-SMTPAPI-CATEGORY"] = @business.code
      end
    end
end
  • تقوم مرشحات Action Mailer بإحباط المعالجة الإضافيّة إن ضبط جسم الرسالة إلى قيمة غير معدومة (non-nil).

استخدام مساعدي Action Mailer

يرث Action Mailer الآن من AbstractController، لذلك لديك حق الوصول إلى نفس المُساعدات العاديّة كما تفعل عادةً مع إجراء التحكم (Action Controller).

ضبط Action Mailer

من الأفضل وضع خيارات الضبط التالية في أحد ملفات البيئة (environment.rb، أو production.rb، ...إلخ):

الإعداد الوصف
logger يولّد معلومات حول الدورة البريديّة (mailing run) إن توفّرت. يمكن ضبطه إلى القيمة nil كي لا يُسجّل أي شيء. يتوافق مع كل من مُسجّل روبي Logger والمسجّلات Log4r.
smtp_settings يسمح بالإعداد المُفصّل لتابع التسليم smtp:
  • address:‎ - يسمح لك باستخدام خادم بريد عن بعد. كل ما عليك هو تغييره عن إعداده "localhost" الافتراضي.
  • port:‎ - تستطيع تغييره في حال عدم عمل خادم بريدك على المنفذ 25.
  • domain:‎ - تستطيع إن إحتجت لتحديد نطاق HELO فعل ذلك هنا.
  • user_name:‎ - إن تطلّب خادم بريدك الاستيثاق، عيّن اسم مستخدم في هذا الإعداد.
  • password:‎ - إن تطلّب خادم بريدك الاستيثاق عيّن كلمة المرور في هذا الإعداد.
  • authentication:‎ - إن تطلّب خادم بريدك الاستيثاق، ستحتاج إلى تحديد نوعه في هذا الإعداد. هذا رمزٌ وواحدٌ من plain:‎ (يرسل كلمة المرور بشكل واضح) و login:‎ (سيرسل كلمة المرور المشفّرة على Base64) أو cram_md5:‎ (يجمع آلية تحدّي/استجابة لتبادل المعلومات وخوارزميّة Message Digest 5 المُشفّرة لتجزئة المعلومات المهمّة)
  • enable_starttls_auto:‎ - يكتشف إن فُعّل STARTTLS في خادمك SMTP ويبدأ في استخدامه. القيمة الافتراضية له هي true.
  • openssl_verify_mode:‎ - عند استخدام TLS، تستطيع ضبط كيفيّة تحقّق OpenSSL من الشهادة. يكون هذا مفيدًا حقًا إن احتجت للتحقّق من صحّة شهادة ذاتيّة التوقيع و/أو بطاقة بدل (wildcard certificate). تستطيع استخدام اسم OpenSSL للتحقق من الثابت ('none' أو 'peer') أو مباشرة من الثابت ( OpenSSL::SSL::VERIFY_NONE أو OpenSSL::SSL::VERIFY_PEER).
sendmail_settings يسمح لك بإعادة تعريف خيارات تابع التسليم sendmail:‎.
  • location:‎ - موقع ملف sendmail التنفيذي (executable). القيمة الافتراضية هي ‎/usr/sbin/sendmail .
  • arguments:‎ - مُتغيّرات سطر الأوامر التي ستُمرّر إلى sendmail. القيمة الافتراضية هي ‎-i.
raise_delivery_errors يحدِّد إن وجب رفع الأخطاء أم لا إن لم يُسلّم البريد الإلكتروني. يعمل هذا الإعداد فقط إن أُعدّ خادم البريد الإلكتروني الخارجي للتسليم الفوري.
delivery_method يُعرّف تابع تسليم. القيم المحتملة هي:
  • smtp:‎: (الافتراضية) يمكن إعداده باستخدام config.action_mailer.smtp_settings.
  • sendmail:‎: يمكن إعداده باستخدام config.action_mailer.sendmail_settings.
  • file:‎: حفظ رسائل البريد الإلكتروني بملفّات. يمكن إعداده باستخدام config.action_mailer.file_settings.
  • test:‎: حفظ رسائل البريد الإلكتروني في ActionMailer::Base.deliveries.

راجع توثيقات API لمزيد من المعلومات.

perform_deliveries يحدّد إن نُفّذت عمليات التسليم فعلًا عند استدعاء التابع deliver على رسالة البريد. ذلك هو الوضع افتراضيًّا ولكن يمكن إيقاف تشغيله للمساعدة في الاختبار الوظيفي.
deliveries يحافظ على مصفوفة من جميع الرسائل المرسلة عبر Action Mailer مع delivery_method :test. مفيدة خاصّة بلاختبار الوحدوي والوظيفي.
default_options تسمح لك بتعيين القيم الافتراضية لخيارات التابع mail (مثل from:‎ و reply_to:‎ وما إلى ذلك).

للحصول على معلومات كاملة عن الإعدادات المحتملة، راجع توثيق إعداد Action Mailer في دليل ضبط تطبيقات ريلز.

مثال عن إعداد Action Mailer

مثال على ذلك هو إضافة ما يلي بملفك config/environments/$RAILS_ENV.rb المناسب:

config.action_mailer.delivery_method = :sendmail
# :القيم الافتراضية هي
# config.action_mailer.sendmail_settings = {
#   location: '/usr/sbin/sendmail',
#   arguments: '-i'
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'no-reply@example.com'}

إعداد Action Mailer مع Gmail

بما أن Action Mailer يستخدم الآن جوهرة البريد، تصبح العمليّة ببساطة إضافة ما يلي إلى ملفك config/environments/$RAILS_ENV.rb:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:              'smtp.gmail.com',
  port:                 587,
  domain:               'example.com',
  user_name:            '<username>',
  password:             '<password>',
  authentication:       'plain',
  enable_starttls_auto: true }

ملاحظة: بدءًا من 15 تموز 2014، عمدت Google إلى زيادة إجراءاتها الأمنيّة، إذ تحظر الآن محاولات التطبيقات التي تراها أقل أمانًا. تستطيع تغيير إعدادات حسابك Gmail هنا للسماح بالمحاولات. إن كانت المصادقة الثنائية (‎2-factor authentication) مُفعّلة بحسابك Gmail، فستحتاج لتعيين كلمة مرور تطبيق واستخدامها بدلًا من كلمة مرورك العاديّة. أو تستطيع بدلًا من ذلك استخدام ESP آخر لإرسال البريد الإلكتروني عن طريق استبدال "smtp.gmail.com" أعلاه بعنوان موفّرك.

اختبار مرسل البريد (Mailer Testing)

تستطيع إيجاد تعليمات مفصّلة حول كيفيّة اختبار مُرسلي بريدك في دليل الاختبار.

اعتراض رسائل البريد الإلكتروني

هناك حالات تحتاج فيها لتعديل بريد إلكتروني قبل تسليمه. لحسن الحظ يوفّر Action Mailer خطافًا لاعتراض كل بريد إلكتروني. تستطيع تسجيل مُعترض لإجراء تعديلات على رسائل البريد قبل تسليمها لوكلاء التوصيل مباشرة.

class SandboxEmailInterceptor
  def self.delivering_email(message)
    message.to = ['sandbox@example.com']
  end
end

يجب تسجيل المُعترض في إطار عمل Action Mailer قبل أن يتمكن من القيام بواجبه. يمكنك ذلك في ملف تهيئة (initializer) من config/initializers/sandbox_email_interceptor.rb:

if Rails.env.staging?
  ActionMailer::Base.register_interceptor(SandboxEmailInterceptor)
end

ملاحظة: يستخدم المثال أعلاه بيئة مخصصّة تسمى "منصة الإطلاق" (staging) لاختبار خادم شبيه بخادم الإنتاج ولكن لأغراض الاختبار. تستطيع قراءة القسم "إنشاء بيئات ريلز" في دليل ضبط تطبيقات ريلز لمزيد من المعلومات حول بيئات ريلز المخصصّة.

مصادر