Email notification to all users in group

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • changos
    Junior Member
    • Oct 2020
    • 13

    Email notification to all users in group

    Hi there! Me again,

    I was wonder if this is possible:

    When a case is assigned to a team, every user of that team gets an notification via email.

    Email notification to user is working OK. But is there anything on the core for notify the whole team?

    If not, I'm considering these approach:

    a) Create an afterSave hook for the case entity, find users and emails of the team assigned to the case, and send the email. (I'm having problems to get the team_id relation with the table entity_team on the ORM)

    b) Create a formula to do the same as mention above, but the same problem to get the team_id.

    Anyone had this issue and any ideas that can help me?

    Thanks a lot!!

  • telecastg
    Active Community Member
    • Jun 2018
    • 907

    #2
    Hi changos

    If you go with the afterSave hook approach for Case, I would suggest the following code to get an email distribution list for the whole team or teams if more than one is involved:

    PHP Code:
    public function afterSave(Entity $entity, array $options = [])
    {
        // initialize variables
        $emailDistributionList = [];
    
        // get the list team objects linked to the Case entity
        foreach ($entity->get('teams') as $team) {
    
            // get the list role objects linked to each team
            $teamRoleList = $team->get('roles');  
    
            foreach ($teamRoleList as $role) {
    
                // get the list of active user objects linked to each role
                $userList = $this->getEntityManager()->getRepository('Role')->findRelated($role, 'users', array('whereClause' => array('isActive' = > true)));
    
                foreach($userList as $user) {
    
                   // skip the Case assigned user to avoid duplicate email notifications
                   if($user->get('id') === $entity->get('assignedUserId') {
                       continue;    
                   }  
                    // get the user email address and add it to the distribution list
                    $emailDistributionList[] = $user->get('emailAddress');
    
                }
            }
        }
    
        // initialize an email object and send the notification emails to each address in the $emailDistribution list array
    
        // note that this hook as written will send notifications every time the Case entity is saved, if you want to limit the notification for new Cases only use the conditional:
       if($entity->isNew())
    } 
    
    I didn't test the code because we don't have anything similar in our application but I copied it from code that we have used before so it should work.
    Last edited by telecastg; 10-12-2020, 06:03 AM.

    Comment

    • changos
      Junior Member
      • Oct 2020
      • 13

      #3
      Hi telecastg , I ended up using your script with a little tweak for my use case (send to all user in the team, not in the role)

      This is my code....

      Now i have to figure out how the emails are being send by the EspoCRM , as I was thinking just to save the notification table was enought , but now I think is not working. Maybe I need to send the email directly from Espo? I have two pieces from the puzzle solved, but cannot put them together.


      PHP Code:
      public function afterSave(Entity $casoWeb, array $options = [])
      {
      // get the list team objects linked to the Case entity
      foreach ($casoWeb->get('teams') as $team) {
      // get the list of active user objects linked to each team
      $userList = $team->get('users');
      foreach($userList as $user) {
      //check user not deleted
      if($user->get("deleted") == 0) {
      // skip the Case assigned user to avoid duplicate email notifications
      if($user->get('id') === $casoWeb->get('assignedUserId')) {
      continue;
      }
      // initialize an email object and send the notification emails to each address in the $emailDistribution list array
      $notification = $this->getEntityManager()->getEntity('Notification');
      $notification->set([
      'type' => 'Assign',
      'userId' => $user->get('id'),
      'data' => [
      'entityType' => $casoWeb->getEntityType(),
      'entityId' => $casoWeb->id,
      'entityName' => $casoWeb->get('name'),
      'isNew' => $casoWeb->isNew(),
      'userId' => $this->getUser()->id,
      'userName' => $this->getUser()->get('name'),
      ]
      ]);
      $this->getEntityManager()->saveEntity($notification);
      }
      }
      }
      } 
      

      Comment

      • telecastg
        Active Community Member
        • Jun 2018
        • 907

        #4
        Hi changos ,

        For what I understand, appending a record to the Notification table does not automatically trigger an email send action, so you will need to:

        a) Mimic the Espo email notification mechanism or
        b) Manually compose and send the emails yourself using the MailSender class.

        Regarding the first option, we don't use the Notification entity so I don't have any code samples to share but you can see how notification emails are sent when an entity is assigned to a user in the EmailNotification service class https://github.com/espocrm/espocrm/b...ation.php#L106

        Regarding the manual options, here's a code sample to send emails manually to the list of email addresses ($emailDistributionList) from a hook:
        PHP Code:
        // create an array to store the sent messages for possible code debugging
        $sentMessages = [];
        // initialize a mail sender service
        $mailSender = $this->getInjection('container')->get('mailSender');
        // create an email entity and load the main properties
        $email = $this->getEntityManager()->getEntity('Email');
        // define the email parameters
        $fromAddress = $this->getConfig()->get('outboundEmailFromAddress');
        $subject = 'bla bla bla';
        $body = 'bla bla bla';
        // iterate the list of users to be notified
        foreach ($emailDistributionList as $emailAddress) {
            $currMessage = [];
            // verify the email format to avoid error throwing by the email object
            if (filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) {
                // load the email object
                email->set(array(
                    'subject' => $subject,
                    'body' => $body,
                    'isHtml' => true,
                    'from' => $fromAddress,
                    'to' => $emailAddress,
                    'isSystem' => true
                ));
                // send the email
                if ($this->getConfig()->get('smtpServer') && $emailAddress) {
                    $mailSender->send($email);
                }
                // store the details of the message sent
                $currMessage['to'] = $emailAddress;
                $currMessage['body'] = $body;
                $sentMessages[] = $currMessage;
            }
        } 
        
        Last edited by telecastg; 10-13-2020, 05:27 PM.

        Comment


        • item
          item commented
          Editing a comment
          Thanks telecastg .. since many time a search how send email
          on your link, there are too "template" .. nice

          not sample with attachment ?

          Regards

        • telecastg
          telecastg commented
          Editing a comment
          You're welcome item I don't have any sample code of sending emails "manually" with attachments but you can see how it is done in the send invitation to an event code here: https://github.com/espocrm/espocrm/b...tions.php#L100
      • changos
        Junior Member
        • Oct 2020
        • 13

        #5
        Hi telecastg !!

        I share my code snippet to anyone who wants this get working (send email to all users in team).
        It checks if user is active (not deleted) , and has an email, and has the preferences marked to recieve this notifications.

        I'm having just one little problem here. I can check if the user asignament has changed , but I dont know how to check if the TEAM assignament has changed, since it depends on another entity.... I need to look for that, any ideas? The idea here is to only send the email if the team has changed.

        This is working perfectly:


        PHP Code:
        
        <?php
        
        namespace Espo\Custom\Hooks\CasosWeb;
        
        use Espo\ORM\Entity;
        Use Espo\Core\Utils\Util;
        
        class sendEmailToGroup extends \Espo\Core\Hooks\Base
        {
        public function afterSave(Entity $entity, array $options = [])
        {
        // get the list team objects linked to the Case entity
        $mailSender = $this->getInjection('container')->get('mailSender');
        $templateManager = $this->getInjection('container')->get('templateFileManager');
        $language = $this->getInjection('container')->get('language');
        $htmlSanitizer = new \Espo\Core\Htmlizer\Htmlizer($this->getInjection('container')->get('fileManager'), $this->getInjection('container')->get('dateTime'), $this->getInjection('container')->get('number'), null);
        
        foreach ($entity->get('teams') as $team) {
        
        // get the list of active user objects linked to each team
        $userList = $team->get('users');
        
        foreach($userList as $user) {
        
        $emailAddress = $user->get('emailAddress');
        //check user not deleted
        if($user->get("deleted") == 0 && $emailAddress) {
        
        // skip the Case assigned user to avoid duplicate email notifications
        // user notification is being sended via job in EmailNotification / notifyAboutAssignmentJob
        // so you dont need to do this
        if($user->get('id') === $entity->get('assignedUserId')) {
        continue;
        }
        
        //check for the user preferences (optional) to see if he wants to recibe this notifications
        $preferences = $this->getEntityManager()->getEntity('Preferences', $user->get('id'));
        if (!$preferences) continue;
        if (!$preferences->get('receiveAssignmentEmailNotifications')) continue;
        
        $ignoreList = $preferences->get('assignmentEmailNotificationsIgnoreEntityType List') ?? [];
        if (in_array($entity->getEntityType(), $ignoreList)) continue;
        
        
        // initialize an email object and send the notification emails to each address in the $emailDistribution list array
        $email = $this->getEntityManager()->getEntity('Email');
        
        $subjectTpl = $templateManager->getTemplate('assignment', 'subject', $entity->getEntityType());
        $bodyTpl = $templateManager->getTemplate('assignment', 'body', $entity->getEntityType());
        
        $subjectTpl = str_replace(["\n", "\r"], '', $subjectTpl);
        
        $recordUrl = rtrim($this->getConfig()->get('siteUrl'), '/') . '/#' . $entity->getEntityType() . '/view/' . $entity->id;
        
        $data = [
        'userName' => $user->get('name'),
        'assignerUserName' => $this->getUser()->get('name'),
        'recordUrl' => $recordUrl,
        'entityType' => $language->translate($entity->getEntityType(), 'scopeNames')
        ];
        $data['entityTypeLowerFirst'] = Util::mbLowerCaseFirst($data['entityType']);
        
        $subject = $htmlSanitizer->render($entity, $subjectTpl, 'assignment-email-subject-' . $entity->getEntityType(), $data, true);
        $body = $htmlSanitizer->render($entity, $bodyTpl, 'assignment-email-body-' . $entity->getEntityType(), $data, true);
        
        $email->set([
        'subject' => $subject,
        'body' => $body,
        'isHtml' => true,
        'to' => $emailAddress,
        'isSystem' => true,
        'parentId' => $entity->id,
        'parentType' => $entity->getEntityType()
        ]);
        try {
        $mailSender->send($email);
        } catch (\Exception $e) {
        $GLOBALS['log']->error('EmailNotification: [' . $e->getCode() . '] ' .$e->getMessage());
        }
        
        }
        
        }
        }
        
        }
        }
        Last edited by changos; 10-14-2020, 05:47 PM. Reason: fast fingers LOL

        Comment

        • telecastg
          Active Community Member
          • Jun 2018
          • 907

          #6
          Hi changos

          but I dont know how to check if the TEAM assignament has changed, since it depends on another entity....
          Not sure I understand. Do you mean if the CasoWeb has been assigned to another Team or when the Team is assigned to another CasoWeb ?. Could you provide an example ?

          Comment

          • changos
            Junior Member
            • Oct 2020
            • 13

            #7
            telecastg I wanna mean that i want to send the email only when the entity gets assigned to a team, not on every update of the entity.
            i know how to look if an attribute has changed but i dont know how to look if a relationship has changed.

            Use case:

            call center generates a new case, and saves it. No email is dispached to team as no team is assigned.

            Admin updates the case and assign it to a team. Emails are being dispached here.

            Team updates with new data the case. Here i need to no emails to be dispached since the team has no changed.



            Comment

            • telecastg
              Active Community Member
              • Jun 2018
              • 907

              #8
              I think that you could add a custom boolean field to the Case entity and flag it after you send the email notifications.
              Last edited by telecastg; 10-15-2020, 06:16 AM.

              Comment

              • changos
                Junior Member
                • Oct 2020
                • 13

                #9
                telecastg YES! I mean no, no boolean but i can add a string field to save the team name in the entity.

                So then I can check if the field team in the entity is the same as the team (id) assigned, on each update of the case. If it is the same, then no email. If is not the same (because you assigned the case or you reassigned the case, then emails are being sended)

                Thanks a lot!!

                Comment


                • telecastg
                  telecastg commented
                  Editing a comment
                  You're welcome :-)
                  Yes, it makes a lot more sense to compare the team name because under my suggestion you would only know if there was a team or not. I'm glad everything is working now.
              Working...