Announcement

Collapse
No announcement yet.

How to send email from custom hook?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to send email from custom hook?

    Hello,

    I want to send email from custom hook, I wasnt able to find it or make it using \Espo\Services\Email. Thank you.

  • #2
    Hey try this code below, i have not tested the code but i think it will work.

    PHP Code:
    <?php
    namespace Espo\Custom\Hooks\YourEntity;

    use 
    Espo\Core\ORM\Repository\Option\SaveOption;
    use 
    Espo\Core\Utils\SystemUser;
    use 
    Espo\Core\InjectableFactory;
    use 
    Espo\Core\ServiceFactory;
    use 
    Espo\ORM\EntityManager;
    use 
    Espo\Entities\Email;
    use 
    Espo\Tools\Email\SendService;

    class 
    SendEmail
    {
        public static 
    $order 1;

        public function 
    __construct(
            private 
    EntityManager $entityManager,
            private 
    ServiceFactory $serviceFactory,
            private 
    InjectableFactory $injectableFactory,
        ){}

        public function 
    beforeSave(Entity $entity, array $options): void
        
    {
            if (!empty(
    $options[SaveOption::SILENT])) {
                return;
            }

            
    $em $this->entityManager;

            
    $id $em->createEntity(Email::ENTITY_TYPE, [
                
    'from''from-address@test.com',
                
    'to''to-address@test.com',
                
    'subject''Test from hooks',
                
    'body''Hi,\n\nThis is a your email body.',
                
    'isHtml'true
            
    ]);

            
    /** @var ?Email $email */
            
    $email $this->entityManager->getEntityById(Email::ENTITY_TYPE$id);

            if (!
    $email) {
                
    $this->log("Email '{$id}' does not exist.");
                return;
            }

            
    $status $email->getStatus();

            if (
    $status === Email::STATUS_SENT) {
                
    $this->log("Can't send email that has 'Sent' status.");
                return;
            }

            
    /** @var \Espo\Services\Email $service */
            
    $service $this->serviceFactory->create(Email::ENTITY_TYPE);

            
    $service->loadAdditionalFields($email);

            
    $toSave false;

            if (
    $status !== Email::STATUS_SENDING) {
                
    $email->set('status'Email::STATUS_SENDING);
                
    $toSave true;
            }

            
    $systemUserId $this->injectableFactory->create(SystemUser::class)->getId();

            if (
    $toSave) {
                
    $em->saveEntity($email, [
                    
    SaveOption::SILENT => true,
                    
    SaveOption::MODIFIED_BY_ID => $systemUserId,
                ]);
            }

           
    $sendService $this->injectableFactory->create(SendService::class);

           try {
                
    $sendService->send($email);
            }
            catch (
    Exception $e) {
                
    $message $e->getMessage();
                
    $this->log("Error while sending. Message: {$message}." 'error');
            }
        }
    }

    Comment


    • #3
      Hey rabii, thank you for your effort! Unfortunately, this code doesnt work for me, I tried to go through whats wrong, but I didnt manage to repair it. I added below some of the errors it gave me after I used your code and tried to modify it.
      Click image for larger version

