Back to Top

Magento 2- Send transactional email programmatically in your custom module

Updated 21 February 2024

Here we learn how to send transactional email programmatically in your Magento 2 custom module.

1# First we create a field in configuration from where we can select which email template will use.

You can create configuration field according to your section and group in app/code/NameSpace/ModuleName/etc/adminhtml/system.xml file as follow

<field id="your_email_template_field_id" translate="label comment" type="select" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
    <label>Label Of Your Field</label>
    <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
    <!-- This model return all transactional email template list of magento -->
</field>

2# Now create a email template configuration file at app/code/NameSpace/ModuleName/etc location file name should be 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="section_group_your_email_template_field_id" label="Label Of Your Template File" file="your_email_template.html" type="html" module="NameSpace_ModuleName" area="adminhtml"/>
</config>
<!-- here you define your email template and its template location path-->

3# Now create email template file at app/code/NameSpace/ModuleName/view/adminhtml/email as name which you given in email_template.xml file . Here we will use  “your_email_template.html” name for email template

Searching for an experienced
Magento Company ?
Find out More
<!--@subject Subject Of your email  @-->
<!--@vars {
"var this.getUrl($store, 'admin')":"Warehouse Account URL",
"var customer.email":"Customer Email",
"var customer.name":"Customer Name"
} @-->

{{template config_path="design/email/header_template"}} <!-- pathe of template header-->

<!-- here $myvar1 , $myvar2, $myvar3, $myvar4, $myvar5, $myvar6 are variables in which we
                                     asssign values when we use this template for send mail-->

<!-- you can Modify content of template according to your requirement-->
<table>
    <tr class="email-intro">
        <td>
            <p class="greeting">{{trans "%customer_name," customer_name=$myvar3}}</p>
            <p>
                {{trans "Your custom message."}}
                {{trans 'Your custom message <a href="%account_url">logging into your account</a>.' account_url=$this.getUrl($store,'admin',[_nosid:1]) |raw}}
            </p>
        </td>
    </tr>
    <tr class="email-summary">
        <td>
            <h1>{{trans 'Your Order <span class="no-link">#%increment_id</span>' increment_id=$myvar1 |raw}}</h1>
            <p>{{trans 'Placed on <span class="no-link">%created_at</span>' created_at=$myvar2 |raw}}</p>
        </td>
    </tr>
    <tr class="email-information">
        <td>
            <table class="order-details">
                <tr>
                    <td class="address-details">
                        <h3>{{trans "Billing Info"}}</h3>
                        <p>{{var myvar4|raw}}</p>
                    </td>
                </tr>
            </table>
            <table class="email-items">
                <thead>
                    <tr>
                        <th class="item-info">{{trans "Item"}}</th>
                        <th class="item-info">{{trans "Sku"}}</th>
                    </tr>
                </thead>
                <tbody>
                    {{var myvar8|raw}}
                </tbody>
            </table>
        </td>
    </tr>
</table>

{{template config_path="design/email/footer_template"}} <!--footer of template-->

4# Now template is ready and we will do code for send mail.
Write send mail code on action from where you want to send this mail.

/* Here we prepare data for our email  */


/* Receiver Detail  */
$receiverInfo = [
    'name' => 'Reciver Name',
    'email' => '[email protected]'
];


/* Sender Detail  */
$senderInfo = [
    'name' => 'Sender Name',
    'email' => '[email protected]',
];


/* Assign values for your template variables  */
$emailTemplateVariables = array();
$emailTempVariables['myvar1'] = $variablevalue1;
$emailTempVariables['myvar2'] = $variablevalue2;
                 ...
                 ...
                 ...    

/* We write send mail function in helper because if we want to 
   use same in other action then we can call it directly from helper */  

/* call send mail method from helper or where you define it*/  
$this->_objectManager->get('NameSpace\ModuleNmae\Helper\Email')->yourCustomMailSendMethod(
      $emailTempVariables,
      $senderInfo,
      $receiverInfo
  );

5# Helper file where we define our custom send mail function

<?php
namespace NameSpace\ModuleName\Helper;

/**
 * Custom Module Email helper
 */
class Email extends \Magento\Framework\App\Helper\AbstractHelper
{
    const XML_PATH_EMAIL_TEMPLATE_FIELD  = 'section/group/your_email_template_field_id';
    /* Here section and group refer to name of section and group where you create this field in configuration*/

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_scopeConfig;

    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $_storeManager;

    /**
     * @var \Magento\Framework\Translate\Inline\StateInterface
     */
    protected $inlineTranslation;

    /**
     * @var \Magento\Framework\Mail\Template\TransportBuilder
     */
    protected $_transportBuilder;
    
    /**
     * @var string
    */
    protected $temp_id;

    /**
    * @param Magento\Framework\App\Helper\Context $context
    * @param Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    * @param Magento\Store\Model\StoreManagerInterface $storeManager
    * @param Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
    * @param Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
    */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
    ) {
        $this->_scopeConfig = $context;
        parent::__construct($context);
        $this->_storeManager = $storeManager;
        $this->inlineTranslation = $inlineTranslation;
        $this->_transportBuilder = $transportBuilder; 
    }

    /**
     * Return store configuration value of your template field that which id you set for template
     *
     * @param string $path
     * @param int $storeId
     * @return mixed
     */
    protected function getConfigValue($path, $storeId)
    {
        return $this->scopeConfig->getValue(
            $path,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    /**
     * Return store 
     *
     * @return Store
     */
    public function getStore()
    {
        return $this->_storeManager->getStore();
    }

    /**
     * Return template id according to store
     *
     * @return mixed
     */
    public function getTemplateId($xmlPath)
    {
        return $this->getConfigValue($xmlPath, $this->getStore()->getStoreId());
    }

    /**
     * [generateTemplate description]  with template file and tempaltes variables values                
     * @param  Mixed $emailTemplateVariables 
     * @param  Mixed $senderInfo             
     * @param  Mixed $receiverInfo           
     * @return void
     */
    public function generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo)
    {
        $template =  $this->_transportBuilder->setTemplateIdentifier($this->temp_id)
                ->setTemplateOptions(
                    [
                        'area' => \Magento\Framework\App\Area::AREA_FRONTEND, /* here you can defile area and
                                                                                 store of template for which you prepare it */
                        'store' => $this->_storeManager->getStore()->getId(),
                    ]
                )
                ->setTemplateVars($emailTemplateVariables)
                ->setFrom($senderInfo)
                ->addTo($receiverInfo['email'],$receiverInfo['name']);
        return $this;        
    }

    /**
     * [sendInvoicedOrderEmail description]                  
     * @param  Mixed $emailTemplateVariables 
     * @param  Mixed $senderInfo             
     * @param  Mixed $receiverInfo           
     * @return void
     */
    /* your send mail method*/
    public function yourCustomMailSendMethod($emailTemplateVariables,$senderInfo,$receiverInfo)
    {

        $this->temp_id = $this->getTemplateId(self::XML_PATH_EMAIL_TEMPLATE_FIELD);
        $this->inlineTranslation->suspend();    
        $this->generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo);    
        $transport = $this->_transportBuilder->getTransport();
        $transport->sendMessage();        
        $this->inlineTranslation->resume();
    }

}

Thanks 🙂

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


5 comments

  • Manncorp Accounts
  • Idham Choudry
  • Gurpreet Dhanju
    • Abhishek Singh
  • chetan141tiwari
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home