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');
            }
        }
    }
    Rabii
    Web Dev

    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:	253
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');
                }
            }
        }
        Rabii
        Web Dev

        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.
          If you find EspoCRM good, we would greatly appreciate if you could give the project a star on GitHub. We believe our work truly deserves more recognition. Thanks.

          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');
                    }
                }
            ​ 
            Rabii
            Web Dev

            Comment

          Working...
          X