Como enviar emails con swiftmailer

Buen día, ando tratando de enviar emails usando yii2 basic, a lo que lei en foros debo de apagar el yii debugger pero no lo encuentro donde se encuentra, solo encontre en el path proyecto/config/web.php debo de poner en false lo siguiente:

'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => false,
        ],

pero no encuentro como apagar el debugger. me podrian explicar como puedo apagar el debugger para que desde localhost me envie un email o debe de estar ya dentro de un servidor el código?

Gracias de ante mano

Buenas, el debug lo apagas desde el script de entrada al sitio. El script de entrada por defecto es public_html/index.php. Ese archivo setea, entre otras, la constante YII_DEBUG la cual podes pasar a ‘false’ si queres desactivarla.
No se si ese será el motivo de que no te envíe los mails, pero podes probarlo.
Exitos.

Gracias lo probare, ya probe la opción de comentar el código debug en yii basic, donde dice antes de deployar comentar estas lineas, pero seguire probando por que no deja enviar el correo, checare la opción que dices. Saludos y gracias por tu comentario

Intenta revisando logs del mailer para tratar de tener un mayor detalle del error. Puedes intentar activando los logs del mailer, o sino intenta mostrar por consola la respuesta que te está dando el send. Quizás con eso tengas mayor detalle de qué tipo de error estas teniendo: si tienes mail alguna dirección, o permisos de acceso al mailserver, u otra cosa.

1 Like

Hola, debe configurar el mailer con una cuenta real y dicha cuenta debe tener permiso para aplicación de terceros o no seguras (algo así se llama). Yo lo pasé a otro archivo, por eso el return directo.

<?php return [ 'class' => 'yii\swiftmailer\Mailer', 'viewPath' => '@app/mail', // send all mails to a file by default. You have to set // 'useFileTransport' to false and configure a transport // for the mailer to send real emails. 'useFileTransport' => false, 'transport' => [ 'class' => 'Swift_SmtpTransport', // 'host' => 'smtp.gmail.com', // 'host' => 'smtp.mail.yahoo.com', 'host' => 'smtp-mail.outlook.com', 'username' => 'micorreo@outlook.com', 'password' => 'mi-clave', 'port' => '587', // 25 o 465 para yahoo - 587 para GMail/outlook 'encryption' => 'tls', ], ];
1 Like

Primera:

Como te han dicho arriba, para apagar el debugger debes cambiar una constante, evidentemente es algo que debes hacer sí o sí para poner tu sitio online.

En la plantilla básica, debes ir a /web/index,php

// comment out the following two lines when deployed to production
   defined('YII_DEBUG') or define('YII_DEBUG', true);
   defined('YII_ENV') or define('YII_ENV', 'dev');

Yii2 está definiendo dos constantes, si no existen ya.

La primera es YII_DEBUG y se refiere a la barra de debug y la cantidad de información que mostrará de cada error y el detalle de los logs.

Obviamente esos logs y la barra sólo son para los ojos del desarrollador, asi que comentamos la segunda línea para ponerlo online.

La segunda es YII_ENV y se refiere al entorno de desarrollo de la aplicación. Si YII_ENV no está definida ya, le asigna el valor ‘dev’.

En un mundo ideal, las empresas de desarrollo deberían tener varios servidores y las aplicaciones ir cumpliendo ciclos dependiendo de lo que los PM digan.

Si trabajamos con varios entornos (como “testing”, “staging”, “bugs…)” Yii2 da mucha flexibilidad para controlar lo que mostramos.

Para pasar a producción, solo hay que comentar esas líneas.

// comment out the following two lines when deployed to production
// defined('YII_DEBUG') or define('YII_DEBUG', true);
// defined('YII_ENV') or define('YII_ENV', 'dev');

De esta forma YII_DEBUG no será TRUE y YII_ENV no será ‘dev’ y la aplicación no mostrará detalles de los errores del servidor, entre otras cosas.

Por si acaso, échale un ojo a /config/web.php y en algún lado tendrás esto:

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];
}

Como verás, los módulos de Gii y debug sólo se inyectan cuando YII_ENV es ‘dev’. Si pese a comentar las líneas la barra de debug sigue apareciendo, fíjate que en /config/web.php tengas el debug y gii metidos en un if que evalúe YII_ENV

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    (...)
1 Like

Segunda:

SwiftMailer está deprecated. Ahora se usa SymfonyMailer, pero es peor en realidad.

No entiendo lo de “apagar” el debugger para mandar mails. Con cambiar “useFileTransport” a FALSE debería ir sin importar el debugger, pero quién sabe.

