Mostrar archivos adjuntos de imágenes en línea con wp_mail

6 minutos de lectura

avatar de usuario
Eek

Tengo un problema.

Me gustaría adjuntar una imagen a un correo electrónico y también mostrarla en línea, con algún otro contenido generado por php. El problema es que no tengo la menor idea de cómo usar una matriz de archivos adjuntos en línea utilizada por wp_mail para adjuntar.

Mi solución fue codificar las imágenes en base64 y ponerlas en línea en el HTML de esta manera:

<img alt="The Alt" src="data:image/png;base64,*etc*etc*etc" />

Pero el problema es que Gmail/Outlook elimina los datos src de la imagen. Entonces aterriza como

<img alt="The Alt" />

¿Alguna pista sobre qué modificar (encabezados para trabajar con base64) o cómo usar el archivo adjunto para incrustarlos en línea?

avatar de usuario
Constantino

wp_mail usa el PHPMailer clase. Esta clase tiene toda la funcionalidad necesaria para los archivos adjuntos en línea. Para cambiar el objeto phpmailer antes de que wp_mail() envíe el correo electrónico, puede usar el filtro phpmailer_init.

$body = '
Hello John,
checkout my new cool picture.
<img src="https://stackoverflow.com/questions/15646187/cid:my-cool-picture-uid" width="300" height="400">

Thanks, hope you like it ;)';

Ese fue un ejemplo de cómo insertar la imagen en el cuerpo de su correo electrónico.

$file="/path/to/file.jpg"; //phpmailer will load this file
$uid = 'my-cool-picture-uid'; //will map it to this UID
$name="file.jpg"; //this will be the file name for the attachment

global $phpmailer;
add_action( 'phpmailer_init', function(&$phpmailer)use($file,$uid,$name){
    $phpmailer->SMTPKeepAlive = true;
    $phpmailer->AddEmbeddedImage($file, $uid, $name);
});

//now just call wp_mail()
wp_mail('test@example.com','Hi John',$body);

Eso es todo.

  • Recuerde el punto y coma al final de la línea después de ‘archivo.jpg’

    – janlindso

    25/10/2014 a las 22:26

avatar de usuario
Para mi

Si obtiene un error T_FUNCTION inesperado, se debe a la versión de PHP

function attachInlineImage() {  
  global $phpmailer;  
  $file="/path/to/file.jpg"; //phpmailer will load this file  
  $uid = 'my-cool-picture-uid'; //will map it to this UID  
  $name="file.jpg"; //this will be the file name for the attachment  
  if (is_file($file)) {  
    $phpmailer->AddEmbeddedImage($file, $uid, $name);  
  }  
}  

add_action('phpmailer_init','attachInlineImage');  

Necesitaba esto de una manera pequeña y mejor porque estoy enviando varios correos en un solo paso y no todos los correos deben tener las mismas imágenes incrustadas. Así que estoy usando esta solución de Constantin pero con mis Modificaciones 🙂

wp_mail('test@example.org', 'First mail without attachments', 'Test 1');

$phpmailerInitAction = function(&$phpmailer) {
    $phpmailer->AddEmbeddedImage(__DIR__ . '/img/header.jpg', 'header');
    $phpmailer->AddEmbeddedImage(__DIR__ . '/img/footer.png', 'footer');
};
add_action('phpmailer_init', $phpmailerInitAction);
wp_mail('test@example.org', 'Mail with embedded images', 'Example <img src="https://stackoverflow.com/questions/15646187/cid:header" /><br /><img src="cid:footer" />', [
    'Content-Type: text/html; charset=UTF-8'
], [
    __DIR__ . '/files/terms.pdf'
]);
remove_action('phpmailer_init', $phpmailerInitAction);

wp_mail('test@example.org', 'Second mail without attachments', 'Test 2');

El primero wp_mail será sin archivos adjuntos. El segundo wp_mail contendrá imágenes incrustadas. El tercero wp_mail será sin archivos adjuntos.

Está funcionando bien por ahora 😎

Creé esta clase para administrar la adición de una imagen al cuerpo del correo electrónico y limpiar después de sí mismo.

También si defines SENDGRID_PASSWORDutilizará Sendgrid en lugar de su servidor para enviar correos electrónicos

Este artículo es una guía paso a paso sobre cómo incrustar imágenes en el cuerpo del correo electrónico usando wordpress

https://codewriteups.com/embed-images-in-email-body-using-wp_mail-and-phpmailer

<?php

