שיווק מודרני דורש קמפיינים דוא"ל להסתגל במהירות למגזרי קהל, A / B בדיקות, תוכן דינמי. יישום קשיח, מונוליטי הופך במהרה לסיוט תחזוקה כמו דרישות להתפתח.לארו, עם סינטקס אקספרסיבי שלה ואת מערכת אקולוגית חזקה, מספק בסיס אידיאלי, אבל המפתח האמיתי לגמישות ארוכת טווח שקרים בבחירת דפוס העיצוב הנכון.

במדריך מקיף זה, תלמד כיצד לאדריכל מערכת קמפיין דואר אלקטרוני גמישה ב Laravel באמצעות התבנית המארגנת.We will break down the theory, Walk Through applied, ולחקור אינטגרציה עם מערכות הדואר וההתנור של לארהvel עד הסוף, תהיה לך גישה מוכנה לייצור כל גרסה של קמפיין דואר אלקטרוני - מהודעות עסקאות טקסט פשוטות ועד קידום HTML עשיר - עם קוד מינימלי.

מהו תבנית ה-Neative?

תבנית בונה היא תבנית עיצוב יצירה המפרידה את בנייתו של אובייקט מורכב מהייצוג הסופי שלו.במקום ליצור אובייקט באמצעות בונה מסיבי או קבוצה של שיטות מפעל, אתה מאציל את תהליך הבנייה למנהל מסור ומעמדי בונה.הבמאי מתזמר את השלבים, בעוד שכל בונה יודע כיצד להרכיב את הרכיבים עבור גרסה מסוימת.

דפוס זה מאיר כאשר אובייקט דורש חלקים אופציונליים רבים, יש מספר שלבים תצורה, או כאשר אתה צריך לייצר ייצוגים שונים של אובייקטים דומים. עבור קמפיינים דואר אלקטרוני, "אובייקט" הוא הודעת דואר אלקטרוני - שלם עם נושא, גוף, החזקות, נמענים, ראשים, ו metadata. כל סוג קמפיין (מניעה, עסקה, אירוע) עשוי לשתף בסיס משותף אבל שונה בפריסה, תוכן או בלוקים.

איך זה מת מתבנית המפעל

בעוד דפוס המפעל מתמקד ביצירת אובייקטים בקריאה אחת, דפוס הרוכש מאפשר תהליך בנייה מבוקר, ⁇ הם אידיאליים כאשר לוגיקה הבריאה היא פשוטה; בנינים טובים יותר כאשר אתה צריך לשלוט על הסדר ובחירת חלקים. במערכות דואר אלקטרוני, לעתים קרובות צריך להוסיף החזקות בתנאיות, לשנות את תבנית הגוף, או להגדיר סדרי עדיפויות שונות.המודל נותן לך שליטה גרפית ללא מפעל בודד.

הגדרת הסביבה של לארהvel

לפני צלילה לקוד, ודא שיש לך יישום של Laravel (הפרשה 9 ואילך) עם תצורת הדואר ברירת המחדל.We נניח שיש לך את טבלאות מסד הנתונים הדרושות עבור קמפיינים, מנויים ותבניות - אבל עבור מאמר זה, אנו מתמקדים בלוגיקה בונה עצמו.You יכול לעקוב יחד עם התקנת Laravel באמצעות Composer:

composer create-project laravel/laravel email-campaign-builder

לאחר מכן, הגדר את נהג הדואר שלך ב-FLT:1 (למשל, FLT:2 לבדיקה) אנו נשתמש גם בחזית של Laravel 3 ובמבנה המובנה של 4:4 שיעורים מאוחר יותר, אבל בונהנו יישאר עצמאי מהם כדי לשמור על הפרדה נקייה.

המונחים: the Builder Pattern

אנו ניישם ארבעה מרכיבים עיקריים:

  1. (ב) ,5 , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  2. (ב) [ה]הסברים:0Builder InterfaceFLT:1] – מבהירים שיטות לכל חלק מהדואר האלקטרוני: נושא, גוף, נמענים, החזקות, ראשים וכו'.
  3. (FLT:0) קונקטריקטורים (FLT:1) - כל אחד מיישם את הממשק לסוג מסוים של דואר אלקטרוני (Promotional, Dealal, Welcome series).
  4. (FLT:0)DirectorveFLT:1) - מציג את השלבים של הבנייה בסדר מוגדר, לעתים קרובות באמצעות אותו בונה כדי לייצר מספר הודעות דוא"ל מטביעה כחולה.

שלב 1: Define the email Message Product

