Tóm lược
Bởi vì một lỗi trong WP Core, gửi nhiều phần dữ liệu email (html / text) với wp_mail () (để giảm cơ hội của email kết thúc trong thư mục spam) sẽ trớ trêu thay cho kết quả với tên miền của bạn bị chặn bởi Hotmail (và email khác của Microsoft).
Đây là một vấn đề phức tạp mà tôi sẽ nhắm đến để phân tích rất chi tiết trong nỗ lực giúp ai đó tìm ra giải pháp khả thi mà cuối cùng có thể được thực hiện trong cốt lõi.
Đây sẽ là một bài đọc bổ ích. Hãy bắt đầu nào...
Con bọ
Lời khuyên phổ biến nhất để tránh việc email bản tin của bạn kết thúc trong các thư mục spam là gửi tin nhắn nhiều phần.
Đa phần (mime) đề cập đến việc gửi cả phần HTML và văn bản của một thông điệp email trong một email. Khi khách hàng nhận được một tin nhắn nhiều phần, nó chấp nhận phiên bản HTML nếu nó có thể hiển thị HTML, nếu không, nó thể hiện phiên bản văn bản thuần túy.
Điều này được chứng minh là có tác dụng. Khi gửi đến gmail, tất cả các email của chúng tôi đều rơi vào các thư mục spam cho đến khi chúng tôi thay đổi thư thành nhiều phần khi chúng được chuyển đến hộp thư đến chính. Công cụ tuyệt vời.
Bây giờ, khi gửi tin nhắn nhiều phần qua wp_mail (), nó sẽ xuất Loại Nội dung (bội / *) hai lần, một lần với ranh giới (nếu được đặt tùy chỉnh) và một lần không có. Hành vi này dẫn đến việc email được hiển thị dưới dạng tin nhắn thô và không phải là nhiều phần trên một số email, bao gồm tất cả Microsoft (Hotmail, Outlook, v.v.)
Microsoft sẽ gắn cờ tin nhắn này là rác và một vài tin nhắn đi qua sẽ được người nhận gắn cờ theo cách thủ công. Thật không may , địa chỉ email của Microsoft được sử dụng rộng rãi. 40% thuê bao của chúng tôi sử dụng nó.
Điều này được Microsoft xác nhận thông qua trao đổi email mà chúng tôi đã có gần đây.
Việc gắn cờ các tin nhắn sẽ dẫn đến việc tên miền bị chặn hoàn toàn . Điều này có nghĩa là tin nhắn sẽ không được gửi đến thư mục thư rác, chúng thậm chí sẽ không được gửi đến người nhận.
Chúng tôi đã có tên miền chính của chúng tôi bị chặn 3 lần cho đến nay.
Vì đây là một lỗi trong lõi WP, nên mọi miền gửi tin nhắn nhiều phần đều bị chặn. Vấn đề là hầu hết các quản trị web không biết tại sao. Tôi đã xác nhận điều này khi thực hiện nghiên cứu của mình và thấy những người dùng khác thảo luận về vấn đề này trên các diễn đàn, v.v. Nó đòi hỏi phải đi sâu vào mã thô và có kiến thức tốt về cách thức các loại email này hoạt động, mà chúng ta sẽ tiếp tục ...
Hãy chia nó thành mã
Tạo một tài khoản hotmail / triển vọng. Sau đó, chạy mã sau đây:
// Set $to to an hotmail.com or outlook.com email
$to = "YourEmail@hotmail.com";
$subject = 'wp_mail testing multipart';
$message = '------=_Part_18243133_1346573420.1408991447668
Content-Type: text/plain; charset=UTF-8
Hello world! This is plain text...
------=_Part_18243133_1346573420.1408991447668
Content-Type: text/html; charset=UTF-8
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<p>Hello World! This is HTML...</p>
</body>
</html>
------=_Part_18243133_1346573420.1408991447668--';
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: Foo <foo@bar.com>\r\n";
$headers .= 'Content-Type: multipart/alternative;boundary="----=_Part_18243133_1346573420.1408991447668"';
// send email
wp_mail( $to, $subject, $message, $headers );
Và nếu bạn muốn thay đổi loại nội dung mặc định , hãy sử dụng:
add_filter( 'wp_mail_content_type', 'set_content_type' );
function set_content_type( $content_type ) {
return 'multipart/alternative';
}
Điều này sẽ gửi một tin nhắn nhiều phần.
Vì vậy, nếu bạn kiểm tra toàn bộ nguồn thô của tin nhắn, bạn sẽ nhận thấy rằng loại nội dung được thêm hai lần, một lần không có ranh giới:
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="====f230673f9d7c359a81ffebccb88e5d61=="
MIME-Version: 1.0
Content-Type: multipart/alternative; charset=
Đó là vấn đề.
Nguồn gốc của vấn đề nằm ở pluggable.php
- nếu chúng ta tìm kiếm ở đâu đó ở đây:
// Set Content-Type and charset
// If we don't have a content-type from the input headers
if ( !isset( $content_type ) )
$content_type = 'text/plain';
/**
* Filter the wp_mail() content type.
*
* @since 2.3.0
*
* @param string $content_type Default wp_mail() content type.
*/
$content_type = apply_filters( 'wp_mail_content_type', $content_type );
$phpmailer->ContentType = $content_type;
// Set whether it's plaintext, depending on $content_type
if ( 'text/html' == $content_type )
$phpmailer->IsHTML( true );
// If we don't have a charset from the input headers
if ( !isset( $charset ) )
$charset = get_bloginfo( 'charset' );
// Set the content-type and charset
/**
* Filter the default wp_mail() charset.
*
* @since 2.3.0
*
* @param string $charset Default email charset.
*/
$phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
// Set custom headers
if ( !empty( $headers ) ) {
foreach( (array) $headers as $name => $content ) {
$phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
}
if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) )
$phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
}
if ( !empty( $attachments ) ) {
foreach ( $attachments as $attachment ) {
try {
$phpmailer->AddAttachment($attachment);
} catch ( phpmailerException $e ) {
continue;
}
}
}
Các giải pháp tiềm năng
Vì vậy, bạn đang tự hỏi, tại sao bạn không báo cáo điều này tại trac ? Tôi đã có . Thật ngạc nhiên, một vé khác đã được tạo ra 5 năm trước phác thảo cùng một vấn đề.
Hãy đối mặt với nó, đó là một nửa thập kỷ. Trong những năm qua, nó giống như 30. Vấn đề rõ ràng đã bị bỏ qua và về cơ bản sẽ không bao giờ được khắc phục (... trừ khi chúng tôi giải quyết nó ở đây).
Tôi đã tìm thấy một chủ đề tuyệt vời ở đây cung cấp một giải pháp, nhưng trong khi giải pháp của anh ấy hoạt động, nó phá vỡ các email không có $headers
bộ tùy chỉnh .
Đó là nơi chúng ta gặp sự cố mỗi lần. Phiên bản nhiều trang hoạt động tốt, và $headers
các thông báo bỏ đặt bình thường không, hoặc câu thơ vise.
Giải pháp chúng tôi đưa ra là:
if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) ) {
$phpmailer->ContentType = $content_type . "; boundary=" . $boundary;
}
else {
$content_type = apply_filters( 'wp_mail_content_type', $content_type );
$phpmailer->ContentType = $content_type;
// Set whether it's plaintext, depending on $content_type
if ( 'text/html' == $content_type )
$phpmailer->IsHTML( true );
// If we don't have a charset from the input headers
if ( !isset( $charset ) )
$charset = get_bloginfo( 'charset' );
}
// Set the content-type and charset
/**
* Filter the default wp_mail() charset.
*
* @since 2.3.0
*
* @param string $charset Default email charset.
*/
$phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
// Set custom headers
if ( !empty( $headers ) ) {
foreach( (array) $headers as $name => $content ) {
$phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
}
}
Vâng, tôi biết, chỉnh sửa các tệp lõi là điều cấm kỵ, ngồi xuống ... đây là một sửa chữa tuyệt vọng và một nỗ lực kém để cung cấp một sửa chữa cho lõi.
Vấn đề với cách khắc phục của chúng tôi là các email mặc định như đăng ký mới, nhận xét, đặt lại mật khẩu, v.v. sẽ được gửi dưới dạng tin nhắn trống. Vì vậy, chúng tôi có một tập lệnh wp_mail () đang hoạt động sẽ gửi tin nhắn nhiều phần nhưng không có gì khác.
Phải làm gì
Mục đích ở đây là tìm cách gửi cả tin nhắn thông thường (văn bản thuần túy) và tin nhắn nhiều phần bằng cách sử dụng hàm wp_mail () lõi (không phải là chức năng gửi thư tùy chỉnh).
Khi cố gắng giải quyết vấn đề này, vấn đề chính bạn sẽ gặp phải là lượng thời gian bạn sẽ dành để gửi tin nhắn giả, kiểm tra xem chúng có nhận được không và về cơ bản là mở hộp aspirin và chửi bới tại Microsoft vì bạn đã quen với chúng Vấn đề IE trong khi gremlin ở đây không may là WordPress.
Cập nhật
Giải pháp được đăng bởi @bonger cho phép $message
là một mảng chứa các lựa chọn thay thế kiểu nội dung. Tôi đã xác nhận rằng nó hoạt động trong tất cả các kịch bản.
Chúng tôi sẽ cho phép câu hỏi này vẫn mở cho đến khi hết tiền thưởng để nâng cao nhận thức về vấn đề, có thể đến một mức độ mà nó sẽ được khắc phục trong cốt lõi. Hãy đăng một giải pháp thay thế trong đó $message
có thể là một chuỗi.
wp_mail
nó có thể cắm được . Sao chép chức năng ban đầu trong một plugin, chỉnh sửa nó như bạn cần và kích hoạt plugin. WordPress sẽ sử dụng chức năng chỉnh sửa của bạn thay vì chức năng ban đầu, không cần chỉnh sửa lõi.
wp_mail()
chức năng có thể cắm được nên không xác định thay thế của bạn là plugin phải sử dụng (trong wp-content / mu-plugin) không phải là giải pháp tốt cho bạn (và mọi người khác, không khắc phục được lỗi)? Trong trường hợp nào sẽ không di chuyển kiểm tra nhiều phần / ranh giới đến sau khi cài đặt$phpmailer->ContentType = $content_type;
(chứ không phải elsing) không hoạt động?