Ringkasan
Karena bug di WP Core, mengirim email multi bagian (html / teks) dengan wp_mail () (untuk mengurangi kemungkinan email berakhir di folder spam) secara ironis akan mengakibatkan domain Anda diblokir oleh Hotmail (dan email Microsoft lainnya).
Ini adalah masalah kompleks yang akan saya uraikan dengan sangat rinci dalam upaya membantu seseorang menemukan solusi yang bisa diterapkan yang pada akhirnya dapat diterapkan pada intinya.
Ini akan menjadi bacaan yang bermanfaat. Mari kita mulai...
Serangga
Saran paling umum untuk menghindari email buletin Anda berakhir di folder spam adalah mengirim pesan multi bagian.
Multi-bagian (pantomim) mengacu pada mengirim bagian HTML dan TEXT dari pesan email dalam satu email. Ketika klien menerima pesan multi-bagian, ia menerima versi HTML jika dapat merender HTML, jika tidak, ia menyajikan versi teks biasa.
Ini terbukti berhasil. Saat mengirim ke gmail, semua email kami mendarat di folder spam hingga kami mengubah pesan menjadi multipart ketika mereka masuk ke kotak masuk utama. Hal yang bagus.
Sekarang, ketika mengirim pesan multi bagian melalui wp_mail (), ia menampilkan Jenis Konten (multi bagian / *) dua kali, sekali dengan batas (jika diatur secara khusus) dan sekali tanpa. Perilaku ini dihasilkan dengan email yang ditampilkan sebagai pesan mentah dan tidak multi-bagian pada beberapa email, termasuk semua Microsoft (Hotmail, Outlook, dll ...)
Microsoft akan menandai pesan ini sebagai sampah, dan beberapa pesan yang datang akan ditandai secara manual oleh penerima. Sayangnya , alamat email Microsoft banyak digunakan. 40% pelanggan kami menggunakannya.
Ini dikonfirmasi oleh Microsoft melalui pertukaran email yang kami miliki baru-baru ini.
Penandaan pesan akan mengakibatkan domain diblokir sepenuhnya . Ini berarti bahwa pesan tidak akan dikirim ke folder spam, mereka bahkan tidak akan dikirimkan ke penerima sama sekali.
Kami telah memblokir domain utama kami 3 kali sejauh ini.
Karena ini adalah bug di inti WP, setiap domain yang mengirim pesan multi bagian diblokir. Masalahnya adalah kebanyakan webmaster tidak tahu mengapa. Saya telah mengkonfirmasi ini ketika melakukan penelitian dan melihat pengguna lain mendiskusikan hal ini di forum, dll. Memerlukan menggali kode mentah dan memiliki pengetahuan yang baik tentang bagaimana jenis pesan email ini bekerja, yang akan kita bahas selanjutnya ...
Mari kita memecahnya menjadi kode
Buat akun hotmail / prospek. Kemudian, jalankan kode berikut:
// 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 );
Dan jika Anda ingin mengubah jenis konten default , gunakan:
add_filter( 'wp_mail_content_type', 'set_content_type' );
function set_content_type( $content_type ) {
return 'multipart/alternative';
}
Ini akan mengirim pesan multi bagian.
Jadi, jika Anda memeriksa sumber mentah lengkap pesan, Anda akan melihat bahwa jenis konten ditambahkan dua kali, sekali tanpa batas:
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="====f230673f9d7c359a81ffebccb88e5d61=="
MIME-Version: 1.0
Content-Type: multipart/alternative; charset=
Itu masalahnya.
Sumber masalahnya terletak pada pluggable.php
- jika kita melihat ke suatu tempat di sini:
// 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;
}
}
}
Solusi potensial
Jadi Anda bertanya-tanya, mengapa Anda tidak melaporkan ini di trac ? Saya sudah punya . Yang sangat mengejutkan saya, tiket yang berbeda dibuat 5 tahun yang lalu menguraikan masalah yang sama.
Mari kita hadapi itu, sudah setengah dekade. Dalam tahun-tahun internet, itu lebih seperti 30. Masalahnya jelas telah ditinggalkan dan pada dasarnya tidak akan pernah diperbaiki (... kecuali jika kita menyelesaikannya di sini).
Saya menemukan utas yang bagus di sini menawarkan solusi, tetapi sementara solusinya bekerja, itu merusak email yang tidak memiliki $headers
set kustom .
Di situlah kita crash setiap saat. Versi multipart berfungsi dengan baik, dan $headers
pesan yang tidak disetel normal tidak berfungsi , atau sebaliknya.
Solusi yang kami temukan adalah:
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 ) );
}
}
Ya, saya tahu, mengedit file inti adalah hal yang tabu, duduk kembali ... ini adalah perbaikan yang putus asa dan upaya yang buruk untuk memberikan perbaikan untuk inti.
Masalah dengan perbaikan kami adalah bahwa email default seperti pendaftaran baru, komentar, reset kata sandi dll akan dikirimkan sebagai pesan kosong. Jadi kami memiliki skrip wp_mail () yang berfungsi yang akan mengirim pesan multi bagian tetapi tidak ada yang lain.
Melakukan apa
Tujuannya di sini adalah untuk menemukan cara untuk mengirim pesan normal (teks biasa) dan multi -bagian menggunakan fungsi inti wp_mail () (bukan fungsi sendmail khusus).
Ketika mencoba untuk menyelesaikan ini, masalah utama yang akan Anda temui adalah jumlah waktu yang akan Anda habiskan untuk mengirim pesan palsu, memeriksa apakah mereka diterima dan pada dasarnya membuka kotak aspirin dan memaki di Microsoft karena Anda terbiasa dengan mereka Masalah IE sementara GREMLIN di sini sayangnya WordPress.
Memperbarui
Solusi yang diposting oleh @bonger memungkinkan $message
untuk menjadi array yang berisi alternatif jenis konten yang dikunci. Saya telah mengkonfirmasi bahwa ini berfungsi di semua skenario.
Kami akan membiarkan pertanyaan ini tetap terbuka sampai hadiah habis untuk meningkatkan kesadaran tentang masalah, mungkin ke tingkat di mana ia akan diperbaiki pada intinya. Jangan ragu untuk mengirim solusi alternatif di mana $message
dapat berupa string.
wp_mail
dapat dicolokkan . Salin fungsi asli dalam sebuah plugin, edit sesuai kebutuhan dan aktifkan plugin tersebut. WordPress akan menggunakan fungsi yang diedit alih-alih yang asli, tanpa perlu mengedit inti.
wp_mail()
fungsi ini pluggable, tidak mendefinisikan pengganti Anda sebagai plugin yang harus digunakan (dalam wp-content / mu-plugins) bukan solusi yang baik untuk Anda (dan semua orang, gagal memperbaiki inti)? Dalam hal mana tidak akan memindahkan pemeriksaan multi bagian / batas setelah pengaturan$phpmailer->ContentType = $content_type;
(daripada elsing) tidak berfungsi?