אנו ניצור אובייקט פשוט ערך כדי להחזיק את כל הנתונים של דואר אלקטרוני, זה שומר קוד בונה נקי ומבחן.

<?php

namespace App\Values;

class EmailMessage
{
 public string $subject;
 public string $body;
 public string $mimeType = 'text/html'; // or text/plain
 public array $recipients = [];
 public array $ccRecipients = [];
 public array $bccRecipients = [];
 public array $attachments = [];
 public array $headers = [];
 public ?string $fromAddress = null;
 public ?string $fromName = null;

 public function toArray(): array
 {
 return [
 'subject' => $this->subject,
 'body' => $this->body,
 'mimeType' => $this->mimeType,
 'recipients' => $this->recipients,
 'cc' => $this->ccRecipients,
 'bcc' => $this->bccRecipients,
 'attachments' => $this->attachments,
 'headers' => $this->headers,
 'from' => ['address' => $this->fromAddress, 'name' => $this->fromName],
 ];
 }
}

שלב 2: ממשקי עבודה

הממשק מגדיר את החוזה לבניית כל גרסה דוא"ל.

<?php

namespace App\Builders\Contracts;

use App\Values\EmailMessage;

interface EmailBuilderContract
{
 public function setSubject(string $subject): self;
 public function setBody(string $body, string $mimeType = 'text/html'): self;
 public function addRecipient(string $email, ?string $name = null): self;
 public function addCc(string $email, ?string $name = null): self;
 public function addBcc(string $email, ?string $name = null): self;
 public function addAttachment(string $filePath, ?string $name = null): self;
 public function addHeader(string $key, string $value): self;
 public function setFrom(string $address, ?string $name = null): self;
 public function getEmail(): EmailMessage;
 public function reset(): void;
}

שלב 3: קונסולת הרוכשים עבור הודעות דואר אלקטרוני

בואו יישם בונה שמתאים את הדואר האלקטרוני למבצעים – מעקב אחר פיקסלים, קישורים לשיתוף חברתי ומדפי לא סופר סטנדרטיים.

<?php

namespace App\Builders;

use App\Builders\Contracts\EmailBuilderContract;
use App\Values\EmailMessage;

class PromotionalEmailBuilder implements EmailBuilderContract
{
 private EmailMessage $email;

 public function __construct()
 {
 $this->reset();
 }

 public function setSubject(string $subject): self
 {
 $this->email->subject = '[Promo] ' . $subject;
 return $this;
 }

 public function setBody(string $body, string $mimeType = 'text/html'): self
 {
 // Wrap body with promotional header/footer
 $this->email->body = $this->wrapBody($body);
 $this->email->mimeType = $mimeType;
 return $this;
 }

 private function wrapBody(string $body): string
 {
 return "<div style=\"background:#f5f5f5; padding:20px;\">
 <div style=\"max-width:600px; margin:auto;\">
 $body
 <hr>
 <p style=\"font-size:12px; color:#888;\">
 You received this because you opted in.
 <a href=\"{{unsubscribe_url}}\">Unsubscribe</a>
 </p>
 </div>
 </div>";
 }

 public function addRecipient(string $email, ?string $name = null): self
 {
 $this->email->recipients[] = compact('email', 'name');
 return $this;
 }

 public function addCc(string $email, ?string $name = null): self
 {
 $this->email->ccRecipients[] = compact('email', 'name');
 return $this;
 }

 public function addBcc(string $email, ?string $name = null): self
 {
 $this->email->bccRecipients[] = compact('email', 'name');
 return $this;
 }

 public function addAttachment(string $filePath, ?string $name = null): self
 {
 $this->email->attachments[] = ['path' => $filePath, 'name' => $name];
 return $this;
 }

 public function addHeader(string $key, string $value): self
 {
 $this->email->headers[$key] = $value;
 return $this;
 }

 public function setFrom(string $address, ?string $name = null): self
 {
 $this->email->fromAddress = $address;
 $this->email->fromName = $name;
 return $this;
 }

 public function getEmail(): EmailMessage
 {
 $built = clone $this->email;
 $this->reset();
 return $built;
 }

 public function reset(): void
 {
 $this->email = new EmailMessage();
 }
}

שלב 4: דוגמה מקצועית

אימייל עסקאות (למשל אישור הזמנה) זקוק לחתימה שונה - מינימום מיתוג, כותרות עדיפות, ואין סופר חת שוליים.

<?php

namespace App\Builders;

class TransactionalEmailBuilder implements EmailBuilderContract
{
 private EmailMessage $email;
 // ... same structure, but setSubject does not prepend prefix
 // and wrapBody() uses a simple layout with order details
 // getEmail() resets the builder
}

