Como: Enviar Emails Programaticamente en Magento 2
En esta página
Tarde o temprano todo proyecto necesita enviar un email que Magento no envía por defecto, una notificación a un admin,
un recordatorio a un cliente, un reporte al almacén. La buena noticia es que Magento nos da un servicio limpio para
hacerlo, el TransportBuilder. Déjame mostrarte la configuración que uso.
app/code/Vendor/Module y que ya registraste una plantilla de email. Si necesitas la parte de la plantilla, echa un vistazo a Como: Crear email templates personalizados en Magento 2.El servicio
Me gusta envolver todo en un pequeño servicio para que el código que lo llama quede limpio y fácil de testear.
<?php
/** app/code/Vendor/Module/Model/EmailSender.php */
namespace Vendor\Module\Model;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Area;
class EmailSender
{
/**
* @var TransportBuilder
*/
private $transportBuilder;
/**
* @var StateInterface
*/
private $inlineTranslation;
/**
* @var StoreManagerInterface
*/
private $storeManager;
public function __construct(
TransportBuilder $transportBuilder,
StateInterface $inlineTranslation,
StoreManagerInterface $storeManager
) {
$this->transportBuilder = $transportBuilder;
$this->inlineTranslation = $inlineTranslation;
$this->storeManager = $storeManager;
}
/**
* @param string $toEmail
* @param array $templateVars
*/
public function send($toEmail, array $templateVars = [])
{
$storeId = $this->storeManager->getStore()->getId();
$this->inlineTranslation->suspend();
try {
$transport = $this->transportBuilder
->setTemplateIdentifier('vendor_module_email_template')
->setTemplateOptions(['area' => Area::AREA_FRONTEND, 'store' => $storeId])
->setTemplateVars($templateVars)
->setFromByScope('general')
->addTo($toEmail)
->getTransport();
$transport->sendMessage();
} finally {
$this->inlineTranslation->resume();
}
}
}Algunas cosas que vale la pena señalar:
setTemplateIdentifieres elidque le diste a la plantilla en elemail_templates.xml.- Siempre haz
suspend()de la traducción inline antes de enviar yresume()después, de lo contrario puedes tener el markup de traducción filtrándose dentro del email. Hacerlo en un bloquefinallygarantiza que se reanude incluso si el envío lanza una excepción. setFromByScope('general')usa el contacto general de la tienda, pero puedes pasar el tuyo['email' => ..., 'name' => ...].
Usándolo
Desde un controlador, un observer u otro servicio, ahora es una sola línea:
$this->emailSender->send('customer@example.com', ['customer_name' => 'John', 'order_id' => '000000123']);Esas variables son las que referencias en la plantilla con {{var customer_name}}.
Espero que esto ayude.
Si tienes alguna pregunta o conoces una mejor manera de lograr esto, siéntete libre de compartir en los comentarios a continuación.
Related links: