Laravel 5.6: Как отправлять электронные письма, чтобы клиенты показывали их как темы / разговоры? - PullRequest
0 голосов
/ 28 мая 2018

В мое приложение Laravel включена система тикетов, которая отправляет уведомления по электронной почте.

Все электронные письма создаются и отправляются следующим образом:

public function build()
{
    $email_from_name = "Support - " . config('app.name');
    $subject = "[" . $this->ticket->id . "] " . $this->ticket->subject . " - " . config('app.name');

    return $this->from('support@example.com', $email_from_name)
                    ->subject($subject)
                    ->markdown('emails.customer.ticket.comment_added')
                        ->with([
                            'nickname' => $this->user->nickname,
                            'ticket_id' => $this->ticket->id,
                            'ticket_subject' => $this->ticket->subject,
                            'ticket_text' => $this->ticket_comments->text,
                        ]);
}

К сожалению, когда я получаю несколькоэти электронные письма, без почтового клиента (Outlook, Thunderbird, Roundcube, ...) показывает эти электронные письма как цепочку / разговор.Все клиенты показывают каждое электронное письмо как ветку / беседу «Новая электронная почта».

Что означает, что некоторые электронные письма являются одной веткой / беседой, а некоторые нет?Как я могу сказать своему приложению Laravel, что эти электронные письма - это одна тема / разговор?

Я подумал, что это просто должна быть одна и та же тема электронной почты, но она не работает.

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Спасибо @Yeeooow за информацию, касающуюся стандарта RFC 2822: The References and In-Reply-To headers must be set in compliance with the RFC 2822 standard.

На основании этой информации я проверил некоторые другие темы / разговоры по электронной почте, которые у меня были.Все они использовали упомянутые заголовки References и In-Reply-To одинаково.Имея эту информацию, я начал разработку для архивации того же результата.

В связи с тем, что нам нужно ссылаться на старые электронные письма, нам нужна таблица, в которой мы можем хранить Message-ID каждогоотправил письмо.Я создал эту таблицу в моем случае:

// Table: ticket_message_ids
public function up()
{
    Schema::create('ticket_message_ids', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('ticket_id')->unsigned();
        $table->integer('reference_id')->unsigned(); // Optional; You may remove it or make it ->nullable()
        $table->string('message_id');
        $table->timestamps();
    });
}

С помощью этой таблицы мы можем хранить Message-ID каждого отправленного электронного письма и можем ссылаться на то, к какому билету он принадлежит.Это поможет нам позже также получить только связанные Message-ID s, связанные с этим тикетом - в противном случае мы будем смешивать разные истории тикетов в одной и той же ветке электронной почты.

В поле reference_id вы можетепри необходимости сохраните связанный идентификатор задачи:

  • Добавлен текст заявки
  • Выполнена операция заявки (например, изменен сторонник, приоритет, название или статус)

В вашем почтовом ящике (например, app\Mail\TicketTextAdded.php) теперь вы можете добавить секцию кода $this->withSwiftMessage() {} в функцию build(), чтобы захватить текущий Message-ID этого нового электронного письма и ссылаться на все другие электронные письма до, а также хранитьновый Message-ID`:

public function build()
{
    $email_from_name = "Support - " . config('app.name');
    $subject = "[" . $this->ticket->id . "] " . $this->ticket->subject . " - " . config('app.name');

    $email = $this->from('support@example.com', $email_from_name)
                    ->subject($subject)
                    ->markdown('emails.customer.ticket.comment_added')
                        ->with([
                            'nickname' => $this->user->nickname,
                            'ticket_id' => $this->ticket->id,
                            'ticket_subject' => $this->ticket->subject,
                            'ticket_text' => $this->ticket_comments->text,
                        ]);

    // Access underlaying Swift message
    $this->withSwiftMessage(function ($swiftmessage) {
        // Get all Message-IDs associated to this specific ticket
        $message_ids = TicketMessageIds::where('ticket_id', '=', $this->ticket->id)->get();

        // Build RFC2822 conform 'References' header
        // Example: 'References: <4bcf5a806f795b86fb2ba7238c78983c@swift.generated> <ab7898365c4aa91bfe010d4e1e8da377@swift.generated>'
        $header_references = "";            
        foreach($message_ids as $message_id) {
            if(empty($header_references)) {
                $header_references = $message_id->message_id;
            } else {
                $header_references = $header_references . " " . $message_id->message_id;
            }
        }

        // Build RFC2822 conform 'In-Reply-To' header
        // Example: 'In-Reply-To: <ab7898365c4aa91bfe010d4e1e8da377@swift.generated>'
        $header_in_reply_to = TicketMessageIds::where('ticket_id', '=', $this->ticket->id)->orderBy('id', 'DESC')->get(['message_id'])->first()->message_id;

        // Add required custom headers with above values
        $headers = $swiftmessage->getHeaders();
        // 'X-Mailer' header is not required for this purpose
        // This header sets only a name for the client, which sent this message (typical values: Outlook 2016, PHPMailer v6.0.5,...)
        $headers->addTextHeader('X-Mailer', config('app.name') . ' (' . config('app.url') . ')');
        if(!empty($header_references)) {
            $headers->addTextHeader('References', $header_references);
        }
        $headers->addTextHeader('In-Reply-To', $header_in_reply_to);

        TicketMessageIds::create([
            'ticket_id' => $this->ticket->id,
            'message_id' => '<'.$swiftmessage->getId().'>'
        ]);
    });

    return $email;
}

К вашему сведению: вы также можете изменить Message-ID там, где мы установили пользовательские заголовки, но это должно соответствовать соответствующим документам RFC:

$msgId = $swiftmessage->getHeaders()->get('Message-ID');
$msgId->setId(time() . '.' . uniqid('thing') . '@example.org');

Дополнительная информация: https://swiftmailer.symfony.com/docs/headers.html#id-headers

Надеюсь, я мог бы помочь кому-нибудь еще с этой информацией.:)

0 голосов
/ 28 мая 2018

Темы создаются автоматически почтовыми клиентами.Вы не могли ничего сделать

...