שם הסרטון: Orchestraing the Build

הבמאי לוקח דוגמה בונה ומכנה את צעדיו בסדר מסוים.כאן אתה יכול להגדיר רצף סטנדרטי, כגון "לבנות אימייל קמפיין עבור המנויים".

<?php

namespace App\Builders;

use App\Builders\Contracts\EmailBuilderContract;
use App\Models\User;

class CampaignDirector
{
 public function __construct(private EmailBuilderContract $builder) {}

 public function buildPromotionalCampaign(User $user, string $subject, string $body): EmailMessage
 {
 return $this->builder
 ->setFrom('[email protected]', 'Marketing Team')
 ->setSubject($subject)
 ->addRecipient($user->email, $user->name)
 ->addHeader('X-Campaign-Id', $campaignId)
 ->setBody($body)
 ->getEmail();
 }

 public function buildTransactionalOrderConfirmation(Order $order): EmailMessage
 {
 // Switch builder if needed, or use a different director method
 // (In practice, you'd instantiate a TransactionalEmailBuilder)
 $this->builder = new TransactionalEmailBuilder();
 $body = view('emails.order-confirmation', compact('order'))->render();
 return $this->builder
 ->setFrom('[email protected]', 'Order System')
 ->setSubject('Order Confirmation #' . $order->id)
 ->addRecipient($order->user->email, $order->user->name)
 ->setBody($body)
 ->addHeader('X-Transaction-Id', $order->transaction_id)
 ->addAttachment(storage_path('invoices/' . $order->invoice_file))
 ->getEmail();
 }
}

באמצעות מנהל, יש צורך בלוגיקה בנייה מרכזית, אם אתה צריך להוסיף שיטה (FLT):13, אתה רק להרחיב את הבמאי ללא נגיעה בבניינים.

עקבו אחרי Laravel Mail

לאחר שיש לך אובייקט ערך (FLT:14), עליך לשלוח אותו, ליצור דואר מותאם אישית שמקבל את ה-FLT:15 והופכת אותו באמצעות מערכת הדואר המובנה של לליבר.

<?php

namespace App\Mail;

use App\Values\EmailMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class CampaignMail extends Mailable
{
 use Queueable, SerializesModels;

 public function __construct(public EmailMessage $emailMessage) {}

 public function envelope(): Envelope
 {
 return new Envelope(
 from: $this->emailMessage->fromAddress
 ? new Address($this->emailMessage->fromAddress, $this->emailMessage->fromName)
 : null,
 subject: $this->emailMessage->subject,
 cc: $this->emailMessage->ccRecipients,
 bcc: $this->emailMessage->bccRecipients,
 headers: $this->emailMessage->headers,
 );
 }

 public function content(): Content
 {
 return new Content(
 htmlString: $this->emailMessage->body,
 );
 }

 public function attachments(): array
 {
 return array_map(function ($attach) {
 return Attachment::fromPath($attach['path'])
 ->as($attach['name'] ?? null);
 }, $this->emailMessage->attachments);
 }
}

עכשיו אתה יכול לשלוח הודעות דוא"ל מכל בקר או עבודה באמצעות הבונים:

use App\Builders\PromotionalEmailBuilder;
use App\Builders\CampaignDirector;
use App\Mail\CampaignMail;
use Illuminate\Support\Facades\Mail;

$builder = new PromotionalEmailBuilder();
$director = new CampaignDirector($builder);

$emailMessage = $director->buildPromotionalCampaign($user, 'Summer Sale', $htmlContent);
Mail::to($user->email)->send(new CampaignMail($emailMessage));

עקבו אחרי Scalability

מערכות קמפיין דואר אלקטרוני חייבות לטפל באלפי נמעןים באופן מסונכרן.מערכת התור של לארהvel היא משחק מושלם.האנס את הלוגיקה של שליחת עבודה בתור המשתמשת בבנו עבור כל מקבל.

<?php

namespace App\Jobs;

use App\Builders\Contracts\EmailBuilderContract;
use App\Builders\CampaignDirector;
use App\Mail\CampaignMail;
use App\Models\Subscriber;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;

class SendCampaignEmail implements ShouldQueue
{
 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

 public function __construct(
 private Subscriber $subscriber,
 private string $subject,
 private string $body,
 private string $builderClass // class-string
 ) {}

 public function handle(): void
 {
 $builder = app($this->builderClass);
 $director = new CampaignDirector($builder);
 $emailMessage = $director->buildPromotionalCampaign(
 $this->subscriber->user,
 $this->subject,
 $this->body
 );

 Mail::to($this->subscriber->email)
 ->send(new CampaignMail($emailMessage));
 }
}

