Send mail from custom module Magento 2

To send custom email in Magento 2 using the module, We need to create a custom module to send email to a specific recipient.

Out of the box, Magento Provides multiple mail template, like Sales Order, Customer mails, Contacts and so on.

If you want to send your custom mail functionality using Magento 2, You need to create a simple module and create a custom template file using Module for mail body.

You need to create the first registration.php and module.xml file for defining our module. Here I have used Rbj as Packagename where SendEmail is a module name.

Check Image Attachment with Email by link, Image Attachment with Email Template Magento 2

Path: app/code/Rbj/SendEmail/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Rbj_SendEmail',
    __DIR__
);

Create module.xml file, Path: app/code/Rbj/SendEmail/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Rbj_SendEmail" setup_version="1.0.0">
    </module>
</config>

Create custom email templates in Module, We need to create an email_templates.xml file for defining our template file plus an area of mail sending whether its frontend or adminhtml area.

Type is HTML or text will be defined in below XML file. file attribute is for our custom file.

Path: app/code/Rbj/SendEmail/etc/email_templates.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="email_section_sendmail_email_template" label="Custom Email Template Magento 2" file="email_file.html" type="html" module="Rbj_SendEmail" area="frontend"/>
</config>

We need to create a system.xml file for set default email template settings.
Path: app/code/Rbj/SendEmail/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="custom_tabs" translate="label" sortOrder="110">
            <label>Email Tabs</label>
        </tab>
        <section id="email_section" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Custom Email send</label>
            <tab>custom_tabs</tab>
            <resource>Rbj_SendEmail::config</resource>
            <group id="sendmail" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Email Setting</label>
                <field id="enabled" translate="label comment" type="select" sortOrder="10" showInDefault="1"
                       showInWebsite="1" showInStore="1">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                    <comment><![CDATA[Your Comments]]></comment>
                </field>
                <field id="sender" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="3" canRestore="1">
                    <label>Product failed email sender</label>
                    <source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>
                <field id="email_template" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Custom Email Template</label>
                    <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
                    <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
                    <depends>
                        <field id="enabled">1</field>
                    </depends>
                </field>
            </group>
        </section>
    </system>
</config>

In an above system.xml file, we have to define email Module is enable or not, Default sender of an email and default email template to send with email body.

Create a config.xml file set default sender data and email template to send when an email is fired.
Path: app/code/Rbj/SendEmail/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <email_section>
            <sendmail>
                <enabled>1</enabled>
                <sender>general</sender>
                <email_template>email_section_sendmail_email_template</email_template>
            </sendmail>
        </email_section>
    </default>
</config>

We have set default setting enabled equals to 1 for enable module.
sender value as general.

For general default, email id takes from a backend.
Stores -> General -> Store Email Address -> General Contact.
Sender name and sender email will be taken.
email_template is our custom email template which we have defined under view/frontend folder below.

Now we will define our custom email template for send body of the mail.
Path: app/code/Rbj/SendEmail/view/frontend/email/email_file.html

<!--@subject {{trans "Custom Email template from %store_name" store_name=$store.getFrontendName()}} @-->
<!--@vars {
"var message_1":"Custom Message 1",
"var message_2":"Custom Message 2"
} @-->

{{template config_path="design/email/header_template"}}

<table>
    <tr class="email-info">
         <td>
            <h1>{{trans "Your Custom Message for email goes here"}}</h1>
        </td>
    </tr>
</table>

{{template config_path="design/email/footer_template"}}

You can modify the above file based on your requirement.
Now Main logic for send email resides under Helper file.

Magento\Framework\Mail\Template\TransportBuilder is used for sending custom email in Magento 2.

TransportBuilder class has the ability to send custom email based on your requirement. You need to pass all the required field in TransportBuilder class function.

Path: app/code/Rbj/SendEmail/Helper/Data.php

<?php
namespace Rbj\SendEmail\Helper;

use Psr\Log\LoggerInterface;
use Magento\Framework\App\Area;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Exception\MailException;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;

class Data extends AbstractHelper
{
    const EMAIL_TEMPLATE = 'email_section/sendmail/email_template';

    const EMAIL_SERVICE_ENABLE = 'email_section/sendmail/enabled';

    /**
     * @var StateInterface
     */
    private $inlineTranslation;

    /**
     * @var TransportBuilder
     */
    private $transportBuilder;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * Data constructor.
     * @param Context $context
     * @param StoreManagerInterface $storeManager
     * @param TransportBuilder $transportBuilder
     * @param StateInterface $inlineTranslation
     * @param LoggerInterface $logger
     */
    public function __construct(
        Context $context,
        StoreManagerInterface $storeManager,
        TransportBuilder $transportBuilder,
        StateInterface $inlineTranslation,
        LoggerInterface $logger
    )
    {
        $this->storeManager = $storeManager;
        $this->transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->logger = $logger;
        parent::__construct($context);
    }

    /**
     * Send Mail
     *
     * @return $this
     *
     * @throws LocalizedException
     * @throws MailException
     */
    public function sendMail()
    {
        $email = 'receiver@example.com'; //set receiver mail

        $this->inlineTranslation->suspend();
        $storeId = $this->getStoreId();

        /* email template */
        $template = $this->scopeConfig->getValue(
            self::EMAIL_TEMPLATE,
            ScopeInterface::SCOPE_STORE,
            $storeId
        );

        $vars = [
            'message_1' => 'CUSTOM MESSAGE STR 1',
            'message_2' => 'custom message str 2',
            'store' => $this->getStore()
        ];

        // set from email
        $sender = $this->scopeConfig->getValue(
            'email_section/sendmail/sender',
            ScopeInterface::SCOPE_STORE,
            $this->getStoreId()
        );

        $transport = $this->transportBuilder->setTemplateIdentifier(
            $template
        )->setTemplateOptions(
            [
                'area' => Area::AREA_FRONTEND,
                'store' => $this->getStoreId()
            ]
        )->setTemplateVars(
            $vars
        )->setFromByScope(
            $sender
        )->addTo(
            $email
        )->addBcc(
           ['receiver1@example.com', 'receiver2@example.com']
        )->getTransport();

        try {
            $transport->sendMessage();
        } catch (\Exception $exception) {
            $this->logger->critical($exception->getMessage());
        }
        $this->inlineTranslation->resume();

        return $this;
    }

    /*
     * get Current store id
     */
    public function getStoreId()
    {
        return $this->storeManager->getStore()->getId();
    }

    /*
     * get Current store Info
     */
    public function getStore()
    {
        return $this->storeManager->getStore();
    }
}

Here we have defined an area as frontend \Magento\Framework\App\Area::AREA_FRONTEND
$email is your receiver email id.
if you want to send multiple email address, pass email id as an array in addBcc() method.

  • Send email using below function in your template or block file.

$this->helper(‘Rbj\SendEmail\Helper\Data’)->sendMail();