/*
 * Send HTML Emails with inline images
 */
class Custom_Mailer
{
    public $email_attachments = [];

    public function send($to, $subject, $body, $headers, $attachments)
    {
        /* Used by "phpmailer_init" hook to add attachments directly to PHPMailer  */
        $this->email_attachments = $attachments;

        /* Setup Before send email */
        add_action('phpmailer_init', [$this, 'add_attachments_to_php_mailer']);
        add_filter('wp_mail_content_type', [$this, 'set_content_type']);
        add_filter('wp_mail_from', [$this, 'set_wp_mail_from']);
        add_filter('wp_mail_from_name', [$this, 'wp_mail_from_name']);
        
        /* Send Email */
        $is_sent = wp_mail($to, $subject, $body, $headers);
        
        /* Cleanup after send email */
        $this->email_attachments = [];
        remove_action('phpmailer_init', [$this, 'add_attachments_to_php_mailer']);
        remove_filter('wp_mail_content_type', [$this, 'set_content_type']);
        remove_filter('wp_mail_from', [$this, 'set_wp_mail_from']);
        remove_filter('wp_mail_from_name', [$this, 'wp_mail_from_name']);

        return $is_sent;
    }

    public function add_attachments_to_php_mailer(&$phpmailer)
    {
        $phpmailer->SMTPKeepAlive=true;
        
        /* Sendgrid */
        if (defined('SENDGRID_PASSWORD')) {
            $phpmailer->IsSMTP();
            $phpmailer->Host="smtp.sendgrid.net";
            $phpmailer->Port = 587;
            $phpmailer->SMTPAuth = true;
            $phpmailer->SMTPSecure="tls";
            $phpmailer->Username="apikey";
            $phpmailer->Password = SENDGRID_PASSWORD;   /* api key from sendgrid */
        }

        /* Add attachments to mail */
        foreach ($this->email_attachments as $attachment) {
            if (file_exists($attachment['path'])) {
                $phpmailer->AddEmbeddedImage($attachment['path'], $attachment['cid']);
            }
        }
    }

    public function set_content_type()
    {
        return "text/html";
    }
    
    public function set_wp_mail_from($email)
    {
        //Make sure the email is from the same domain
        //as your website to avoid being marked as spam.
        return strip_tags(get_option('admin_email'));
    }

    public function wp_mail_from_name($name)
    {
        return get_bloginfo('name');
    }
}

Uso:

/* Set mail parameters */
$to = 'test@example.com';
$subject="Inline Img";
$body = '<h1>Image:</h1> <img src="cid:my_img_cid"/>';
$headers = "";
$my_attachments = [
    [
        "cid" => "my_img_cid", /* used in email body */
        "path" => plugin_dir_path(__FILE__) . '/my_img.png',
    ],
];

$custom_mailer = new Custom_Mailer();
$custom_mailer->send($to, $subject, $body, $headers, $my_attachments);

AddEmbeddedImage solo acepta dos parámetros, así que asegúrese de no incluir el parámetro $name como en el ejemplo.

  • También ayudaría proporcionar un enlace a los documentos, para respaldar su reclamo y para una mayor investigación.

    – sjaustirni

    27 de febrero de 2018 a las 13:17

avatar de usuario
dharma

Agregue el código a continuación en functions.php para incluir su imagen en todos los correos electrónicos (como un logotipo de firma).

function attachInlineLogo() {
    global $phpmailer;
    if (!( $phpmailer instanceof PHPMailer )) {
        require_once ABSPATH . WPINC . '/class-phpmailer.php';
        require_once ABSPATH . WPINC . '/class-smtp.php';
        $phpmailer = new PHPMailer(true);
    }
    $strFilePath="ABSOLUTE LOGO PATH";
    $strFileUID  = 'UNIQUE-UID'; //UID TO USE IN HTML TEMPLATE
    $strFileName="LOGO NAME";
    if (is_file($strFilePath)) {
        $phpmailer->SMTPKeepAlive = true;
        $phpmailer->AddEmbeddedImage($strFilePath, $strFileUID, $strFileName);
    }
}

add_action('phpmailer_init', 'attachInlineLogo');

En tu código HTML

<img src="https://stackoverflow.com/questions/15646187/cid:UNIQUE-UID" />

  • También ayudaría proporcionar un enlace a los documentos, para respaldar su reclamo y para una mayor investigación.

    – sjaustirni

    27 de febrero de 2018 a las 13:17

¿Ha sido útil esta solución?