§ § שתף את התפקיד עבור כל המנוי בלולאה (או טוב יותר, השתמש ב-FLT:19 כדי לנהל את המשלוח המוצלח / המופרע).

הוספת תבניות דינמיות עם Blade

ה- HTML הגדל בבניינים אינו אידיאלי, אלא עובר את השקפות הבלדה כגוף.הבן שלך יכול לקבל שם תצוגה ומערך נתונים, ואז לקרוא FLT:20 בתוך FLT:21 זה שומר את התבניות שלך נפרדות וקלות למעצבים לערוך.

public function setBody(string $viewName, array $data = [], string $mimeType = 'text/html'): self
{
 $rendered = view($viewName, $data)->render();
 $this->email->body = $this->wrapBody($rendered);
 $this->email->mimeType = $mimeType;
 return $this;
}

עכשיו אפשר לקרוא לזה (בשיתוף: 23)

יתרונות בקמפיינים אמיתיים

  • (ב) ויקרא:0) ללא שכפול 1 (ב) - סוגי קמפיין שונים חולקים את אותו ממשק; בנינים מבססים את ההבדלים.
  • (ב) ,0) , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  • (FLT:0) קלאס A/B TestingFLT:1) - מגדלי סוופ לקבוצת גרסאות.
  • (ב) ,0) ,Audit TracksFLT:1 - הוסף כניסה בתוך הבונים כדי להקליט כל צעד אחר ניתוח מאוחר יותר.
  • (ב) ,0) אינטגרציה עם שירותים חיצוניים FLT1 - השתמש בבן כדי להרכיב מטענים עבור שירותים כמו Mailgun, SendGrid, או SparkPost.

ההליכים הטובים ביותר והמלכודות הנפוצות

שמור על הבונים חסרי מדינה היכן שאפשר

שיטת ה-FLT:25 מבטיחה כי ניתן להשתמש בבן אם אתה שוכח לקרוא ל-FLT:26, אותו מקרה בונה עשוי להדליף את המדינה בין קמפיינים שונים.

אל תתגברו על הודעות דואר אלקטרוני פשוטות

אם היישום שלך שולח רק סוג אחד של דואר אלקטרוני, דפוס הרוכש עשוי להיות overkill. זה מאיר כאשר יש לך לפחות שלושה סוגים שונים של דואר אלקטרוני עם רכיבים שונים.

שימוש בזריקת תלות עבור יצרנים

לרשום את הבונים שלך במיכל השירות כך שתוכל להזריק תלויות (כמו כניסה או מעקב) אליהם בקלות.

המונחים: the Number of Recipients

הבונים לא צריך לאסוף אלפי נמעןים ב-OneFLT:29 - זה יטען ג'יגהבייט בזיכרון. במקום זאת, ליצור דוא"ל אחד לנמען, או להשתמש ב- APIs (דואר זבל: 30) הבמאי יכול לחדור מעל נתח של מנויים.

שיפורים נוספים

שקול להוסיף מודל אל-קולי המאחסן את מעמד הבונים, תבנית ופרמטרי ברירת מחדל.לאחר מכן, עבודה לוח הזמנים קורא טביעות אצבע ומשתמשת בבמאי כדי לבנות & תור הודעות דוא"ל לכל מנויים פעילים.

ניתן גם להציג את החוקים הגלובליים (כמו תמיד הוספת קישור לא מצורף) לפני ניכוי על בונה ספציפי.

משאבים חיצוניים

  • (ב) ויקרא י"א: ויקרא י"ד): "הסבר חזותי מלומד" (הסבר חזותי).
  • (ב) ויקרא י"א: ויקרא י"א): "לכתוב את ה'" (במדבר כ"ד).
  • (ב) ◄ [17] , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

מסקנה

תכנון מערכת קמפיין דואר אלקטרוני גמישה אינו דורש מסגרת מסיבית.עם התבנית המארגנת ב Laravel, אתה מקבל שליטה מדויקת על בניית דואר אלקטרוני, מה שהופך את בסיס הקוד שלך להתאמה להחלפת צרכי שיווק.על ידי הפרדה מה (Builder) מהאופן (בימוי), אתה מאפשר לצוותים להוסיף סוגי קמפיין חדשים ללא חשש לשבור אלה קיימים.שלב זאת עם דואר ו תור של לארהvel, ויש לך יכולת נית, לבדיקות, כדי לשמור על פתרון אפשרי עבור שנים.