الفرق بين المراجعتين لصفحة: «Rails/action mailer basics»
جميل-بيلوني (نقاش | مساهمات) إنشاء الصفحة |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(2 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:أساسيات Action Mailer في ريلز}}</noinclude> | |||
يوفّر لك هذا الدليل كل ما تحتاجه للبدء في إرسال واستقبال رسائل البريد الإلكتروني من وإلى تطبيقك، والعديد من عمليّات | يوفّر لك هذا الدليل كل ما تحتاجه للبدء في إرسال واستقبال رسائل البريد الإلكتروني من وإلى تطبيقك، والعديد من عمليّات [[Rails/action mailer|Action Mailer]] الداخليّة. كما يغطي كيفية اختبار مُرسلي بريدك (mailers). | ||
ستتعلم بعد قراءة هذا الدليل: | ستتعلم بعد قراءة هذا الدليل: | ||
* كيفيّة إرسال واستقبال البريد الإلكتروني داخل تطبيق ريلز. | * كيفيّة إرسال واستقبال البريد الإلكتروني داخل تطبيق ريلز. | ||
* كيفيّة إنشاء وتعديل صنف | * كيفيّة إنشاء وتعديل صنف [[Rails/action mailer|Action Mailer]] والعرض المرتبط به. | ||
* كيفيّة إعداد | * كيفيّة إعداد [[Rails/action mailer|Action Mailer]] لبيئتك. | ||
* كيفيّة اختبار أصنافك | * كيفيّة اختبار أصنافك لـ [[Rails/action mailer|Action Mailer]]. | ||
== مقدمة == | == مقدمة == | ||
يسمح لك | يسمح لك [[Rails/action mailer|Action Mailer]] بإرسال رسائل البريد الإلكتروني من تطبيقك باستخدام الأصناف <code>mailer</code> والعروض المرتبطة بها (views). | ||
تعمل مُرسلات البريد بطريقة مشابهة جدًا لوحدات التحكّم. وهي ترث من <code>ActionMailer::Base</code> وتتوضع في app/mailers | تعمل مُرسلات البريد بطريقة مشابهة جدًا لوحدات التحكّم. وهي ترث من <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 في | أنشئ ملفًا يسمّى 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> الآن، سيكتشف | </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> مباشرةً بعد حفظ المستخدم بنجاح. | ||
يتكامل | يتكامل [[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 | ||
# | # بإرسال بريد ترحيبي بعد حفظ UserMailer أخبر | ||
UserMailer.with(user: @user).welcome_email.deliver_later | UserMailer.with(user: @user).welcome_email.deliver_later | ||
سطر 131: | سطر 131: | ||
end | end | ||
end | end | ||
</syntaxhighlight>'''ملاحظة''': السلوك الافتراضي | </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> | </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]] إضافة المرفقات. | ||
* مرّر اسم الملف والمحتوى وسيخمّن | * مرّر اسم الملف والمحتوى وسيخمّن [[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>. | ||
* مرّر اسم الملف وحدد الترويسة والمحتوى وسيستخدم | * مرّر اسم الملف وحدد الترويسة والمحتوى وسيستخدم [[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) ==== | ||
يجعل | يجعل [[Rails/action mailer|Action Mailer]] 3.0 المُرفقات المضمّنة - والتي تطلّبت الكثير من التلاعب في الإصدارات قبل 3.0 - بالبساطة والسهولة كما يجدر بها أن تكون. | ||
* أولًا لتأمر mail | * أولًا لتأمر <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> هو | تُوجد عروض المُرسل (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) | لتغيير عرض المُرسل الافتراضي لإجرائك (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) === | ||
توفر معاينات | توفر معاينات [[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: | ||
=== إرسال رسائل متعددة الأجزاء === | === إرسال رسائل متعددة الأجزاء === | ||
سيُرسل | سيُرسل [[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> . | ||
يُحلّل | يُحلّل [[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 == | ||
يتيح لك | يتيح لك [[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> | ||
* تقوم مرشحات | * تقوم مرشحات [[Rails/action mailer|Action Mailer]] بإحباط المعالجة الإضافيّة إن ضبط جسم الرسالة إلى قيمة غير معدومة (non-nil). | ||
== استخدام مساعدي | == استخدام مساعدي Action Mailer == | ||
يرث | يرث [[Rails/action mailer|Action Mailer]] الآن من <code>AbstractController</code>، لذلك لديك حق الوصول إلى نفس المُساعدات العاديّة كما تفعل عادةً مع إجراء التحكم (Action Controller). | ||
== | == ضبط Action Mailer == | ||
من الأفضل وضع خيارات | من الأفضل وضع خيارات الضبط التالية في أحد ملفات البيئة (environment.rb، أو production.rb، ...إلخ): | ||
{| class="wikitable" | {| class="wikitable" | ||
!الإعداد | |||
!الوصف | |||
|- | |- | ||
|logger | |<code>logger</code> | ||
|يولّد معلومات حول الدورة البريديّة (mailing run) إن توفّرت. يمكن ضبطه | |يولّد معلومات حول الدورة البريديّة (mailing run) إن توفّرت. يمكن ضبطه إلى القيمة <code>nil</code> كي لا يُسجّل أي شيء. يتوافق مع كل من مُسجّل روبي Logger والمسجّلات Log4r. | ||
|- | |- | ||
|smtp_settings | |<code>smtp_settings</code> | ||
|يسمح بالإعداد المُفصّل لتابع التسليم smtp: | |يسمح بالإعداد المُفصّل لتابع التسليم <code>smtp</code>: | ||
* address: - يسمح لك باستخدام خادم بريد عن بعد. كل ما عليك هو تغييره عن إعداده "localhost" الافتراضي. | * <code>address:</code> - يسمح لك باستخدام خادم بريد عن بعد. كل ما عليك هو تغييره عن إعداده "localhost" الافتراضي. | ||
* port: - تستطيع في | * <code>port:</code> - تستطيع تغييره في حال عدم عمل خادم بريدك على المنفذ 25. | ||
* domain: - تستطيع إن إحتجت لتحديد نطاق HELO فعل ذلك هنا. | * <code>domain:</code> - تستطيع إن إحتجت لتحديد نطاق HELO فعل ذلك هنا. | ||
* user_name: - إن تطلّب خادم بريدك | * <code>user_name:</code> - إن تطلّب خادم بريدك الاستيثاق، عيّن اسم مستخدم في هذا الإعداد. | ||
* password: - إن تطلّب خادم بريدك | * <code>password:</code> - إن تطلّب خادم بريدك الاستيثاق عيّن كلمة المرور في هذا الإعداد. | ||
* authentication: - إن تطلّب خادم بريدك | * <code>authentication:</code> - إن تطلّب خادم بريدك الاستيثاق، ستحتاج إلى تحديد نوعه في هذا الإعداد. هذا رمزٌ وواحدٌ من <code>plain:</code> (يرسل كلمة المرور بشكل واضح) و <code>login:</code> (سيرسل كلمة المرور المشفّرة على Base64) أو <code>cram_md5:</code> (يجمع آلية تحدّي/استجابة لتبادل المعلومات وخوارزميّة Message Digest 5 المُشفّرة لتجزئة المعلومات المهمّة) | ||
* enable_starttls_auto: - يكتشف | * <code>enable_starttls_auto:</code> - يكتشف إن فُعّل STARTTLS في خادمك SMTP ويبدأ في استخدامه. القيمة الافتراضية له هي <code>true</code>. | ||
* openssl_verify_mode: - عند استخدام | * <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). | * <code>location:</code> - موقع ملف <code>sendmail</code> التنفيذي (executable). القيمة الافتراضية هي /usr/sbin/sendmail . | ||
* arguments: - مُتغيّرات سطر الأوامر التي ستُمرّر إلى sendmail. | * <code>arguments:</code> - مُتغيّرات سطر الأوامر التي ستُمرّر إلى <code>sendmail</code>. القيمة الافتراضية هي <code>-i</code>. | ||
|- | |- | ||
|raise_delivery_errors | |<code>raise_delivery_errors</code> | ||
| | |يحدِّد إن وجب رفع الأخطاء أم لا إن لم يُسلّم البريد الإلكتروني. يعمل هذا الإعداد فقط إن أُعدّ خادم البريد الإلكتروني الخارجي للتسليم الفوري. | ||
|- | |- | ||
|delivery_method | |<code>delivery_method</code> | ||
|يُعرّف تابع تسليم. القيم المحتملة هي: | |يُعرّف تابع تسليم. القيم المحتملة هي: | ||
* smtp: ( | * <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> | ||
|يحدّد إن نُفّذت عمليات التسليم فعلًا عند | |يحدّد إن نُفّذت عمليات التسليم فعلًا عند استدعاء التابع <code>deliver</code> على رسالة البريد. ذلك هو الوضع افتراضيًّا ولكن يمكن إيقاف تشغيله للمساعدة في الاختبار الوظيفي. | ||
|- | |- | ||
|deliveries | |<code>deliveries</code> | ||
|يحافظ على مصفوفة من جميع الرسائل المرسلة عبر | |يحافظ على مصفوفة من جميع الرسائل المرسلة عبر [[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|ضبط تطبيقات ريلز]]. | ||
=== مثال عن إعداد 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> | |||
=== إعداد 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', | |||
port: 587, | |||
domain: 'example.com', | |||
user_name: '<username>', | |||
password: '<password>', | |||
authentication: 'plain', | |||
enable_starttls_auto: true } | |||
</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) == | |||
تستطيع إيجاد تعليمات مفصّلة حول كيفيّة اختبار مُرسلي بريدك في [[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|دليل الاختبار]]. | |||
ملاحظة: | |||
== اختبار | |||
تستطيع إيجاد تعليمات مفصّلة حول كيفيّة اختبار مُرسلي بريدك في دليل الاختبار. | |||
== اعتراض رسائل البريد الإلكتروني == | == اعتراض رسائل البريد الإلكتروني == | ||
هناك حالات تحتاج فيها لتعديل بريد إلكتروني قبل تسليمه. لحسن الحظ يوفّر | هناك حالات تحتاج فيها لتعديل بريد إلكتروني قبل تسليمه. لحسن الحظ يوفّر [[Rails/action mailer|Action Mailer]] خطافًا لاعتراض كل بريد إلكتروني. تستطيع تسجيل مُعترض لإجراء تعديلات على رسائل البريد قبل تسليمها لوكلاء التوصيل مباشرة.<syntaxhighlight lang="rails"> | ||
class SandboxEmailInterceptor | |||
def self.delivering_email(message) | |||
message.to = ['sandbox@example.com'] | |||
end | |||
end | end | ||
</syntaxhighlight>يجب تسجيل المُعترض في إطار عمل [[Rails/action mailer|Action Mailer]] قبل أن يتمكن من القيام بواجبه. يمكنك ذلك في ملف تهيئة (initializer) من config/initializers/sandbox_email_interceptor.rb:<syntaxhighlight lang="rails"> | |||
يجب تسجيل المُعترض في إطار عمل | if Rails.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 :
|
sendmail_settings
|
يسمح لك بإعادة تعريف خيارات تابع التسليم sendmail: .
|
raise_delivery_errors
|
يحدِّد إن وجب رفع الأخطاء أم لا إن لم يُسلّم البريد الإلكتروني. يعمل هذا الإعداد فقط إن أُعدّ خادم البريد الإلكتروني الخارجي للتسليم الفوري. |
delivery_method
|
يُعرّف تابع تسليم. القيم المحتملة هي:
راجع توثيقات 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) لاختبار خادم شبيه بخادم الإنتاج ولكن لأغراض الاختبار. تستطيع قراءة القسم "إنشاء بيئات ريلز" في دليل ضبط تطبيقات ريلز لمزيد من المعلومات حول بيئات ريلز المخصصّة.