Ésta es tu configuración.

'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => false,
        ],

Es complicado que mande mails porque el correo no está configurado :slight_smile:

Como indica @blonder4131 al definir ‘useFileTransport’ como FALSE es obligatorio configurar el transport, porque Yii no sabe cuál es tu servidor de correo.

'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,            
            'transport' => [
                'scheme' => 'smtps',
                'host' => '', // dirección del servidor de correo
                'username' => '', // tu cuenta de correo
                'password' => '', // password de tu cuenta de correo
                'port' => 465, // el puerto cambia. Por ejemplo gmail y outlook usan puertos diferentes.
                'dsn' => 'native://default', // esto es otra forma de config, yo prefiero la clásica
            ],
            'viewPath' => '@app/mail', // views para los correos
            // send all mails to a file by default.
            'useFileTransport' => false,
        ],
    ],
            // ... aquí sigue la configuración ...

Hay que rellenar esa configuración con los datos de tu servidor de correo y a volar.

1 Like

perdón, hace rato no uso yii. También se pueden enviar correos de forma nativa, no encontré el código de ejemplo, pero seguro buscando en internet lo encuentra, aunque creo que para ese sí necesita tener configurado un servidor de correo.

1 Like

Gracias a todos por sus comentarios, de hecho probe lo que me dijeron pero ahora siento que es cuestión de permisos del proveedor que le ando rentando el servidor, por que haciendo los cambios como me sugirio @MeFuMo me sale el error de internal server error, en un chat me sugirieron hablarlo con el proveedor del server por que tal vez es problema de permisos y que algunas veces quieren cobrar por eso, lo que hare ahora antes de hablar con ellos es probar otro método donde yo envie el correo y si eso no me funciona, entonces si tendré que hablar con el proveedor, les dejo la imagen del error que me sale como el código en web.php

        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => false,
            'transport' => [ 
				'class' => 'Swift_SmtpTransport', // 
				'host' => 'smtp.gmail.com', // 
				'username' => 'username@gmail.com', 
				'password' => 'password_gmail', 
				'port' => '587', // 25 o 465 para yahoo - 587 para GMail/outlook 
				'encryption' => 'tls', 
			],
        ],

Estas instanciando SwiftMailer, que creo que está deprecated y sustituído por SymfonyMailer.

Prueba un par de cosas:

  • Mira en los “use” al principio del script si estás incluyendo la clase correcta (SwiftMailer).

  • Prueba a instanciar la clase directamente, así:

'mailer' => [
    'class' => yii\swiftmailer\Mailer::class, // Aquì usamos el namespace de la clase directamente.
    'viewPath' => ...

Si ves que no y que no, pásate a SymfonyMailer y lo configuras como en mi ejemplo de arriba o asì:

'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class, // Sin comillas. A hierro.
            'transport' =>
                [
                    'dsn' => 'gmail+smtp://USERNAME:PASSWORD@smtp.gmail.com',
                ]
        ],		

Use esta opción que me comentaste @MeFuMo y no me funciono

'mailer' => [
            'class' => yii\swiftmailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => false,
            'transport' => [ 
				'class' => 'Swift_SmtpTransport', // 
				'host' => 'smtp.gmail.com', // 
				'username' => 'user@gmail.com', 
				'password' => 'password', 
				'port' => '587', 
				'encryption' => 'tls', 
			],
        ],

probe la otra opción y paso lo mismo, mas bien siento que si son permisos del server

'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class, // Sin comillas. A hierro.
            'transport' =>
                [
                    'dsn' => 'gmail+smtp://user@gmail.com:password@smtp.gmail.com',
                ]
        ],

también lo intente de la forma del servidor y es lo mismo, me comunicare con ellos mañana para checar eso ya que a estas horas o no hay chat

'mailer' => [
            'class' => yii\swiftmailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => false,
            'transport' => [ 
				'class' => 'Swift_SmtpTransport', // 
				'host' => 'smtp.titan.email', // 
				'username' => 'contacto@amurderdirge.com', 
				'password' => 'password', 
				'port' => '465', // puerto de hostgator
				'encryption' => 'tls', 
			],
        ],

Yo uso la siguiente configuracion: en mi archivo app/config/web.php

        ...
        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,            
            'transport' => [
                'scheme' => 'smtps',
                'host' => 'mail.dominio.com.co',
                'username' => 'correo@dominio.com.co',
                'password' => '*****************',
                'port' => 465,
            ],
            'useFileTransport' => false,
        ],
        ...

