Menu Close
    Hire us Request quote Reading list Switch to dark mode

    Magento 2- Send transactional email programmatically in your custom module

    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="your_email_template_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

    <!--@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' => 'receiver@address.com'
    ];
    
    
    /* Sender Detail  */
    $senderInfo = [
        'name' => 'Sender Name',
        'email' => 'sender@addess.com',
    ];
    
    
    /* 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 🙂

    . . .

    Comments (5)

    Add Your Comment

  • Manncorp Accounts
    Line 113 of the Email class you have ->setFrom($senderInfo)
    But you defined $senderInfo as an Array:
    /* Sender Detail */
    $senderInfo = [
    ‘name’ => ‘Sender Name’,
    ’email’ => ‘sender@addess.com’,

    Shouldn’t that be ->sentFrom($senderInfo[’email’],$senderInfo[‘name’]) ?

    If that’s not necessary, why not do the same thing here at line 114:
    ->addTo($receiverInfo)
    instead of ->addTo($receiverInfo[’email’],$receiverInfo[‘name’]) ?

  • Idham Choudry
    Do i have to configure the header and footer again or its automatically generated when i call {{template config_path=”design/email/header_template”}} ?
  • Gurpreet Dhanju
    $this->temp_id = $this->getTemplateId(self::XML_PATH_EMAIL_ORDER_APPROVED);

    What is this self::XML_PATH_EMAIL_ORDER_APPROVED in above line. It is never defined?

    • Abhishek Singh
      Hi,
      There was error. Now code is updated. you can check it. XML_PATH_EMAIL_ORDER_APPROVED replace by XML_PATH_EMAIL_TEMPLATE_FIELD
      Thanks
  • chetan141tiwari
    After this line
    $transport = $this->_transportBuilder->getTransport();

    it shows internal server error

  • Back to Top
    css.php
    Hire Us!
    Brief us about your requirements and we'll get back to you.
    Woo! Hooy!
    We have just received your message and our expert will get back to you shortly.
    Send Again
    Close