概要
そのためWPコアのバグのため、送信マルチパートで電子メール(HTML /テキスト))(wp_mail(スパムフォルダで終わるメールの可能性を減らすために)します皮肉なことに、あなたのドメインがホットメール(およびその他のMicrosoftの電子メール)によってブロックされているとなります。
これは複雑な問題であり、最終的にコアに実装される可能性のある実行可能なソリューションを誰かが見つけられるように、詳細に分析することを目指します。
やりがいのある読み物になるでしょう。さぁ、始めよう...
不具合
ニュースレターの電子メールがスパムフォルダーになってしまうことを避けるための最も一般的なアドバイスは、マルチパートメッセージを送信することです。
マルチパート(MIME)は、1つの電子メールで電子メールメッセージのHTML部分とTEXT部分の両方を送信することを指します。クライアントがマルチパートメッセージを受信すると、HTMLをレンダリングできる場合はHTMLバージョンを受け入れ、そうでない場合はプレーンテキストバージョンを提示します。
これは機能することが証明されています。Gmailに送信すると、メインの受信トレイに到達したときにメッセージをマルチパートに変更するまで、すべての電子メールがスパムフォルダーに到着しました。素晴らしいもの。
現在、wp_mail()を介してマルチパートメッセージを送信する場合、コンテンツタイプ(multipart / *)を2回出力します。この動作は、すべての Microsoft(Hotmail、Outlookなど)を含む一部の電子メールでは生のメッセージとして表示され、マルチパートではない電子メールで発生します
Microsoftはこのメッセージに迷惑メールのフラグを付け、受信したいくつかのメッセージには受信者が手動でフラグを付けます。残念ながら、Microsoftの電子メールアドレスは広く使用されています。サブスクライバーの40%が使用しています。
これは、Microsoftが最近行ったメール交換で確認されています。
ドメインが完全にブロックされると、メッセージにフラグが立てられます。つまり、メッセージはスパムフォルダーに送信されず、受信者にも配信されません。
これまでにメインドメインを3回ブロックしました。
これはWPコアのバグであるため、マルチパートメッセージを送信するすべてのドメインがブロックされています。問題は、ほとんどのウェブマスターが理由を知らないことです。私は調査を行い、他のユーザーがフォーラムなどでこれを議論しているのを見て、これを確認しました。それは生のコードを掘り下げ、これらのタイプの電子メールメッセージがどのように機能するかについての十分な知識が必要です。
コードに分解しましょう
hotmail / outlookアカウントを作成します。次に、次のコードを実行します。
// 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 );
デフォルトのコンテンツタイプを変更する場合は、次を使用します。
add_filter( 'wp_mail_content_type', 'set_content_type' );
function set_content_type( $content_type ) {
return 'multipart/alternative';
}
これにより、マルチパートメッセージが送信されます。
したがって、メッセージの未加工のソース全体を確認すると、コンテンツタイプが2回追加され、境界なしで1回追加されていることがわかります。
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="====f230673f9d7c359a81ffebccb88e5d61=="
MIME-Version: 1.0
Content-Type: multipart/alternative; charset=
それが問題です。
問題の原因はpluggable.php
次のとおりです。ここを参照してください。
// 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;
}
}
}
潜在的なソリューション
あなたは不思議に思っています、なぜあなたはtracでこれを報告しなかったのですか?私はすでに持っています。驚いたことに、同じ問題の概要を説明する別のチケットが5年前に作成されました。
それに直面しましょう、それは半十年です。インターネットの年では、それは30に近いです。問題は明らかに放棄されており、基本的に修正されることはありません(...ここで解決しない限り)。
私はここで解決策を提供するすばらしいスレッドを見つけましたが、彼の解決策は機能しますが、カスタム$headers
セットを持たない電子メールを中断します。
そこが毎回クラッシュする場所です。マルチパートバージョンは正常に$headers
機能し、通常の未設定メッセージは機能しないか、またはその逆です。
私たちが思いついた解決策は:
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 ) );
}
}
はい、私は知っています、コアファイルの編集はタブーで、座ってください...これは必死の修正であり、コアの修正を提供する試みは貧弱でした。
修正の問題は、新規登録、コメント、パスワードのリセットなどのデフォルトのメールが空白のメッセージとして配信されることです。したがって、マルチパートメッセージを送信するがそれ以外は送信しないwp_mail()スクリプトが動作します。
何をすべきか
ここでの目的は、コアwp_mail()関数(カスタムsendmail関数ではない)を使用して、通常(プレーンテキスト)とマルチパートメッセージの両方を送信する方法を見つけることです。
これを解決しようとすると、遭遇する主な問題は、ダミーメッセージの送信、受信したかどうかの確認、基本的にアスピリンの箱を開けてMicrosoftに呪いをかけることに費やす時間ですIEは、ここのグレムリンは残念ながらWordPressですが、問題があります。
更新
@bongerによって投稿されたソリューションでは、$message
コンテンツタイプのキー付き代替を含む配列を使用できます。すべてのシナリオで機能することを確認しました。
この問題は、問題についての認識を高めるために賞金が尽きるまで、おそらく問題が核心で修正されるレベルまで、この質問を開いたままにしておきます。$message
文字列にできる代替ソリューションをお気軽に投稿してください。
wp_mail()
機能はプラグイン可能である(WP-コンテンツ/ MU-プラグインで)必見使用プラグインではない良いあなたのためのソリューション(および他の皆、失敗コアフィックス)として、あなたの交換を定義していませんか?どのような場合、設定後に$phpmailer->ContentType = $content_type;
(エルシングではなく)マルチパート/境界チェックが移動しないのですか?