y en mi controller donde voy a a enviar el mensaje uso lo siguiente:

           .....
           $mail = Yii::$app->mailer->compose()
                ->setFrom(["correo@dominio.com.co" => "NOMBRE QUE QUIERES MOSTRAR"]) // Cambiar al correo remitente, asi se vera en el correo del destinatario Ejemplo: HUBER SALAZAR <correo@dominio.com.co>
                ->setTo("destiantario@dominio.com") // Correo del destinatario
                ->setSubject("Asunto del mensaje") //Asunto
                //->setReplyTo("correo@dominio.com.co") //Responder a: 
                ->setBcc("correo@dominio.com.co") //Solo para que me lo envie al mismo correo como copia oculta
                ->setPriority(2) //Prioridad del mensaje no recomendable pero ayuda a que tus email enviados desde la plataforma o sitio tenga mayor prioridad que los enviados por otro medio como webmail, u otro cliente
                ->setHtmlBody("Todo el mensaje que quiere escribir soporta html");

            try {
                if ($mail->send()) {
                    $enviados++;
                }
            } catch (\Exception $e) {
                Yii::error("Error al enviar correo: " . $e->getMessage());
            }
           ...

Hasta el momento me funciona correctamente, espero que a ustedes también les funcione.

IMPORTANTE:
Google Gmail gratuito ya no permite este tipo de configuraciones poco seguras. y mucho menos si la cuenta tienes autenticación multifactor.
Las cuentas de la versión empresa si permite, pues tengo algunos clientes donde funciona perfecto con sus cuentas de empresas.
Vista la información de Google para revisar mas detalles: https://support.google.com/accounts/answer/6010255?hl=es-419

1 Like

Agradezco tu comentario, pero lo RARO es que inclusive agrego tu manera y no me funciona y dije a tal vez estoy haciendo mal las cosas y lo intente con el que trae yii original

Yii::$app->mailer->compose()
            ->setTo("contacto@amurderdirge.com")
            ->setFrom(["persona_quien_envia@hotmail.com" => "Nombre del usuario"])
            ->setSubject("Prueba de Asunto")
            ->setTextBody("Aqui es donde estoy poniendo el body")
            ->send();

y no me funciona, pero pongo tu códigode esta manera

$mail = Yii::$app->mailer->compose()
            ->setFrom([$this->name => $this->email])
            ->setTo(Yii::$app->params['senderEmail'])  // es el correo de contacto@amurderdirge.com
            ->setSubject($this->subject) //Asunto
            ->setHtmlBody($message);

y ni asi me funciona lo mas raro es que pongo un envio de correo SIMPLE con PHP usando la función mail y allí si funciona, pero al llegar al return true; es donde falla, y lo se porque lo comente por error y el correo me esta llegando bien usando la siguiente forma:

            $header = "Correo enviado desde Sitio Web: '".Yii::$app->params['senderName']."' www.mab.com";
            $message = $this->body;
            $message .= "\n\n\nAtentamente: ";
            $message .= "\n\n\n".$this->name;
            $message .= "\n\n\nCorreo: ".$this->email;
            mail(Yii::$app->params['senderEmail'], $this->subject, $message, $header);
            echo "<script>alert('Mensaje Enviado'); setTimeout(\"location.href='index'\",10); </script>";

No es una manera elegante de usarla pero me esta funcionando ponerle el JS con el setTimeout, si le dejo mas tiempo en poco tiempo yii detecta error y muestra sitio no encontrado y ya no me funciona el script, por eso le pongo poco tiempo, no se si es problema de YII, pero lo volvi a descargar hace unos dias y ps esta es la solución que encontre por el momento

Eh encontrado el error, al parecer swiftmailer no lo encuentra, solo ando buscando como usar composer para instalarlo

creo que se debe de agregar en composer.json pero no se como agregarlo ando investigando para agregar eso

en mi composer.json tengo lo siguiente:

veo que este mismo problema alguien ya lo tuvo en otro foro, pero no dicen si lo resolvieron

mmmm al final tuve que reinstalar yii pero usando composer y de esa manera ya no me salio el error, ahora me salia el error:

" Failed to authenticate on SMTP server with username "username@server.com" using the following authenticators: "LOGIN", "PLAIN"."

Contacte al equipo de soporte del servidor y me habilito el correo para recibir correos de terceros usando aplicaciones, pero el problema ahora es que me sale lo siguiente:

Sender address rejected: not owned by user

solo he encontrado se inhabilite el smtp usando composer y aún asi sigue sin funcionar.