Name:	image.png
Views:	169
Size:	104.8 KB
ID:	89879​​
      Attached Files

      Comment


      • #4
        Try this i have made some changes, if it doesn't work send me the log file as a text, the picture you have attached is not showing all the errors properly.

        PHP Code:
        <?php
        namespace Espo\Custom\Hooks\Holiday;

        use 
        Espo\Core\ORM\Repository\Option\SaveOption;
        use 
        Espo\Core\Utils\SystemUser;
        use 
        Espo\Core\InjectableFactory;
        use 
        Espo\Core\ServiceFactory;
        use 
        Espo\ORM\EntityManager;
        use 
        Espo\ORM\Entity;
        use 
        Espo\Entities\Email;
        use 
        Espo\Tools\Email\SendService;

        class 
        SendEmail
        {
            public static 
        $order 1;

            public function 
        __construct(
                private 
        EntityManager $entityManager,
                private 
        ServiceFactory $serviceFactory,
                private 
        InjectableFactory $injectableFactory,
            ){}

            public function 
        beforeSave(Entity $entity, array $options): void
            
        {
                if (!empty(
        $options[SaveOption::SILENT])) {
                    return;
                }

              
        $em $this->entityManager;

               
        $createdEmail $em->createEntity(Email::ENTITY_TYPE, [
                    
        'from''from-address@test.com',
                    
        'to''to-address@test.com',
                    
        'subject''Test from hooks',
                    
        'body''Hi,\n\nThis is a your email body.',
                    
        'isHtml'true
                
        ]);

                
        /** @var ?Email $email */
                
        $email $em->getEntityById(Email::ENTITY_TYPE$createdEmail->getId());

                if (!
        $email) {
                    
        $this->log("Email '{$id}' does not exist.");
                    return;
                }

               
        $status $email->getStatus();

                if (
        $status === Email::STATUS_SENT) {
                    
        $this->log("Can't send email that has 'Sent' status.");
                    return;
                }

                
        /** @var \Espo\Services\Email $service */
                
        $service $this->serviceFactory->create(Email::ENTITY_TYPE);

                
        $service->loadAdditionalFields($email);

                
        $toSave false;

               if (
        $status !== Email::STATUS_SENDING) {
                    
        $email->set('status'Email::STATUS_SENDING);
                    
        $toSave true;
                }

                
        // if from email is not set use default system outbound
                
        if (!$email->get('from')) {
                    
        $from $this->config->get('outboundEmailFromAddress');
                    if (
        $from) {
                        
        $email->set('from'$from);
                        
        $toSave true;
                    }
                }

               
        $systemUserId $this->injectableFactory->create(SystemUser::class)->getId();

               if (
        $toSave) {
                    
        $em->saveEntity($email, [
                        
        SaveOption::SILENT => true,
                        
        SaveOption::MODIFIED_BY_ID => $systemUserId,
                    ]);
                }

               
        $sendService $this->injectableFactory->create(SendService::class);

               try {
                    
        $sendService->send($email);
                }
                catch (
        Exception $e) {
                    
        $message $e->getMessage();
                    
        $this->log("Error while sending. Message: {$message}." 'error');
                }
            }
        }

        Comment


        • #5
          No need to use the service class. Just use Espo\Core\Mail\EmailSender (passed via constructor). An email entity can be created by Espo\Core\Mail\EmailFactory.

          Comment


          • #6
            Hey Yuri,

            if an email entity could be created through the email Factory like
            PHP Code:
            $createdEmail $this->emailFactory->create(); 
            then how to set the attribute of the email entity. is the code below is correct then ? i have passed both EmailSender and EmailFactory through constructor and used them as below to create and send email.
            PHP Code:
            public function beforeSave(Entity $entity, array $options): void
                
            {
                    if (!empty(
            $options[SaveOption::SILENT])) {
                        return;
                    }
                    
            $em $this->entityManager;
                    
            $createdEmail $this->emailFactory->create();
                    
            /** @var ?Email $email */
                    
            $email $em->getEntityById(Email::ENTITY_TYPE$createdEmail->getId());
                    if (!
            $email) {
                        
            $this->log("Email '{$id}' does not exist.");
                        return;
                    }
                    
            $status $email->getStatus();
                    if (
            $status === Email::STATUS_SENT) {
                        
            $this->log("Can't send email that has 'Sent' status.");
                        return;
                    }
                    
            $toSave false;
                    if (
            $status !== Email::STATUS_SENDING) {
                        
            $email->set('status'Email::STATUS_SENDING);
                        
            $toSave true;
                    }
                    
            // if from email is not set use default system outbound
                    
            if (!$email->get('from')) {
                        
            $from $this->config->get('outboundEmailFromAddress');
                        if (
            $from) {
                            
            $email->set('from'$from);
                            
            $toSave true;
                        }
                    }
                    
            $systemUserId $this->injectableFactory->create(SystemUser::class)->getId();
                    if (
            $toSave) {
                        
            $em->saveEntity($email, [
                            
            SaveOption::SILENT => true,
                            
            SaveOption::MODIFIED_BY_ID => $systemUserId,
                        ]);
                    }
                    try {
                        
            $this->emailSender->send($email);
                    }
                    catch (
            Exception $e) {
                        
            $message $e->getMessage();
                        
            $this->log("Error while sending. Message: {$message}." 'error');
                    }
                }
            ​ 

            Comment

          Working...
          X